aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig1
-rw-r--r--security/Makefile2
-rw-r--r--security/apparmor/.gitignore1
-rw-r--r--security/apparmor/domain.c4
-rw-r--r--security/apparmor/lib.c1
-rw-r--r--security/apparmor/lsm.c2
-rw-r--r--security/apparmor/path.c65
-rw-r--r--security/capability.c2
-rw-r--r--security/commoncap.c10
-rw-r--r--security/device_cgroup.c10
-rw-r--r--security/integrity/ima/ima_api.c4
-rw-r--r--security/integrity/ima/ima_main.c2
-rw-r--r--security/integrity/ima/ima_queue.c17
-rw-r--r--security/keys/Makefile2
-rw-r--r--security/keys/ecryptfs_format.c81
-rw-r--r--security/keys/ecryptfs_format.h30
-rw-r--r--security/keys/encrypted.c251
-rw-r--r--security/keys/keyring.c1
-rw-r--r--security/keys/request_key_auth.c2
-rw-r--r--security/keys/user_defined.c3
-rw-r--r--security/security.c10
-rw-r--r--security/selinux/avc.c2
-rw-r--r--security/selinux/hooks.c11
-rw-r--r--security/selinux/include/netif.h2
-rw-r--r--security/selinux/include/netlabel.h2
-rw-r--r--security/selinux/include/netnode.h2
-rw-r--r--security/selinux/include/netport.h2
-rw-r--r--security/selinux/netif.c2
-rw-r--r--security/selinux/netlabel.c2
-rw-r--r--security/selinux/netnode.c22
-rw-r--r--security/selinux/netport.c26
-rw-r--r--security/selinux/selinuxfs.c3
-rw-r--r--security/selinux/ss/ebitmap.c2
-rw-r--r--security/selinux/ss/mls.c2
-rw-r--r--security/selinux/ss/mls.h2
-rw-r--r--security/selinux/ss/policydb.c2
-rw-r--r--security/selinux/ss/services.c2
-rw-r--r--security/selinux/xfrm.c2
-rw-r--r--security/smack/smack_lsm.c7
-rw-r--r--security/tf_driver/Kconfig8
-rw-r--r--security/tf_driver/Makefile36
-rw-r--r--security/tf_driver/s_version.h92
-rw-r--r--security/tf_driver/tf_comm.c1745
-rw-r--r--security/tf_driver/tf_comm.h202
-rw-r--r--security/tf_driver/tf_comm_tz.c885
-rw-r--r--security/tf_driver/tf_conn.c1574
-rw-r--r--security/tf_driver/tf_conn.h106
-rw-r--r--security/tf_driver/tf_defs.h538
-rw-r--r--security/tf_driver/tf_device.c796
-rw-r--r--security/tf_driver/tf_protocol.h690
-rw-r--r--security/tf_driver/tf_util.c1143
-rw-r--r--security/tf_driver/tf_util.h122
-rw-r--r--security/tomoyo/.gitignore2
-rw-r--r--security/tomoyo/Kconfig61
-rw-r--r--security/tomoyo/Makefile49
-rw-r--r--security/tomoyo/audit.c456
-rw-r--r--security/tomoyo/common.c1964
-rw-r--r--security/tomoyo/common.h1197
-rw-r--r--security/tomoyo/condition.c1035
-rw-r--r--security/tomoyo/domain.c630
-rw-r--r--security/tomoyo/file.c954
-rw-r--r--security/tomoyo/gc.c551
-rw-r--r--security/tomoyo/group.c61
-rw-r--r--security/tomoyo/load_policy.c80
-rw-r--r--security/tomoyo/memory.c173
-rw-r--r--security/tomoyo/mount.c176
-rw-r--r--security/tomoyo/realpath.c231
-rw-r--r--security/tomoyo/securityfs_if.c22
-rw-r--r--security/tomoyo/tomoyo.c238
-rw-r--r--security/tomoyo/util.c363
70 files changed, 14011 insertions, 2765 deletions
diff --git a/security/Kconfig b/security/Kconfig
index e0f08b52e4a..85923b649d1 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -185,6 +185,7 @@ source security/selinux/Kconfig
185source security/smack/Kconfig 185source security/smack/Kconfig
186source security/tomoyo/Kconfig 186source security/tomoyo/Kconfig
187source security/apparmor/Kconfig 187source security/apparmor/Kconfig
188source security/tf_driver/Kconfig
188 189
189source security/integrity/ima/Kconfig 190source security/integrity/ima/Kconfig
190 191
diff --git a/security/Makefile b/security/Makefile
index 8bb0fe9e1ca..9962092f065 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -7,6 +7,7 @@ subdir-$(CONFIG_SECURITY_SELINUX) += selinux
7subdir-$(CONFIG_SECURITY_SMACK) += smack 7subdir-$(CONFIG_SECURITY_SMACK) += smack
8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo 8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo
9subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor 9subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
10subdir-$(CONFIG_TRUSTED_FOUNDATIONS) += tf_driver
10 11
11# always enable default capabilities 12# always enable default capabilities
12obj-y += commoncap.o 13obj-y += commoncap.o
@@ -22,6 +23,7 @@ obj-$(CONFIG_AUDIT) += lsm_audit.o
22obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o 23obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o
23obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o 24obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o
24obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o 25obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
26obj-$(CONFIG_TRUSTED_FOUNDATIONS) += tf_driver/built-in.o
25 27
26# Object integrity file lists 28# Object integrity file lists
27subdir-$(CONFIG_IMA) += integrity/ima 29subdir-$(CONFIG_IMA) += integrity/ima
diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore
index 4d995aeaebc..9cdec70d72b 100644
--- a/security/apparmor/.gitignore
+++ b/security/apparmor/.gitignore
@@ -1,6 +1,5 @@
1# 1#
2# Generated include files 2# Generated include files
3# 3#
4af_names.h
5capability_names.h 4capability_names.h
6rlim_names.h 5rlim_names.h
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index c825c6e0b63..c1e18ba5bdc 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -67,13 +67,12 @@ static int may_change_ptraced_domain(struct task_struct *task,
67 int error = 0; 67 int error = 0;
68 68
69 rcu_read_lock(); 69 rcu_read_lock();
70 tracer = tracehook_tracer_task(task); 70 tracer = ptrace_parent(task);
71 if (tracer) { 71 if (tracer) {
72 /* released below */ 72 /* released below */
73 cred = get_task_cred(tracer); 73 cred = get_task_cred(tracer);
74 tracerp = aa_cred_profile(cred); 74 tracerp = aa_cred_profile(cred);
75 } 75 }
76 rcu_read_unlock();
77 76
78 /* not ptraced */ 77 /* not ptraced */
79 if (!tracer || unconfined(tracerp)) 78 if (!tracer || unconfined(tracerp))
@@ -82,6 +81,7 @@ static int may_change_ptraced_domain(struct task_struct *task,
82 error = aa_may_ptrace(tracer, tracerp, to_profile, PTRACE_MODE_ATTACH); 81 error = aa_may_ptrace(tracer, tracerp, to_profile, PTRACE_MODE_ATTACH);
83 82
84out: 83out:
84 rcu_read_unlock();
85 if (cred) 85 if (cred)
86 put_cred(cred); 86 put_cred(cred);
87 87
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index 506d2baf614..b82e383beb7 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -12,6 +12,7 @@
12 * License. 12 * License.
13 */ 13 */
14 14
15#include <linux/mm.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/string.h> 17#include <linux/string.h>
17#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 3d2fd141dff..37832026e58 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -127,7 +127,7 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
127 *inheritable = cred->cap_inheritable; 127 *inheritable = cred->cap_inheritable;
128 *permitted = cred->cap_permitted; 128 *permitted = cred->cap_permitted;
129 129
130 if (!unconfined(profile)) { 130 if (!unconfined(profile) && !COMPLAIN_MODE(profile)) {
131 *effective = cap_intersect(*effective, profile->caps.allow); 131 *effective = cap_intersect(*effective, profile->caps.allow);
132 *permitted = cap_intersect(*permitted, profile->caps.allow); 132 *permitted = cap_intersect(*permitted, profile->caps.allow);
133 } 133 }
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 36cc0cc39e7..b566eba4a65 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -57,23 +57,44 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen)
57static int d_namespace_path(struct path *path, char *buf, int buflen, 57static int d_namespace_path(struct path *path, char *buf, int buflen,
58 char **name, int flags) 58 char **name, int flags)
59{ 59{
60 struct path root, tmp;
61 char *res; 60 char *res;
62 int connected, error = 0; 61 int error = 0;
62 int connected = 1;
63
64 if (path->mnt->mnt_flags & MNT_INTERNAL) {
65 /* it's not mounted anywhere */
66 res = dentry_path(path->dentry, buf, buflen);
67 *name = res;
68 if (IS_ERR(res)) {
69 *name = buf;
70 return PTR_ERR(res);
71 }
72 if (path->dentry->d_sb->s_magic == PROC_SUPER_MAGIC &&
73 strncmp(*name, "/sys/", 5) == 0) {
74 /* TODO: convert over to using a per namespace
75 * control instead of hard coded /proc
76 */
77 return prepend(name, *name - buf, "/proc", 5);
78 }
79 return 0;
80 }
63 81
64 /* Get the root we want to resolve too, released below */ 82 /* resolve paths relative to chroot?*/
65 if (flags & PATH_CHROOT_REL) { 83 if (flags & PATH_CHROOT_REL) {
66 /* resolve paths relative to chroot */ 84 struct path root;
67 get_fs_root(current->fs, &root); 85 get_fs_root(current->fs, &root);
68 } else { 86 res = __d_path(path, &root, buf, buflen);
69 /* resolve paths relative to namespace */ 87 if (res && !IS_ERR(res)) {
70 root.mnt = current->nsproxy->mnt_ns->root; 88 /* everything's fine */
71 root.dentry = root.mnt->mnt_root; 89 *name = res;
72 path_get(&root); 90 path_put(&root);
91 goto ok;
92 }
93 path_put(&root);
94 connected = 0;
73 } 95 }
74 96
75 tmp = root; 97 res = d_absolute_path(path, buf, buflen);
76 res = __d_path(path, &tmp, buf, buflen);
77 98
78 *name = res; 99 *name = res;
79 /* handle error conditions - and still allow a partial path to 100 /* handle error conditions - and still allow a partial path to
@@ -84,7 +105,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
84 *name = buf; 105 *name = buf;
85 goto out; 106 goto out;
86 } 107 }
108 if (!our_mnt(path->mnt))
109 connected = 0;
87 110
111ok:
88 /* Handle two cases: 112 /* Handle two cases:
89 * 1. A deleted dentry && profile is not allowing mediation of deleted 113 * 1. A deleted dentry && profile is not allowing mediation of deleted
90 * 2. On some filesystems, newly allocated dentries appear to the 114 * 2. On some filesystems, newly allocated dentries appear to the
@@ -97,10 +121,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
97 goto out; 121 goto out;
98 } 122 }
99 123
100 /* Determine if the path is connected to the expected root */ 124 /* If the path is not connected to the expected root,
101 connected = tmp.dentry == root.dentry && tmp.mnt == root.mnt;
102
103 /* If the path is not connected,
104 * check if it is a sysctl and handle specially else remove any 125 * check if it is a sysctl and handle specially else remove any
105 * leading / that __d_path may have returned. 126 * leading / that __d_path may have returned.
106 * Unless 127 * Unless
@@ -112,17 +133,9 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
112 * namespace root. 133 * namespace root.
113 */ 134 */
114 if (!connected) { 135 if (!connected) {
115 /* is the disconnect path a sysctl? */ 136 if (!(flags & PATH_CONNECT_PATH) &&
116 if (tmp.dentry->d_sb->s_magic == PROC_SUPER_MAGIC &&
117 strncmp(*name, "/sys/", 5) == 0) {
118 /* TODO: convert over to using a per namespace
119 * control instead of hard coded /proc
120 */
121 error = prepend(name, *name - buf, "/proc", 5);
122 } else if (!(flags & PATH_CONNECT_PATH) &&
123 !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) && 137 !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
124 (tmp.mnt == current->nsproxy->mnt_ns->root && 138 our_mnt(path->mnt))) {
125 tmp.dentry == tmp.mnt->mnt_root))) {
126 /* disconnected path, don't return pathname starting 139 /* disconnected path, don't return pathname starting
127 * with '/' 140 * with '/'
128 */ 141 */
@@ -133,8 +146,6 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
133 } 146 }
134 147
135out: 148out:
136 path_put(&root);
137
138 return error; 149 return error;
139} 150}
140 151
diff --git a/security/capability.c b/security/capability.c
index bbb51156261..2984ea4f776 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -181,7 +181,7 @@ static int cap_inode_follow_link(struct dentry *dentry,
181 return 0; 181 return 0;
182} 182}
183 183
184static int cap_inode_permission(struct inode *inode, int mask, unsigned flags) 184static int cap_inode_permission(struct inode *inode, int mask)
185{ 185{
186 return 0; 186 return 0;
187} 187}
diff --git a/security/commoncap.c b/security/commoncap.c
index a93b3b73307..e508e2b170a 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -29,6 +29,10 @@
29#include <linux/securebits.h> 29#include <linux/securebits.h>
30#include <linux/user_namespace.h> 30#include <linux/user_namespace.h>
31 31
32#ifdef CONFIG_ANDROID_PARANOID_NETWORK
33#include <linux/android_aid.h>
34#endif
35
32/* 36/*
33 * If a non-root user executes a setuid-root binary in 37 * If a non-root user executes a setuid-root binary in
34 * !secure(SECURE_NOROOT) mode, then we raise capabilities. 38 * !secure(SECURE_NOROOT) mode, then we raise capabilities.
@@ -83,6 +87,12 @@ EXPORT_SYMBOL(cap_netlink_recv);
83int cap_capable(struct task_struct *tsk, const struct cred *cred, 87int cap_capable(struct task_struct *tsk, const struct cred *cred,
84 struct user_namespace *targ_ns, int cap, int audit) 88 struct user_namespace *targ_ns, int cap, int audit)
85{ 89{
90#ifdef CONFIG_ANDROID_PARANOID_NETWORK
91 if (cap == CAP_NET_RAW && in_egroup_p(AID_NET_RAW))
92 return 0;
93 if (cap == CAP_NET_ADMIN && in_egroup_p(AID_NET_ADMIN))
94 return 0;
95#endif
86 for (;;) { 96 for (;;) {
87 /* The creator of the user namespace has all caps. */ 97 /* The creator of the user namespace has all caps. */
88 if (targ_ns != &init_user_ns && targ_ns->creator == cred->user) 98 if (targ_ns != &init_user_ns && targ_ns->creator == cred->user)
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 1be68269e1c..4450fbeec41 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -125,14 +125,6 @@ static int dev_whitelist_add(struct dev_cgroup *dev_cgroup,
125 return 0; 125 return 0;
126} 126}
127 127
128static void whitelist_item_free(struct rcu_head *rcu)
129{
130 struct dev_whitelist_item *item;
131
132 item = container_of(rcu, struct dev_whitelist_item, rcu);
133 kfree(item);
134}
135
136/* 128/*
137 * called under devcgroup_mutex 129 * called under devcgroup_mutex
138 */ 130 */
@@ -155,7 +147,7 @@ remove:
155 walk->access &= ~wh->access; 147 walk->access &= ~wh->access;
156 if (!walk->access) { 148 if (!walk->access) {
157 list_del_rcu(&walk->list); 149 list_del_rcu(&walk->list);
158 call_rcu(&walk->rcu, whitelist_item_free); 150 kfree_rcu(walk, rcu);
159 } 151 }
160 } 152 }
161} 153}
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index da36d2c085a..5335605571f 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -177,8 +177,8 @@ void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
177 strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX); 177 strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
178 178
179 result = ima_store_template(entry, violation, inode); 179 result = ima_store_template(entry, violation, inode);
180 if (!result) 180 if (!result || result == -EEXIST)
181 iint->flags |= IMA_MEASURED; 181 iint->flags |= IMA_MEASURED;
182 else 182 if (result < 0)
183 kfree(entry); 183 kfree(entry);
184} 184}
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 39d66dc2b8e..26b46ff7466 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -86,7 +86,7 @@ static void ima_check_last_writer(struct ima_iint_cache *iint,
86 struct inode *inode, 86 struct inode *inode,
87 struct file *file) 87 struct file *file)
88{ 88{
89 mode_t mode = file->f_mode; 89 fmode_t mode = file->f_mode;
90 90
91 mutex_lock(&iint->mutex); 91 mutex_lock(&iint->mutex);
92 if (mode & FMODE_WRITE && 92 if (mode & FMODE_WRITE &&
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index 8e28f04a5e2..55a6271bce7 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -23,6 +23,8 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include "ima.h" 24#include "ima.h"
25 25
26#define AUDIT_CAUSE_LEN_MAX 32
27
26LIST_HEAD(ima_measurements); /* list of all measurements */ 28LIST_HEAD(ima_measurements); /* list of all measurements */
27 29
28/* key: inode (before secure-hashing a file) */ 30/* key: inode (before secure-hashing a file) */
@@ -94,7 +96,8 @@ static int ima_pcr_extend(const u8 *hash)
94 96
95 result = tpm_pcr_extend(TPM_ANY_NUM, CONFIG_IMA_MEASURE_PCR_IDX, hash); 97 result = tpm_pcr_extend(TPM_ANY_NUM, CONFIG_IMA_MEASURE_PCR_IDX, hash);
96 if (result != 0) 98 if (result != 0)
97 pr_err("IMA: Error Communicating to TPM chip\n"); 99 pr_err("IMA: Error Communicating to TPM chip, result: %d\n",
100 result);
98 return result; 101 return result;
99} 102}
100 103
@@ -106,14 +109,16 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
106{ 109{
107 u8 digest[IMA_DIGEST_SIZE]; 110 u8 digest[IMA_DIGEST_SIZE];
108 const char *audit_cause = "hash_added"; 111 const char *audit_cause = "hash_added";
112 char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX];
109 int audit_info = 1; 113 int audit_info = 1;
110 int result = 0; 114 int result = 0, tpmresult = 0;
111 115
112 mutex_lock(&ima_extend_list_mutex); 116 mutex_lock(&ima_extend_list_mutex);
113 if (!violation) { 117 if (!violation) {
114 memcpy(digest, entry->digest, sizeof digest); 118 memcpy(digest, entry->digest, sizeof digest);
115 if (ima_lookup_digest_entry(digest)) { 119 if (ima_lookup_digest_entry(digest)) {
116 audit_cause = "hash_exists"; 120 audit_cause = "hash_exists";
121 result = -EEXIST;
117 goto out; 122 goto out;
118 } 123 }
119 } 124 }
@@ -128,9 +133,11 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
128 if (violation) /* invalidate pcr */ 133 if (violation) /* invalidate pcr */
129 memset(digest, 0xff, sizeof digest); 134 memset(digest, 0xff, sizeof digest);
130 135
131 result = ima_pcr_extend(digest); 136 tpmresult = ima_pcr_extend(digest);
132 if (result != 0) { 137 if (tpmresult != 0) {
133 audit_cause = "TPM error"; 138 snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TPM_error(%d)",
139 tpmresult);
140 audit_cause = tpm_audit_cause;
134 audit_info = 0; 141 audit_info = 0;
135 } 142 }
136out: 143out:
diff --git a/security/keys/Makefile b/security/keys/Makefile
index 1bf090a885f..b34cc6ee690 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -14,7 +14,7 @@ obj-y := \
14 user_defined.o 14 user_defined.o
15 15
16obj-$(CONFIG_TRUSTED_KEYS) += trusted.o 16obj-$(CONFIG_TRUSTED_KEYS) += trusted.o
17obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted.o 17obj-$(CONFIG_ENCRYPTED_KEYS) += ecryptfs_format.o encrypted.o
18obj-$(CONFIG_KEYS_COMPAT) += compat.o 18obj-$(CONFIG_KEYS_COMPAT) += compat.o
19obj-$(CONFIG_PROC_FS) += proc.o 19obj-$(CONFIG_PROC_FS) += proc.o
20obj-$(CONFIG_SYSCTL) += sysctl.o 20obj-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/security/keys/ecryptfs_format.c b/security/keys/ecryptfs_format.c
new file mode 100644
index 00000000000..6daa3b6ff9e
--- /dev/null
+++ b/security/keys/ecryptfs_format.c
@@ -0,0 +1,81 @@
1/*
2 * ecryptfs_format.c: helper functions for the encrypted key type
3 *
4 * Copyright (C) 2006 International Business Machines Corp.
5 * Copyright (C) 2010 Politecnico di Torino, Italy
6 * TORSEC group -- http://security.polito.it
7 *
8 * Authors:
9 * Michael A. Halcrow <mahalcro@us.ibm.com>
10 * Tyler Hicks <tyhicks@ou.edu>
11 * Roberto Sassu <roberto.sassu@polito.it>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, version 2 of the License.
16 */
17
18#include <linux/module.h>
19#include "ecryptfs_format.h"
20
21u8 *ecryptfs_get_auth_tok_key(struct ecryptfs_auth_tok *auth_tok)
22{
23 return auth_tok->token.password.session_key_encryption_key;
24}
25EXPORT_SYMBOL(ecryptfs_get_auth_tok_key);
26
27/*
28 * ecryptfs_get_versions()
29 *
30 * Source code taken from the software 'ecryptfs-utils' version 83.
31 *
32 */
33void ecryptfs_get_versions(int *major, int *minor, int *file_version)
34{
35 *major = ECRYPTFS_VERSION_MAJOR;
36 *minor = ECRYPTFS_VERSION_MINOR;
37 if (file_version)
38 *file_version = ECRYPTFS_SUPPORTED_FILE_VERSION;
39}
40EXPORT_SYMBOL(ecryptfs_get_versions);
41
42/*
43 * ecryptfs_fill_auth_tok - fill the ecryptfs_auth_tok structure
44 *
45 * Fill the ecryptfs_auth_tok structure with required ecryptfs data.
46 * The source code is inspired to the original function generate_payload()
47 * shipped with the software 'ecryptfs-utils' version 83.
48 *
49 */
50int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
51 const char *key_desc)
52{
53 int major, minor;
54
55 ecryptfs_get_versions(&major, &minor, NULL);
56 auth_tok->version = (((uint16_t)(major << 8) & 0xFF00)
57 | ((uint16_t)minor & 0x00FF));
58 auth_tok->token_type = ECRYPTFS_PASSWORD;
59 strncpy((char *)auth_tok->token.password.signature, key_desc,
60 ECRYPTFS_PASSWORD_SIG_SIZE);
61 auth_tok->token.password.session_key_encryption_key_bytes =
62 ECRYPTFS_MAX_KEY_BYTES;
63 /*
64 * Removed auth_tok->token.password.salt and
65 * auth_tok->token.password.session_key_encryption_key
66 * initialization from the original code
67 */
68 /* TODO: Make the hash parameterizable via policy */
69 auth_tok->token.password.flags |=
70 ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET;
71 /* The kernel code will encrypt the session key. */
72 auth_tok->session_key.encrypted_key[0] = 0;
73 auth_tok->session_key.encrypted_key_size = 0;
74 /* Default; subject to change by kernel eCryptfs */
75 auth_tok->token.password.hash_algo = PGP_DIGEST_ALGO_SHA512;
76 auth_tok->token.password.flags &= ~(ECRYPTFS_PERSISTENT_PASSWORD);
77 return 0;
78}
79EXPORT_SYMBOL(ecryptfs_fill_auth_tok);
80
81MODULE_LICENSE("GPL");
diff --git a/security/keys/ecryptfs_format.h b/security/keys/ecryptfs_format.h
new file mode 100644
index 00000000000..40294de238b
--- /dev/null
+++ b/security/keys/ecryptfs_format.h
@@ -0,0 +1,30 @@
1/*
2 * ecryptfs_format.h: helper functions for the encrypted key type
3 *
4 * Copyright (C) 2006 International Business Machines Corp.
5 * Copyright (C) 2010 Politecnico di Torino, Italy
6 * TORSEC group -- http://security.polito.it
7 *
8 * Authors:
9 * Michael A. Halcrow <mahalcro@us.ibm.com>
10 * Tyler Hicks <tyhicks@ou.edu>
11 * Roberto Sassu <roberto.sassu@polito.it>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, version 2 of the License.
16 */
17
18#ifndef __KEYS_ECRYPTFS_H
19#define __KEYS_ECRYPTFS_H
20
21#include <linux/ecryptfs.h>
22
23#define PGP_DIGEST_ALGO_SHA512 10
24
25u8 *ecryptfs_get_auth_tok_key(struct ecryptfs_auth_tok *auth_tok);
26void ecryptfs_get_versions(int *major, int *minor, int *file_version);
27int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
28 const char *key_desc);
29
30#endif /* __KEYS_ECRYPTFS_H */
diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c
index b1cba5bf0a5..e7eca9ec4c6 100644
--- a/security/keys/encrypted.c
+++ b/security/keys/encrypted.c
@@ -1,8 +1,11 @@
1/* 1/*
2 * Copyright (C) 2010 IBM Corporation 2 * Copyright (C) 2010 IBM Corporation
3 * Copyright (C) 2010 Politecnico di Torino, Italy
4 * TORSEC group -- http://security.polito.it
3 * 5 *
4 * Author: 6 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com> 7 * Mimi Zohar <zohar@us.ibm.com>
8 * Roberto Sassu <roberto.sassu@polito.it>
6 * 9 *
7 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -26,22 +29,27 @@
26#include <linux/rcupdate.h> 29#include <linux/rcupdate.h>
27#include <linux/scatterlist.h> 30#include <linux/scatterlist.h>
28#include <linux/crypto.h> 31#include <linux/crypto.h>
32#include <linux/ctype.h>
29#include <crypto/hash.h> 33#include <crypto/hash.h>
30#include <crypto/sha.h> 34#include <crypto/sha.h>
31#include <crypto/aes.h> 35#include <crypto/aes.h>
32 36
33#include "encrypted.h" 37#include "encrypted.h"
38#include "ecryptfs_format.h"
34 39
35static const char KEY_TRUSTED_PREFIX[] = "trusted:"; 40static const char KEY_TRUSTED_PREFIX[] = "trusted:";
36static const char KEY_USER_PREFIX[] = "user:"; 41static const char KEY_USER_PREFIX[] = "user:";
37static const char hash_alg[] = "sha256"; 42static const char hash_alg[] = "sha256";
38static const char hmac_alg[] = "hmac(sha256)"; 43static const char hmac_alg[] = "hmac(sha256)";
39static const char blkcipher_alg[] = "cbc(aes)"; 44static const char blkcipher_alg[] = "cbc(aes)";
45static const char key_format_default[] = "default";
46static const char key_format_ecryptfs[] = "ecryptfs";
40static unsigned int ivsize; 47static unsigned int ivsize;
41static int blksize; 48static int blksize;
42 49
43#define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1) 50#define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1)
44#define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1) 51#define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1)
52#define KEY_ECRYPTFS_DESC_LEN 16
45#define HASH_SIZE SHA256_DIGEST_SIZE 53#define HASH_SIZE SHA256_DIGEST_SIZE
46#define MAX_DATA_SIZE 4096 54#define MAX_DATA_SIZE 4096
47#define MIN_DATA_SIZE 20 55#define MIN_DATA_SIZE 20
@@ -58,6 +66,16 @@ enum {
58 Opt_err = -1, Opt_new, Opt_load, Opt_update 66 Opt_err = -1, Opt_new, Opt_load, Opt_update
59}; 67};
60 68
69enum {
70 Opt_error = -1, Opt_default, Opt_ecryptfs
71};
72
73static const match_table_t key_format_tokens = {
74 {Opt_default, "default"},
75 {Opt_ecryptfs, "ecryptfs"},
76 {Opt_error, NULL}
77};
78
61static const match_table_t key_tokens = { 79static const match_table_t key_tokens = {
62 {Opt_new, "new"}, 80 {Opt_new, "new"},
63 {Opt_load, "load"}, 81 {Opt_load, "load"},
@@ -82,9 +100,37 @@ static int aes_get_sizes(void)
82} 100}
83 101
84/* 102/*
103 * valid_ecryptfs_desc - verify the description of a new/loaded encrypted key
104 *
105 * The description of a encrypted key with format 'ecryptfs' must contain
106 * exactly 16 hexadecimal characters.
107 *
108 */
109static int valid_ecryptfs_desc(const char *ecryptfs_desc)
110{
111 int i;
112
113 if (strlen(ecryptfs_desc) != KEY_ECRYPTFS_DESC_LEN) {
114 pr_err("encrypted_key: key description must be %d hexadecimal "
115 "characters long\n", KEY_ECRYPTFS_DESC_LEN);
116 return -EINVAL;
117 }
118
119 for (i = 0; i < KEY_ECRYPTFS_DESC_LEN; i++) {
120 if (!isxdigit(ecryptfs_desc[i])) {
121 pr_err("encrypted_key: key description must contain "
122 "only hexadecimal characters\n");
123 return -EINVAL;
124 }
125 }
126
127 return 0;
128}
129
130/*
85 * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key 131 * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key
86 * 132 *
87 * key-type:= "trusted:" | "encrypted:" 133 * key-type:= "trusted:" | "user:"
88 * desc:= master-key description 134 * desc:= master-key description
89 * 135 *
90 * Verify that 'key-type' is valid and that 'desc' exists. On key update, 136 * Verify that 'key-type' is valid and that 'desc' exists. On key update,
@@ -118,8 +164,9 @@ out:
118 * datablob_parse - parse the keyctl data 164 * datablob_parse - parse the keyctl data
119 * 165 *
120 * datablob format: 166 * datablob format:
121 * new <master-key name> <decrypted data length> 167 * new [<format>] <master-key name> <decrypted data length>
122 * load <master-key name> <decrypted data length> <encrypted iv + data> 168 * load [<format>] <master-key name> <decrypted data length>
169 * <encrypted iv + data>
123 * update <new-master-key name> 170 * update <new-master-key name>
124 * 171 *
125 * Tokenizes a copy of the keyctl data, returning a pointer to each token, 172 * Tokenizes a copy of the keyctl data, returning a pointer to each token,
@@ -127,52 +174,95 @@ out:
127 * 174 *
128 * On success returns 0, otherwise -EINVAL. 175 * On success returns 0, otherwise -EINVAL.
129 */ 176 */
130static int datablob_parse(char *datablob, char **master_desc, 177static int datablob_parse(char *datablob, const char **format,
131 char **decrypted_datalen, char **hex_encoded_iv) 178 char **master_desc, char **decrypted_datalen,
179 char **hex_encoded_iv)
132{ 180{
133 substring_t args[MAX_OPT_ARGS]; 181 substring_t args[MAX_OPT_ARGS];
134 int ret = -EINVAL; 182 int ret = -EINVAL;
135 int key_cmd; 183 int key_cmd;
136 char *p; 184 int key_format;
185 char *p, *keyword;
186
187 keyword = strsep(&datablob, " \t");
188 if (!keyword) {
189 pr_info("encrypted_key: insufficient parameters specified\n");
190 return ret;
191 }
192 key_cmd = match_token(keyword, key_tokens, args);
137 193
194 /* Get optional format: default | ecryptfs */
138 p = strsep(&datablob, " \t"); 195 p = strsep(&datablob, " \t");
139 if (!p) 196 if (!p) {
197 pr_err("encrypted_key: insufficient parameters specified\n");
140 return ret; 198 return ret;
141 key_cmd = match_token(p, key_tokens, args); 199 }
142 200
143 *master_desc = strsep(&datablob, " \t"); 201 key_format = match_token(p, key_format_tokens, args);
144 if (!*master_desc) 202 switch (key_format) {
203 case Opt_ecryptfs:
204 case Opt_default:
205 *format = p;
206 *master_desc = strsep(&datablob, " \t");
207 break;
208 case Opt_error:
209 *master_desc = p;
210 break;
211 }
212
213 if (!*master_desc) {
214 pr_info("encrypted_key: master key parameter is missing\n");
145 goto out; 215 goto out;
216 }
146 217
147 if (valid_master_desc(*master_desc, NULL) < 0) 218 if (valid_master_desc(*master_desc, NULL) < 0) {
219 pr_info("encrypted_key: master key parameter \'%s\' "
220 "is invalid\n", *master_desc);
148 goto out; 221 goto out;
222 }
149 223
150 if (decrypted_datalen) { 224 if (decrypted_datalen) {
151 *decrypted_datalen = strsep(&datablob, " \t"); 225 *decrypted_datalen = strsep(&datablob, " \t");
152 if (!*decrypted_datalen) 226 if (!*decrypted_datalen) {
227 pr_info("encrypted_key: keylen parameter is missing\n");
153 goto out; 228 goto out;
229 }
154 } 230 }
155 231
156 switch (key_cmd) { 232 switch (key_cmd) {
157 case Opt_new: 233 case Opt_new:
158 if (!decrypted_datalen) 234 if (!decrypted_datalen) {
235 pr_info("encrypted_key: keyword \'%s\' not allowed "
236 "when called from .update method\n", keyword);
159 break; 237 break;
238 }
160 ret = 0; 239 ret = 0;
161 break; 240 break;
162 case Opt_load: 241 case Opt_load:
163 if (!decrypted_datalen) 242 if (!decrypted_datalen) {
243 pr_info("encrypted_key: keyword \'%s\' not allowed "
244 "when called from .update method\n", keyword);
164 break; 245 break;
246 }
165 *hex_encoded_iv = strsep(&datablob, " \t"); 247 *hex_encoded_iv = strsep(&datablob, " \t");
166 if (!*hex_encoded_iv) 248 if (!*hex_encoded_iv) {
249 pr_info("encrypted_key: hex blob is missing\n");
167 break; 250 break;
251 }
168 ret = 0; 252 ret = 0;
169 break; 253 break;
170 case Opt_update: 254 case Opt_update:
171 if (decrypted_datalen) 255 if (decrypted_datalen) {
256 pr_info("encrypted_key: keyword \'%s\' not allowed "
257 "when called from .instantiate method\n",
258 keyword);
172 break; 259 break;
260 }
173 ret = 0; 261 ret = 0;
174 break; 262 break;
175 case Opt_err: 263 case Opt_err:
264 pr_info("encrypted_key: keyword \'%s\' not recognized\n",
265 keyword);
176 break; 266 break;
177 } 267 }
178out: 268out:
@@ -197,8 +287,8 @@ static char *datablob_format(struct encrypted_key_payload *epayload,
197 ascii_buf[asciiblob_len] = '\0'; 287 ascii_buf[asciiblob_len] = '\0';
198 288
199 /* copy datablob master_desc and datalen strings */ 289 /* copy datablob master_desc and datalen strings */
200 len = sprintf(ascii_buf, "%s %s ", epayload->master_desc, 290 len = sprintf(ascii_buf, "%s %s %s ", epayload->format,
201 epayload->datalen); 291 epayload->master_desc, epayload->datalen);
202 292
203 /* convert the hex encoded iv, encrypted-data and HMAC to ascii */ 293 /* convert the hex encoded iv, encrypted-data and HMAC to ascii */
204 bufp = &ascii_buf[len]; 294 bufp = &ascii_buf[len];
@@ -378,11 +468,13 @@ static struct key *request_master_key(struct encrypted_key_payload *epayload,
378 } else 468 } else
379 goto out; 469 goto out;
380 470
381 if (IS_ERR(mkey)) 471 if (IS_ERR(mkey)) {
382 pr_info("encrypted_key: key %s not found", 472 pr_info("encrypted_key: key %s not found",
383 epayload->master_desc); 473 epayload->master_desc);
384 if (mkey) 474 goto out;
385 dump_master_key(*master_key, *master_keylen); 475 }
476
477 dump_master_key(*master_key, *master_keylen);
386out: 478out:
387 return mkey; 479 return mkey;
388} 480}
@@ -439,9 +531,9 @@ static int datablob_hmac_append(struct encrypted_key_payload *epayload,
439 if (ret < 0) 531 if (ret < 0)
440 goto out; 532 goto out;
441 533
442 digest = epayload->master_desc + epayload->datablob_len; 534 digest = epayload->format + epayload->datablob_len;
443 ret = calc_hmac(digest, derived_key, sizeof derived_key, 535 ret = calc_hmac(digest, derived_key, sizeof derived_key,
444 epayload->master_desc, epayload->datablob_len); 536 epayload->format, epayload->datablob_len);
445 if (!ret) 537 if (!ret)
446 dump_hmac(NULL, digest, HASH_SIZE); 538 dump_hmac(NULL, digest, HASH_SIZE);
447out: 539out:
@@ -450,26 +542,35 @@ out:
450 542
451/* verify HMAC before decrypting encrypted key */ 543/* verify HMAC before decrypting encrypted key */
452static int datablob_hmac_verify(struct encrypted_key_payload *epayload, 544static int datablob_hmac_verify(struct encrypted_key_payload *epayload,
453 const u8 *master_key, size_t master_keylen) 545 const u8 *format, const u8 *master_key,
546 size_t master_keylen)
454{ 547{
455 u8 derived_key[HASH_SIZE]; 548 u8 derived_key[HASH_SIZE];
456 u8 digest[HASH_SIZE]; 549 u8 digest[HASH_SIZE];
457 int ret; 550 int ret;
551 char *p;
552 unsigned short len;
458 553
459 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen); 554 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
460 if (ret < 0) 555 if (ret < 0)
461 goto out; 556 goto out;
462 557
463 ret = calc_hmac(digest, derived_key, sizeof derived_key, 558 len = epayload->datablob_len;
464 epayload->master_desc, epayload->datablob_len); 559 if (!format) {
560 p = epayload->master_desc;
561 len -= strlen(epayload->format) + 1;
562 } else
563 p = epayload->format;
564
565 ret = calc_hmac(digest, derived_key, sizeof derived_key, p, len);
465 if (ret < 0) 566 if (ret < 0)
466 goto out; 567 goto out;
467 ret = memcmp(digest, epayload->master_desc + epayload->datablob_len, 568 ret = memcmp(digest, epayload->format + epayload->datablob_len,
468 sizeof digest); 569 sizeof digest);
469 if (ret) { 570 if (ret) {
470 ret = -EINVAL; 571 ret = -EINVAL;
471 dump_hmac("datablob", 572 dump_hmac("datablob",
472 epayload->master_desc + epayload->datablob_len, 573 epayload->format + epayload->datablob_len,
473 HASH_SIZE); 574 HASH_SIZE);
474 dump_hmac("calc", digest, HASH_SIZE); 575 dump_hmac("calc", digest, HASH_SIZE);
475 } 576 }
@@ -514,13 +615,16 @@ out:
514 615
515/* Allocate memory for decrypted key and datablob. */ 616/* Allocate memory for decrypted key and datablob. */
516static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, 617static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
618 const char *format,
517 const char *master_desc, 619 const char *master_desc,
518 const char *datalen) 620 const char *datalen)
519{ 621{
520 struct encrypted_key_payload *epayload = NULL; 622 struct encrypted_key_payload *epayload = NULL;
521 unsigned short datablob_len; 623 unsigned short datablob_len;
522 unsigned short decrypted_datalen; 624 unsigned short decrypted_datalen;
625 unsigned short payload_datalen;
523 unsigned int encrypted_datalen; 626 unsigned int encrypted_datalen;
627 unsigned int format_len;
524 long dlen; 628 long dlen;
525 int ret; 629 int ret;
526 630
@@ -528,29 +632,43 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
528 if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE) 632 if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE)
529 return ERR_PTR(-EINVAL); 633 return ERR_PTR(-EINVAL);
530 634
635 format_len = (!format) ? strlen(key_format_default) : strlen(format);
531 decrypted_datalen = dlen; 636 decrypted_datalen = dlen;
637 payload_datalen = decrypted_datalen;
638 if (format && !strcmp(format, key_format_ecryptfs)) {
639 if (dlen != ECRYPTFS_MAX_KEY_BYTES) {
640 pr_err("encrypted_key: keylen for the ecryptfs format "
641 "must be equal to %d bytes\n",
642 ECRYPTFS_MAX_KEY_BYTES);
643 return ERR_PTR(-EINVAL);
644 }
645 decrypted_datalen = ECRYPTFS_MAX_KEY_BYTES;
646 payload_datalen = sizeof(struct ecryptfs_auth_tok);
647 }
648
532 encrypted_datalen = roundup(decrypted_datalen, blksize); 649 encrypted_datalen = roundup(decrypted_datalen, blksize);
533 650
534 datablob_len = strlen(master_desc) + 1 + strlen(datalen) + 1 651 datablob_len = format_len + 1 + strlen(master_desc) + 1
535 + ivsize + 1 + encrypted_datalen; 652 + strlen(datalen) + 1 + ivsize + 1 + encrypted_datalen;
536 653
537 ret = key_payload_reserve(key, decrypted_datalen + datablob_len 654 ret = key_payload_reserve(key, payload_datalen + datablob_len
538 + HASH_SIZE + 1); 655 + HASH_SIZE + 1);
539 if (ret < 0) 656 if (ret < 0)
540 return ERR_PTR(ret); 657 return ERR_PTR(ret);
541 658
542 epayload = kzalloc(sizeof(*epayload) + decrypted_datalen + 659 epayload = kzalloc(sizeof(*epayload) + payload_datalen +
543 datablob_len + HASH_SIZE + 1, GFP_KERNEL); 660 datablob_len + HASH_SIZE + 1, GFP_KERNEL);
544 if (!epayload) 661 if (!epayload)
545 return ERR_PTR(-ENOMEM); 662 return ERR_PTR(-ENOMEM);
546 663
664 epayload->payload_datalen = payload_datalen;
547 epayload->decrypted_datalen = decrypted_datalen; 665 epayload->decrypted_datalen = decrypted_datalen;
548 epayload->datablob_len = datablob_len; 666 epayload->datablob_len = datablob_len;
549 return epayload; 667 return epayload;
550} 668}
551 669
552static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, 670static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
553 const char *hex_encoded_iv) 671 const char *format, const char *hex_encoded_iv)
554{ 672{
555 struct key *mkey; 673 struct key *mkey;
556 u8 derived_key[HASH_SIZE]; 674 u8 derived_key[HASH_SIZE];
@@ -571,14 +689,14 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
571 hex2bin(epayload->iv, hex_encoded_iv, ivsize); 689 hex2bin(epayload->iv, hex_encoded_iv, ivsize);
572 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen); 690 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen);
573 691
574 hmac = epayload->master_desc + epayload->datablob_len; 692 hmac = epayload->format + epayload->datablob_len;
575 hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE); 693 hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE);
576 694
577 mkey = request_master_key(epayload, &master_key, &master_keylen); 695 mkey = request_master_key(epayload, &master_key, &master_keylen);
578 if (IS_ERR(mkey)) 696 if (IS_ERR(mkey))
579 return PTR_ERR(mkey); 697 return PTR_ERR(mkey);
580 698
581 ret = datablob_hmac_verify(epayload, master_key, master_keylen); 699 ret = datablob_hmac_verify(epayload, format, master_key, master_keylen);
582 if (ret < 0) { 700 if (ret < 0) {
583 pr_err("encrypted_key: bad hmac (%d)\n", ret); 701 pr_err("encrypted_key: bad hmac (%d)\n", ret);
584 goto out; 702 goto out;
@@ -598,13 +716,28 @@ out:
598} 716}
599 717
600static void __ekey_init(struct encrypted_key_payload *epayload, 718static void __ekey_init(struct encrypted_key_payload *epayload,
601 const char *master_desc, const char *datalen) 719 const char *format, const char *master_desc,
720 const char *datalen)
602{ 721{
603 epayload->master_desc = epayload->decrypted_data 722 unsigned int format_len;
604 + epayload->decrypted_datalen; 723
724 format_len = (!format) ? strlen(key_format_default) : strlen(format);
725 epayload->format = epayload->payload_data + epayload->payload_datalen;
726 epayload->master_desc = epayload->format + format_len + 1;
605 epayload->datalen = epayload->master_desc + strlen(master_desc) + 1; 727 epayload->datalen = epayload->master_desc + strlen(master_desc) + 1;
606 epayload->iv = epayload->datalen + strlen(datalen) + 1; 728 epayload->iv = epayload->datalen + strlen(datalen) + 1;
607 epayload->encrypted_data = epayload->iv + ivsize + 1; 729 epayload->encrypted_data = epayload->iv + ivsize + 1;
730 epayload->decrypted_data = epayload->payload_data;
731
732 if (!format)
733 memcpy(epayload->format, key_format_default, format_len);
734 else {
735 if (!strcmp(format, key_format_ecryptfs))
736 epayload->decrypted_data =
737 ecryptfs_get_auth_tok_key((struct ecryptfs_auth_tok *)epayload->payload_data);
738
739 memcpy(epayload->format, format, format_len);
740 }
608 741
609 memcpy(epayload->master_desc, master_desc, strlen(master_desc)); 742 memcpy(epayload->master_desc, master_desc, strlen(master_desc));
610 memcpy(epayload->datalen, datalen, strlen(datalen)); 743 memcpy(epayload->datalen, datalen, strlen(datalen));
@@ -617,19 +750,29 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
617 * itself. For an old key, decrypt the hex encoded data. 750 * itself. For an old key, decrypt the hex encoded data.
618 */ 751 */
619static int encrypted_init(struct encrypted_key_payload *epayload, 752static int encrypted_init(struct encrypted_key_payload *epayload,
753 const char *key_desc, const char *format,
620 const char *master_desc, const char *datalen, 754 const char *master_desc, const char *datalen,
621 const char *hex_encoded_iv) 755 const char *hex_encoded_iv)
622{ 756{
623 int ret = 0; 757 int ret = 0;
624 758
625 __ekey_init(epayload, master_desc, datalen); 759 if (format && !strcmp(format, key_format_ecryptfs)) {
760 ret = valid_ecryptfs_desc(key_desc);
761 if (ret < 0)
762 return ret;
763
764 ecryptfs_fill_auth_tok((struct ecryptfs_auth_tok *)epayload->payload_data,
765 key_desc);
766 }
767
768 __ekey_init(epayload, format, master_desc, datalen);
626 if (!hex_encoded_iv) { 769 if (!hex_encoded_iv) {
627 get_random_bytes(epayload->iv, ivsize); 770 get_random_bytes(epayload->iv, ivsize);
628 771
629 get_random_bytes(epayload->decrypted_data, 772 get_random_bytes(epayload->decrypted_data,
630 epayload->decrypted_datalen); 773 epayload->decrypted_datalen);
631 } else 774 } else
632 ret = encrypted_key_decrypt(epayload, hex_encoded_iv); 775 ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv);
633 return ret; 776 return ret;
634} 777}
635 778
@@ -646,6 +789,7 @@ static int encrypted_instantiate(struct key *key, const void *data,
646{ 789{
647 struct encrypted_key_payload *epayload = NULL; 790 struct encrypted_key_payload *epayload = NULL;
648 char *datablob = NULL; 791 char *datablob = NULL;
792 const char *format = NULL;
649 char *master_desc = NULL; 793 char *master_desc = NULL;
650 char *decrypted_datalen = NULL; 794 char *decrypted_datalen = NULL;
651 char *hex_encoded_iv = NULL; 795 char *hex_encoded_iv = NULL;
@@ -659,18 +803,19 @@ static int encrypted_instantiate(struct key *key, const void *data,
659 return -ENOMEM; 803 return -ENOMEM;
660 datablob[datalen] = 0; 804 datablob[datalen] = 0;
661 memcpy(datablob, data, datalen); 805 memcpy(datablob, data, datalen);
662 ret = datablob_parse(datablob, &master_desc, &decrypted_datalen, 806 ret = datablob_parse(datablob, &format, &master_desc,
663 &hex_encoded_iv); 807 &decrypted_datalen, &hex_encoded_iv);
664 if (ret < 0) 808 if (ret < 0)
665 goto out; 809 goto out;
666 810
667 epayload = encrypted_key_alloc(key, master_desc, decrypted_datalen); 811 epayload = encrypted_key_alloc(key, format, master_desc,
812 decrypted_datalen);
668 if (IS_ERR(epayload)) { 813 if (IS_ERR(epayload)) {
669 ret = PTR_ERR(epayload); 814 ret = PTR_ERR(epayload);
670 goto out; 815 goto out;
671 } 816 }
672 ret = encrypted_init(epayload, master_desc, decrypted_datalen, 817 ret = encrypted_init(epayload, key->description, format, master_desc,
673 hex_encoded_iv); 818 decrypted_datalen, hex_encoded_iv);
674 if (ret < 0) { 819 if (ret < 0) {
675 kfree(epayload); 820 kfree(epayload);
676 goto out; 821 goto out;
@@ -706,6 +851,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
706 struct encrypted_key_payload *new_epayload; 851 struct encrypted_key_payload *new_epayload;
707 char *buf; 852 char *buf;
708 char *new_master_desc = NULL; 853 char *new_master_desc = NULL;
854 const char *format = NULL;
709 int ret = 0; 855 int ret = 0;
710 856
711 if (datalen <= 0 || datalen > 32767 || !data) 857 if (datalen <= 0 || datalen > 32767 || !data)
@@ -717,7 +863,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
717 863
718 buf[datalen] = 0; 864 buf[datalen] = 0;
719 memcpy(buf, data, datalen); 865 memcpy(buf, data, datalen);
720 ret = datablob_parse(buf, &new_master_desc, NULL, NULL); 866 ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL);
721 if (ret < 0) 867 if (ret < 0)
722 goto out; 868 goto out;
723 869
@@ -725,18 +871,19 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
725 if (ret < 0) 871 if (ret < 0)
726 goto out; 872 goto out;
727 873
728 new_epayload = encrypted_key_alloc(key, new_master_desc, 874 new_epayload = encrypted_key_alloc(key, epayload->format,
729 epayload->datalen); 875 new_master_desc, epayload->datalen);
730 if (IS_ERR(new_epayload)) { 876 if (IS_ERR(new_epayload)) {
731 ret = PTR_ERR(new_epayload); 877 ret = PTR_ERR(new_epayload);
732 goto out; 878 goto out;
733 } 879 }
734 880
735 __ekey_init(new_epayload, new_master_desc, epayload->datalen); 881 __ekey_init(new_epayload, epayload->format, new_master_desc,
882 epayload->datalen);
736 883
737 memcpy(new_epayload->iv, epayload->iv, ivsize); 884 memcpy(new_epayload->iv, epayload->iv, ivsize);
738 memcpy(new_epayload->decrypted_data, epayload->decrypted_data, 885 memcpy(new_epayload->payload_data, epayload->payload_data,
739 epayload->decrypted_datalen); 886 epayload->payload_datalen);
740 887
741 rcu_assign_pointer(key->payload.data, new_epayload); 888 rcu_assign_pointer(key->payload.data, new_epayload);
742 call_rcu(&epayload->rcu, encrypted_rcu_free); 889 call_rcu(&epayload->rcu, encrypted_rcu_free);
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index a06ffab3856..30e242f7bd0 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -155,7 +155,6 @@ static void keyring_destroy(struct key *keyring)
155 } 155 }
156 156
157 klist = rcu_dereference_check(keyring->payload.subscriptions, 157 klist = rcu_dereference_check(keyring->payload.subscriptions,
158 rcu_read_lock_held() ||
159 atomic_read(&keyring->usage) == 0); 158 atomic_read(&keyring->usage) == 0);
160 if (klist) { 159 if (klist) {
161 for (loop = klist->nkeys - 1; loop >= 0; loop--) 160 for (loop = klist->nkeys - 1; loop >= 0; loop--)
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 6cff37529b8..60d4e3f5e4b 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -251,6 +251,8 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id)
251 251
252 if (IS_ERR(authkey_ref)) { 252 if (IS_ERR(authkey_ref)) {
253 authkey = ERR_CAST(authkey_ref); 253 authkey = ERR_CAST(authkey_ref);
254 if (authkey == ERR_PTR(-EAGAIN))
255 authkey = ERR_PTR(-ENOKEY);
254 goto error; 256 goto error;
255 } 257 }
256 258
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 5b366d7af3c..69ff52c08e9 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -102,7 +102,8 @@ int user_update(struct key *key, const void *data, size_t datalen)
102 key->expiry = 0; 102 key->expiry = 0;
103 } 103 }
104 104
105 kfree_rcu(zap, rcu); 105 if (zap)
106 kfree_rcu(zap, rcu);
106 107
107error: 108error:
108 return ret; 109 return ret;
diff --git a/security/security.c b/security/security.c
index 4ba6d4cc061..d9e15339092 100644
--- a/security/security.c
+++ b/security/security.c
@@ -518,14 +518,7 @@ int security_inode_permission(struct inode *inode, int mask)
518{ 518{
519 if (unlikely(IS_PRIVATE(inode))) 519 if (unlikely(IS_PRIVATE(inode)))
520 return 0; 520 return 0;
521 return security_ops->inode_permission(inode, mask, 0); 521 return security_ops->inode_permission(inode, mask);
522}
523
524int security_inode_exec_permission(struct inode *inode, unsigned int flags)
525{
526 if (unlikely(IS_PRIVATE(inode)))
527 return 0;
528 return security_ops->inode_permission(inode, MAY_EXEC, flags);
529} 522}
530 523
531int security_inode_setattr(struct dentry *dentry, struct iattr *attr) 524int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
@@ -1104,6 +1097,7 @@ void security_sk_clone(const struct sock *sk, struct sock *newsk)
1104{ 1097{
1105 security_ops->sk_clone_security(sk, newsk); 1098 security_ops->sk_clone_security(sk, newsk);
1106} 1099}
1100EXPORT_SYMBOL(security_sk_clone);
1107 1101
1108void security_sk_classify_flow(struct sock *sk, struct flowi *fl) 1102void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
1109{ 1103{
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index d515b2128a4..dca1c22d927 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -527,7 +527,7 @@ int avc_audit(u32 ssid, u32 tsid,
527 * happened a little later. 527 * happened a little later.
528 */ 528 */
529 if ((a->type == LSM_AUDIT_DATA_INODE) && 529 if ((a->type == LSM_AUDIT_DATA_INODE) &&
530 (flags & IPERM_FLAG_RCU)) 530 (flags & MAY_NOT_BLOCK))
531 return -ECHILD; 531 return -ECHILD;
532 532
533 a->selinux_audit_data.tclass = tclass; 533 a->selinux_audit_data.tclass = tclass;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 20219ef5439..266a2292451 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -14,7 +14,7 @@
14 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 14 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
15 * <dgoeddel@trustedcs.com> 15 * <dgoeddel@trustedcs.com>
16 * Copyright (C) 2006, 2007, 2009 Hewlett-Packard Development Company, L.P. 16 * Copyright (C) 2006, 2007, 2009 Hewlett-Packard Development Company, L.P.
17 * Paul Moore <paul.moore@hp.com> 17 * Paul Moore <paul@paul-moore.com>
18 * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd. 18 * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
19 * Yuichi Nakamura <ynakam@hitachisoft.jp> 19 * Yuichi Nakamura <ynakam@hitachisoft.jp>
20 * 20 *
@@ -57,7 +57,7 @@
57#include <net/netlabel.h> 57#include <net/netlabel.h>
58#include <linux/uaccess.h> 58#include <linux/uaccess.h>
59#include <asm/ioctls.h> 59#include <asm/ioctls.h>
60#include <asm/atomic.h> 60#include <linux/atomic.h>
61#include <linux/bitops.h> 61#include <linux/bitops.h>
62#include <linux/interrupt.h> 62#include <linux/interrupt.h>
63#include <linux/netdevice.h> /* for network interface checks */ 63#include <linux/netdevice.h> /* for network interface checks */
@@ -2053,7 +2053,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2053 u32 ptsid = 0; 2053 u32 ptsid = 0;
2054 2054
2055 rcu_read_lock(); 2055 rcu_read_lock();
2056 tracer = tracehook_tracer_task(current); 2056 tracer = ptrace_parent(current);
2057 if (likely(tracer != NULL)) { 2057 if (likely(tracer != NULL)) {
2058 sec = __task_cred(tracer)->security; 2058 sec = __task_cred(tracer)->security;
2059 ptsid = sec->sid; 2059 ptsid = sec->sid;
@@ -2659,12 +2659,13 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
2659 return dentry_has_perm(cred, dentry, FILE__READ); 2659 return dentry_has_perm(cred, dentry, FILE__READ);
2660} 2660}
2661 2661
2662static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags) 2662static int selinux_inode_permission(struct inode *inode, int mask)
2663{ 2663{
2664 const struct cred *cred = current_cred(); 2664 const struct cred *cred = current_cred();
2665 struct common_audit_data ad; 2665 struct common_audit_data ad;
2666 u32 perms; 2666 u32 perms;
2667 bool from_access; 2667 bool from_access;
2668 unsigned flags = mask & MAY_NOT_BLOCK;
2668 2669
2669 from_access = mask & MAY_ACCESS; 2670 from_access = mask & MAY_ACCESS;
2670 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND); 2671 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
@@ -5319,7 +5320,7 @@ static int selinux_setprocattr(struct task_struct *p,
5319 Otherwise, leave SID unchanged and fail. */ 5320 Otherwise, leave SID unchanged and fail. */
5320 ptsid = 0; 5321 ptsid = 0;
5321 task_lock(p); 5322 task_lock(p);
5322 tracer = tracehook_tracer_task(p); 5323 tracer = ptrace_parent(p);
5323 if (tracer) 5324 if (tracer)
5324 ptsid = task_sid(tracer); 5325 ptsid = task_sid(tracer);
5325 task_unlock(p); 5326 task_unlock(p);
diff --git a/security/selinux/include/netif.h b/security/selinux/include/netif.h
index ce23edd128b..43d507242b4 100644
--- a/security/selinux/include/netif.h
+++ b/security/selinux/include/netif.h
@@ -8,7 +8,7 @@
8 * 8 *
9 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> 9 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
10 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P. 10 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
11 * Paul Moore, <paul.moore@hp.com> 11 * Paul Moore <paul@paul-moore.com>
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2, 14 * it under the terms of the GNU General Public License version 2,
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h
index cf2f628e6e2..8c59b8f150e 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * SELinux interface to the NetLabel subsystem 2 * SELinux interface to the NetLabel subsystem
3 * 3 *
4 * Author : Paul Moore <paul.moore@hp.com> 4 * Author: Paul Moore <paul@paul-moore.com>
5 * 5 *
6 */ 6 */
7 7
diff --git a/security/selinux/include/netnode.h b/security/selinux/include/netnode.h
index 1b94450d11d..df7a5ed6c69 100644
--- a/security/selinux/include/netnode.h
+++ b/security/selinux/include/netnode.h
@@ -6,7 +6,7 @@
6 * needed to reduce the lookup overhead since most of these queries happen on 6 * needed to reduce the lookup overhead since most of these queries happen on
7 * a per-packet basis. 7 * a per-packet basis.
8 * 8 *
9 * Author: Paul Moore <paul.moore@hp.com> 9 * Author: Paul Moore <paul@paul-moore.com>
10 * 10 *
11 */ 11 */
12 12
diff --git a/security/selinux/include/netport.h b/security/selinux/include/netport.h
index 8991752eaf9..4d965b83d73 100644
--- a/security/selinux/include/netport.h
+++ b/security/selinux/include/netport.h
@@ -5,7 +5,7 @@
5 * mapping is maintained as part of the normal policy but a fast cache is 5 * mapping is maintained as part of the normal policy but a fast cache is
6 * needed to reduce the lookup overhead. 6 * needed to reduce the lookup overhead.
7 * 7 *
8 * Author: Paul Moore <paul.moore@hp.com> 8 * Author: Paul Moore <paul@paul-moore.com>
9 * 9 *
10 */ 10 */
11 11
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index 58cc481c93d..326f22cbe40 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -8,7 +8,7 @@
8 * 8 *
9 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> 9 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
10 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P. 10 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
11 * Paul Moore <paul.moore@hp.com> 11 * Paul Moore <paul@paul-moore.com>
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2, 14 * it under the terms of the GNU General Public License version 2,
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index c3bf3ed07b0..da4b8b23328 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -4,7 +4,7 @@
4 * This file provides the necessary glue to tie NetLabel into the SELinux 4 * This file provides the necessary glue to tie NetLabel into the SELinux
5 * subsystem. 5 * subsystem.
6 * 6 *
7 * Author: Paul Moore <paul.moore@hp.com> 7 * Author: Paul Moore <paul@paul-moore.com>
8 * 8 *
9 */ 9 */
10 10
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 3618251d0fd..3bf46abaa68 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -6,7 +6,7 @@
6 * needed to reduce the lookup overhead since most of these queries happen on 6 * needed to reduce the lookup overhead since most of these queries happen on
7 * a per-packet basis. 7 * a per-packet basis.
8 * 8 *
9 * Author: Paul Moore <paul.moore@hp.com> 9 * Author: Paul Moore <paul@paul-moore.com>
10 * 10 *
11 * This code is heavily based on the "netif" concept originally developed by 11 * This code is heavily based on the "netif" concept originally developed by
12 * James Morris <jmorris@redhat.com> 12 * James Morris <jmorris@redhat.com>
@@ -69,22 +69,6 @@ static DEFINE_SPINLOCK(sel_netnode_lock);
69static struct sel_netnode_bkt sel_netnode_hash[SEL_NETNODE_HASH_SIZE]; 69static struct sel_netnode_bkt sel_netnode_hash[SEL_NETNODE_HASH_SIZE];
70 70
71/** 71/**
72 * sel_netnode_free - Frees a node entry
73 * @p: the entry's RCU field
74 *
75 * Description:
76 * This function is designed to be used as a callback to the call_rcu()
77 * function so that memory allocated to a hash table node entry can be
78 * released safely.
79 *
80 */
81static void sel_netnode_free(struct rcu_head *p)
82{
83 struct sel_netnode *node = container_of(p, struct sel_netnode, rcu);
84 kfree(node);
85}
86
87/**
88 * sel_netnode_hashfn_ipv4 - IPv4 hashing function for the node table 72 * sel_netnode_hashfn_ipv4 - IPv4 hashing function for the node table
89 * @addr: IPv4 address 73 * @addr: IPv4 address
90 * 74 *
@@ -193,7 +177,7 @@ static void sel_netnode_insert(struct sel_netnode *node)
193 rcu_dereference(sel_netnode_hash[idx].list.prev), 177 rcu_dereference(sel_netnode_hash[idx].list.prev),
194 struct sel_netnode, list); 178 struct sel_netnode, list);
195 list_del_rcu(&tail->list); 179 list_del_rcu(&tail->list);
196 call_rcu(&tail->rcu, sel_netnode_free); 180 kfree_rcu(tail, rcu);
197 } else 181 } else
198 sel_netnode_hash[idx].size++; 182 sel_netnode_hash[idx].size++;
199} 183}
@@ -306,7 +290,7 @@ static void sel_netnode_flush(void)
306 list_for_each_entry_safe(node, node_tmp, 290 list_for_each_entry_safe(node, node_tmp,
307 &sel_netnode_hash[idx].list, list) { 291 &sel_netnode_hash[idx].list, list) {
308 list_del_rcu(&node->list); 292 list_del_rcu(&node->list);
309 call_rcu(&node->rcu, sel_netnode_free); 293 kfree_rcu(node, rcu);
310 } 294 }
311 sel_netnode_hash[idx].size = 0; 295 sel_netnode_hash[idx].size = 0;
312 } 296 }
diff --git a/security/selinux/netport.c b/security/selinux/netport.c
index cfe2d72d3fb..7b9eb1faf68 100644
--- a/security/selinux/netport.c
+++ b/security/selinux/netport.c
@@ -5,7 +5,7 @@
5 * mapping is maintained as part of the normal policy but a fast cache is 5 * mapping is maintained as part of the normal policy but a fast cache is
6 * needed to reduce the lookup overhead. 6 * needed to reduce the lookup overhead.
7 * 7 *
8 * Author: Paul Moore <paul.moore@hp.com> 8 * Author: Paul Moore <paul@paul-moore.com>
9 * 9 *
10 * This code is heavily based on the "netif" concept originally developed by 10 * This code is heavily based on the "netif" concept originally developed by
11 * James Morris <jmorris@redhat.com> 11 * James Morris <jmorris@redhat.com>
@@ -68,22 +68,6 @@ static DEFINE_SPINLOCK(sel_netport_lock);
68static struct sel_netport_bkt sel_netport_hash[SEL_NETPORT_HASH_SIZE]; 68static struct sel_netport_bkt sel_netport_hash[SEL_NETPORT_HASH_SIZE];
69 69
70/** 70/**
71 * sel_netport_free - Frees a port entry
72 * @p: the entry's RCU field
73 *
74 * Description:
75 * This function is designed to be used as a callback to the call_rcu()
76 * function so that memory allocated to a hash table port entry can be
77 * released safely.
78 *
79 */
80static void sel_netport_free(struct rcu_head *p)
81{
82 struct sel_netport *port = container_of(p, struct sel_netport, rcu);
83 kfree(port);
84}
85
86/**
87 * sel_netport_hashfn - Hashing function for the port table 71 * sel_netport_hashfn - Hashing function for the port table
88 * @pnum: port number 72 * @pnum: port number
89 * 73 *
@@ -139,10 +123,12 @@ static void sel_netport_insert(struct sel_netport *port)
139 if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) { 123 if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) {
140 struct sel_netport *tail; 124 struct sel_netport *tail;
141 tail = list_entry( 125 tail = list_entry(
142 rcu_dereference(sel_netport_hash[idx].list.prev), 126 rcu_dereference_protected(
127 sel_netport_hash[idx].list.prev,
128 lockdep_is_held(&sel_netport_lock)),
143 struct sel_netport, list); 129 struct sel_netport, list);
144 list_del_rcu(&tail->list); 130 list_del_rcu(&tail->list);
145 call_rcu(&tail->rcu, sel_netport_free); 131 kfree_rcu(tail, rcu);
146 } else 132 } else
147 sel_netport_hash[idx].size++; 133 sel_netport_hash[idx].size++;
148} 134}
@@ -241,7 +227,7 @@ static void sel_netport_flush(void)
241 list_for_each_entry_safe(port, port_tmp, 227 list_for_each_entry_safe(port, port_tmp,
242 &sel_netport_hash[idx].list, list) { 228 &sel_netport_hash[idx].list, list) {
243 list_del_rcu(&port->list); 229 list_del_rcu(&port->list);
244 call_rcu(&port->rcu, sel_netport_free); 230 kfree_rcu(port, rcu);
245 } 231 }
246 sel_netport_hash[idx].size = 0; 232 sel_netport_hash[idx].size = 0;
247 } 233 }
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 35459340019..55d92cbb177 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * Added conditional policy language extensions 3 * Added conditional policy language extensions
4 * 4 *
5 * Updated: Hewlett-Packard <paul.moore@hp.com> 5 * Updated: Hewlett-Packard <paul@paul-moore.com>
6 * 6 *
7 * Added support for the policy capability bitmap 7 * Added support for the policy capability bitmap
8 * 8 *
@@ -1984,6 +1984,7 @@ __initcall(init_sel_fs);
1984void exit_sel_fs(void) 1984void exit_sel_fs(void)
1985{ 1985{
1986 kobject_put(selinuxfs_kobj); 1986 kobject_put(selinuxfs_kobj);
1987 kern_unmount(selinuxfs_mount);
1987 unregister_filesystem(&sel_fs_type); 1988 unregister_filesystem(&sel_fs_type);
1988} 1989}
1989#endif 1990#endif
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index d42951fcbe8..30f119b1d1e 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -4,7 +4,7 @@
4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
5 */ 5 */
6/* 6/*
7 * Updated: Hewlett-Packard <paul.moore@hp.com> 7 * Updated: Hewlett-Packard <paul@paul-moore.com>
8 * 8 *
9 * Added support to import/export the NetLabel category bitmap 9 * Added support to import/export the NetLabel category bitmap
10 * 10 *
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index e96174216bc..fbf9c5816c7 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -11,7 +11,7 @@
11 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. 11 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
12 */ 12 */
13/* 13/*
14 * Updated: Hewlett-Packard <paul.moore@hp.com> 14 * Updated: Hewlett-Packard <paul@paul-moore.com>
15 * 15 *
16 * Added support to import/export the MLS label from NetLabel 16 * Added support to import/export the MLS label from NetLabel
17 * 17 *
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index 037bf9d82d4..e4369e3e636 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -11,7 +11,7 @@
11 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. 11 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
12 */ 12 */
13/* 13/*
14 * Updated: Hewlett-Packard <paul.moore@hp.com> 14 * Updated: Hewlett-Packard <paul@paul-moore.com>
15 * 15 *
16 * Added support to import/export the MLS label from NetLabel 16 * Added support to import/export the MLS label from NetLabel
17 * 17 *
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index d246aca3f4f..2381d0ded22 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -13,7 +13,7 @@
13 * 13 *
14 * Added conditional policy language extensions 14 * Added conditional policy language extensions
15 * 15 *
16 * Updated: Hewlett-Packard <paul.moore@hp.com> 16 * Updated: Hewlett-Packard <paul@paul-moore.com>
17 * 17 *
18 * Added support for the policy capability bitmap 18 * Added support for the policy capability bitmap
19 * 19 *
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 973e00e34fa..f6917bc0aa0 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -13,7 +13,7 @@
13 * 13 *
14 * Added conditional policy language extensions 14 * Added conditional policy language extensions
15 * 15 *
16 * Updated: Hewlett-Packard <paul.moore@hp.com> 16 * Updated: Hewlett-Packard <paul@paul-moore.com>
17 * 17 *
18 * Added support for NetLabel 18 * Added support for NetLabel
19 * Added support for the policy capability bitmap 19 * Added support for the policy capability bitmap
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 68178b76a2b..48665ecd119 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -46,7 +46,7 @@
46#include <net/xfrm.h> 46#include <net/xfrm.h>
47#include <net/checksum.h> 47#include <net/checksum.h>
48#include <net/udp.h> 48#include <net/udp.h>
49#include <asm/atomic.h> 49#include <linux/atomic.h>
50 50
51#include "avc.h" 51#include "avc.h"
52#include "objsec.h" 52#include "objsec.h"
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 9831a39c11f..b9c5e149903 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> 10 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
11 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. 11 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
12 * Paul Moore <paul.moore@hp.com> 12 * Paul Moore <paul@paul-moore.com>
13 * Copyright (C) 2010 Nokia Corporation 13 * Copyright (C) 2010 Nokia Corporation
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
@@ -689,9 +689,10 @@ static int smack_inode_rename(struct inode *old_inode,
689 * 689 *
690 * Returns 0 if access is permitted, -EACCES otherwise 690 * Returns 0 if access is permitted, -EACCES otherwise
691 */ 691 */
692static int smack_inode_permission(struct inode *inode, int mask, unsigned flags) 692static int smack_inode_permission(struct inode *inode, int mask)
693{ 693{
694 struct smk_audit_info ad; 694 struct smk_audit_info ad;
695 int no_block = mask & MAY_NOT_BLOCK;
695 696
696 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND); 697 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
697 /* 698 /*
@@ -701,7 +702,7 @@ static int smack_inode_permission(struct inode *inode, int mask, unsigned flags)
701 return 0; 702 return 0;
702 703
703 /* May be droppable after audit */ 704 /* May be droppable after audit */
704 if (flags & IPERM_FLAG_RCU) 705 if (no_block)
705 return -ECHILD; 706 return -ECHILD;
706 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE); 707 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
707 smk_ad_setfield_u_fs_inode(&ad, inode); 708 smk_ad_setfield_u_fs_inode(&ad, inode);
diff --git a/security/tf_driver/Kconfig b/security/tf_driver/Kconfig
new file mode 100644
index 00000000000..2a980c5ade4
--- /dev/null
+++ b/security/tf_driver/Kconfig
@@ -0,0 +1,8 @@
1config TRUSTED_FOUNDATIONS
2 bool "Enable TF Driver"
3 default n
4 select CRYPTO_SHA1
5 help
6 This option adds kernel support for communication with the Trusted Foundations.
7 If you are unsure how to answer this question, answer N.
8
diff --git a/security/tf_driver/Makefile b/security/tf_driver/Makefile
new file mode 100644
index 00000000000..dfadb7d9740
--- /dev/null
+++ b/security/tf_driver/Makefile
@@ -0,0 +1,36 @@
1#
2# Copyright (c) 2006-2010 Trusted Logic S.A.
3# All Rights Reserved.
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License as
7# published by the Free Software Foundation; either version 2 of
8# the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18# MA 02111-1307 USA
19#
20
21# debug options
22#EXTRA_CFLAGS += -O0 -DDEBUG -D_DEBUG -DCONFIG_TF_DRIVER_DEBUG_SUPPORT
23EXTRA_CFLAGS += -DNDEBUG
24EXTRA_CFLAGS += -DLINUX -DCONFIG_TF_TRUSTZONE -DCONFIG_TFN
25
26ifdef S_VERSION_BUILD
27EXTRA_CFLAGS += -DS_VERSION_BUILD=$(S_VERSION_BUILD)
28endif
29
30tf_driver-objs += tf_util.o
31tf_driver-objs += tf_conn.o
32tf_driver-objs += tf_device.o
33tf_driver-objs += tf_comm.o
34tf_driver-objs += tf_comm_tz.o
35
36obj-$(CONFIG_TRUSTED_FOUNDATIONS) += tf_driver.o
diff --git a/security/tf_driver/s_version.h b/security/tf_driver/s_version.h
new file mode 100644
index 00000000000..6244d3fe7e8
--- /dev/null
+++ b/security/tf_driver/s_version.h
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 2011 Trusted Logic S.A.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#ifndef __S_VERSION_H__
21#define __S_VERSION_H__
22
23/*
24 * Usage: define S_VERSION_BUILD on the compiler's command line.
25 *
26 * Then set:
27 * - S_VERSION_OS
28 * - S_VERSION_PLATFORM
29 * - S_VERSION_MAIN
30 * - S_VERSION_ENG is optional
31 * - S_VERSION_PATCH is optional
32 * - S_VERSION_BUILD = 0 if S_VERSION_BUILD not defined or empty
33 */
34
35#define S_VERSION_OS "A" /* "A" for all Android */
36#define S_VERSION_PLATFORM "B" /* "B" for Tegra3 */
37
38/*
39 * This version number must be updated for each new release
40 */
41#define S_VERSION_MAIN "01.03"
42
43/*
44* If this is a patch or engineering version use the following
45* defines to set the version number. Else set these values to 0.
46*/
47#define S_VERSION_ENG 0
48#define S_VERSION_PATCH 0
49
50#ifdef S_VERSION_BUILD
51/* TRICK: detect if S_VERSION is defined but empty */
52#if 0 == S_VERSION_BUILD-0
53#undef S_VERSION_BUILD
54#define S_VERSION_BUILD 0
55#endif
56#else
57/* S_VERSION_BUILD is not defined */
58#define S_VERSION_BUILD 0
59#endif
60
61#define __STRINGIFY(X) #X
62#define __STRINGIFY2(X) __STRINGIFY(X)
63
64#if S_VERSION_ENG != 0
65#define _S_VERSION_ENG "e" __STRINGIFY2(S_VERSION_ENG)
66#else
67#define _S_VERSION_ENG ""
68#endif
69
70#if S_VERSION_PATCH != 0
71#define _S_VERSION_PATCH "p" __STRINGIFY2(S_VERSION_PATCH)
72#else
73#define _S_VERSION_PATCH ""
74#endif
75
76#if !defined(NDEBUG) || defined(_DEBUG)
77#define S_VERSION_VARIANT "D "
78#else
79#define S_VERSION_VARIANT " "
80#endif
81
82#define S_VERSION_STRING \
83 "TFN" \
84 S_VERSION_OS \
85 S_VERSION_PLATFORM \
86 S_VERSION_MAIN \
87 _S_VERSION_ENG \
88 _S_VERSION_PATCH \
89 "." __STRINGIFY2(S_VERSION_BUILD) " " \
90 S_VERSION_VARIANT
91
92#endif /* __S_VERSION_H__ */
diff --git a/security/tf_driver/tf_comm.c b/security/tf_driver/tf_comm.c
new file mode 100644
index 00000000000..16915beb406
--- /dev/null
+++ b/security/tf_driver/tf_comm.c
@@ -0,0 +1,1745 @@
1/**
2 * Copyright (c) 2011 Trusted Logic S.A.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#include <asm/div64.h>
21#include <asm/system.h>
22#include <linux/version.h>
23#include <asm/cputype.h>
24#include <linux/interrupt.h>
25#include <linux/page-flags.h>
26#include <linux/pagemap.h>
27#include <linux/vmalloc.h>
28#include <linux/jiffies.h>
29#include <linux/freezer.h>
30
31#include "tf_defs.h"
32#include "tf_comm.h"
33#include "tf_protocol.h"
34#include "tf_util.h"
35#include "tf_conn.h"
36
37#ifdef CONFIG_TF_ZEBRA
38#include "tf_zebra.h"
39#endif
40
41/*---------------------------------------------------------------------------
42 * Internal Constants
43 *---------------------------------------------------------------------------*/
44
45/*
46 * shared memories descriptor constants
47 */
48#define DESCRIPTOR_B_MASK (1 << 2)
49#define DESCRIPTOR_C_MASK (1 << 3)
50#define DESCRIPTOR_S_MASK (1 << 10)
51
52#define L1_COARSE_DESCRIPTOR_BASE (0x00000001)
53#define L1_COARSE_DESCRIPTOR_ADDR_MASK (0xFFFFFC00)
54#define L1_COARSE_DESCRIPTOR_V13_12_SHIFT (5)
55
56#define L2_PAGE_DESCRIPTOR_BASE (0x00000003)
57#define L2_PAGE_DESCRIPTOR_AP_APX_READ (0x220)
58#define L2_PAGE_DESCRIPTOR_AP_APX_READ_WRITE (0x30)
59
60#define L2_INIT_DESCRIPTOR_BASE (0x00000003)
61#define L2_INIT_DESCRIPTOR_V13_12_SHIFT (4)
62
63/*
64 * Reject an attempt to share a strongly-Ordered or Device memory
65 * Strongly-Ordered: TEX=0b000, C=0, B=0
66 * Shared Device: TEX=0b000, C=0, B=1
67 * Non-Shared Device: TEX=0b010, C=0, B=0
68 */
69#define L2_TEX_C_B_MASK \
70 ((1<<8) | (1<<7) | (1<<6) | (1<<3) | (1<<2))
71#define L2_TEX_C_B_STRONGLY_ORDERED \
72 ((0<<8) | (0<<7) | (0<<6) | (0<<3) | (0<<2))
73#define L2_TEX_C_B_SHARED_DEVICE \
74 ((0<<8) | (0<<7) | (0<<6) | (0<<3) | (1<<2))
75#define L2_TEX_C_B_NON_SHARED_DEVICE \
76 ((0<<8) | (1<<7) | (0<<6) | (0<<3) | (0<<2))
77
78#define CACHE_S(x) ((x) & (1 << 24))
79#define CACHE_DSIZE(x) (((x) >> 12) & 4095)
80
81#define TIME_IMMEDIATE ((u64) 0x0000000000000000ULL)
82#define TIME_INFINITE ((u64) 0xFFFFFFFFFFFFFFFFULL)
83
84/*---------------------------------------------------------------------------
85 * atomic operation definitions
86 *---------------------------------------------------------------------------*/
87
88/*
89 * Atomically updates the sync_serial_n and time_n register
90 * sync_serial_n and time_n modifications are thread safe
91 */
92void tf_set_current_time(struct tf_comm *comm)
93{
94 u32 new_sync_serial;
95 struct timeval now;
96 u64 time64;
97
98 /*
99 * lock the structure while updating the L1 shared memory fields
100 */
101 spin_lock(&comm->lock);
102
103 /* read sync_serial_n and change the TimeSlot bit field */
104 new_sync_serial =
105 tf_read_reg32(&comm->l1_buffer->sync_serial_n) + 1;
106
107 do_gettimeofday(&now);
108 time64 = now.tv_sec;
109 time64 = (time64 * 1000) + (now.tv_usec / 1000);
110
111 /* Write the new time64 and nSyncSerial into shared memory */
112 tf_write_reg64(&comm->l1_buffer->time_n[new_sync_serial &
113 TF_SYNC_SERIAL_TIMESLOT_N], time64);
114 tf_write_reg32(&comm->l1_buffer->sync_serial_n,
115 new_sync_serial);
116
117 spin_unlock(&comm->lock);
118}
119
120/*
121 * Performs the specific read timeout operation
122 * The difficulty here is to read atomically 2 u32
123 * values from the L1 shared buffer.
124 * This is guaranteed by reading before and after the operation
125 * the timeslot given by the Secure World
126 */
127static inline void tf_read_timeout(struct tf_comm *comm, u64 *time)
128{
129 u32 sync_serial_s_initial = 0;
130 u32 sync_serial_s_final = 1;
131 u64 time64;
132
133 spin_lock(&comm->lock);
134
135 while (sync_serial_s_initial != sync_serial_s_final) {
136 sync_serial_s_initial = tf_read_reg32(
137 &comm->l1_buffer->sync_serial_s);
138 time64 = tf_read_reg64(
139 &comm->l1_buffer->timeout_s[sync_serial_s_initial&1]);
140
141 sync_serial_s_final = tf_read_reg32(
142 &comm->l1_buffer->sync_serial_s);
143 }
144
145 spin_unlock(&comm->lock);
146
147 *time = time64;
148}
149
150/*----------------------------------------------------------------------------
151 * SIGKILL signal handling
152 *----------------------------------------------------------------------------*/
153
154static bool sigkill_pending(void)
155{
156 if (signal_pending(current)) {
157 dprintk(KERN_INFO "A signal is pending\n");
158 if (sigismember(&current->pending.signal, SIGKILL)) {
159 dprintk(KERN_INFO "A SIGKILL is pending\n");
160 return true;
161 } else if (sigismember(
162 &current->signal->shared_pending.signal, SIGKILL)) {
163 dprintk(KERN_INFO "A SIGKILL is pending (shared)\n");
164 return true;
165 }
166 }
167 return false;
168}
169
170/*----------------------------------------------------------------------------
171 * Shared memory related operations
172 *----------------------------------------------------------------------------*/
173
174struct tf_coarse_page_table *tf_alloc_coarse_page_table(
175 struct tf_coarse_page_table_allocation_context *alloc_context,
176 u32 type)
177{
178 struct tf_coarse_page_table *coarse_pg_table = NULL;
179
180 spin_lock(&(alloc_context->lock));
181
182 if (!(list_empty(&(alloc_context->free_coarse_page_tables)))) {
183 /*
184 * The free list can provide us a coarse page table
185 * descriptor
186 */
187 coarse_pg_table = list_first_entry(
188 &alloc_context->free_coarse_page_tables,
189 struct tf_coarse_page_table, list);
190 list_del(&(coarse_pg_table->list));
191
192 coarse_pg_table->parent->ref_count++;
193 } else {
194 /* no array of coarse page tables, create a new one */
195 struct tf_coarse_page_table_array *array;
196 void *page;
197 int i;
198
199 spin_unlock(&(alloc_context->lock));
200
201 /* first allocate a new page descriptor */
202 array = internal_kmalloc(sizeof(*array), GFP_KERNEL);
203 if (array == NULL) {
204 dprintk(KERN_ERR "tf_alloc_coarse_page_table(%p):"
205 " failed to allocate a table array\n",
206 alloc_context);
207 return NULL;
208 }
209
210 array->type = type;
211 INIT_LIST_HEAD(&(array->list));
212
213 /* now allocate the actual page the page descriptor describes */
214 page = (void *) internal_get_zeroed_page(GFP_KERNEL);
215 if (page == NULL) {
216 dprintk(KERN_ERR "tf_alloc_coarse_page_table(%p):"
217 " failed allocate a page\n",
218 alloc_context);
219 internal_kfree(array);
220 return NULL;
221 }
222
223 spin_lock(&(alloc_context->lock));
224
225 /* initialize the coarse page table descriptors */
226 for (i = 0; i < 4; i++) {
227 INIT_LIST_HEAD(&(array->coarse_page_tables[i].list));
228 array->coarse_page_tables[i].descriptors =
229 page + (i * SIZE_1KB);
230 array->coarse_page_tables[i].parent = array;
231
232 if (i == 0) {
233 /*
234 * the first element is kept for the current
235 * coarse page table allocation
236 */
237 coarse_pg_table =
238 &(array->coarse_page_tables[i]);
239 array->ref_count = 1;
240 } else {
241 /*
242 * The other elements are added to the free list
243 */
244 list_add(&(array->coarse_page_tables[i].list),
245 &(alloc_context->
246 free_coarse_page_tables));
247 }
248 }
249
250 list_add(&(array->list),
251 &(alloc_context->coarse_page_table_arrays));
252 }
253 spin_unlock(&(alloc_context->lock));
254
255 return coarse_pg_table;
256}
257
258
259void tf_free_coarse_page_table(
260 struct tf_coarse_page_table_allocation_context *alloc_context,
261 struct tf_coarse_page_table *coarse_pg_table,
262 int force)
263{
264 struct tf_coarse_page_table_array *array;
265
266 spin_lock(&(alloc_context->lock));
267
268 array = coarse_pg_table->parent;
269
270 (array->ref_count)--;
271
272 if (array->ref_count == 0) {
273 /*
274 * no coarse page table descriptor is used
275 * check if we should free the whole page
276 */
277
278 if ((array->type == TF_PAGE_DESCRIPTOR_TYPE_PREALLOCATED)
279 && (force == 0))
280 /*
281 * This is a preallocated page,
282 * add the page back to the free list
283 */
284 list_add(&(coarse_pg_table->list),
285 &(alloc_context->free_coarse_page_tables));
286 else {
287 /*
288 * None of the page's coarse page table descriptors
289 * are in use, free the whole page
290 */
291 int i;
292 u32 *descriptors;
293
294 /*
295 * remove the page's associated coarse page table
296 * descriptors from the free list
297 */
298 for (i = 0; i < 4; i++)
299 if (&(array->coarse_page_tables[i]) !=
300 coarse_pg_table)
301 list_del(&(array->
302 coarse_page_tables[i].list));
303
304 descriptors =
305 array->coarse_page_tables[0].descriptors;
306 array->coarse_page_tables[0].descriptors = NULL;
307
308 /* remove the coarse page table from the array */
309 list_del(&(array->list));
310
311 spin_unlock(&(alloc_context->lock));
312 /*
313 * Free the page.
314 * The address of the page is contained in the first
315 * element
316 */
317 internal_free_page((unsigned long) descriptors);
318 /* finaly free the array */
319 internal_kfree(array);
320
321 spin_lock(&(alloc_context->lock));
322 }
323 } else {
324 /*
325 * Some coarse page table descriptors are in use.
326 * Add the descriptor to the free list
327 */
328 list_add(&(coarse_pg_table->list),
329 &(alloc_context->free_coarse_page_tables));
330 }
331
332 spin_unlock(&(alloc_context->lock));
333}
334
335
336void tf_init_coarse_page_table_allocator(
337 struct tf_coarse_page_table_allocation_context *alloc_context)
338{
339 spin_lock_init(&(alloc_context->lock));
340 INIT_LIST_HEAD(&(alloc_context->coarse_page_table_arrays));
341 INIT_LIST_HEAD(&(alloc_context->free_coarse_page_tables));
342}
343
344void tf_release_coarse_page_table_allocator(
345 struct tf_coarse_page_table_allocation_context *alloc_context)
346{
347 spin_lock(&(alloc_context->lock));
348
349 /* now clean up the list of page descriptors */
350 while (!list_empty(&(alloc_context->coarse_page_table_arrays))) {
351 struct tf_coarse_page_table_array *page_desc;
352 u32 *descriptors;
353
354 page_desc = list_first_entry(
355 &alloc_context->coarse_page_table_arrays,
356 struct tf_coarse_page_table_array, list);
357
358 descriptors = page_desc->coarse_page_tables[0].descriptors;
359 list_del(&(page_desc->list));
360
361 spin_unlock(&(alloc_context->lock));
362
363 if (descriptors != NULL)
364 internal_free_page((unsigned long)descriptors);
365
366 internal_kfree(page_desc);
367
368 spin_lock(&(alloc_context->lock));
369 }
370
371 spin_unlock(&(alloc_context->lock));
372}
373
374/*
375 * Returns the L1 coarse page descriptor for
376 * a coarse page table located at address coarse_pg_table_descriptors
377 */
378u32 tf_get_l1_coarse_descriptor(
379 u32 coarse_pg_table_descriptors[256])
380{
381 u32 descriptor = L1_COARSE_DESCRIPTOR_BASE;
382 unsigned int info = read_cpuid(CPUID_CACHETYPE);
383
384 descriptor |= (virt_to_phys((void *) coarse_pg_table_descriptors)
385 & L1_COARSE_DESCRIPTOR_ADDR_MASK);
386
387 if (CACHE_S(info) && (CACHE_DSIZE(info) & (1 << 11))) {
388 dprintk(KERN_DEBUG "tf_get_l1_coarse_descriptor "
389 "V31-12 added to descriptor\n");
390 /* the 16k alignment restriction applies */
391 descriptor |= (DESCRIPTOR_V13_12_GET(
392 (u32)coarse_pg_table_descriptors) <<
393 L1_COARSE_DESCRIPTOR_V13_12_SHIFT);
394 }
395
396 return descriptor;
397}
398
399
400#define dprintk_desc(...)
401/*
402 * Returns the L2 descriptor for the specified user page.
403 */
404u32 tf_get_l2_descriptor_common(u32 vaddr, struct mm_struct *mm)
405{
406 pgd_t *pgd;
407 pud_t *pud;
408 pmd_t *pmd;
409 pte_t *ptep;
410 u32 *hwpte;
411 u32 tex = 0;
412 u32 descriptor = 0;
413
414 dprintk_desc(KERN_INFO "VirtAddr = %x\n", vaddr);
415 pgd = pgd_offset(mm, vaddr);
416 dprintk_desc(KERN_INFO "pgd = %x, value=%x\n", (unsigned int) pgd,
417 (unsigned int) *pgd);
418 if (pgd_none(*pgd))
419 goto error;
420 pud = pud_offset(pgd, vaddr);
421 dprintk_desc(KERN_INFO "pud = %x, value=%x\n", (unsigned int) pud,
422 (unsigned int) *pud);
423 if (pud_none(*pud))
424 goto error;
425 pmd = pmd_offset(pud, vaddr);
426 dprintk_desc(KERN_INFO "pmd = %x, value=%x\n", (unsigned int) pmd,
427 (unsigned int) *pmd);
428 if (pmd_none(*pmd))
429 goto error;
430
431 if (PMD_TYPE_SECT&(*pmd)) {
432 /* We have a section */
433 dprintk_desc(KERN_INFO "Section descr=%x\n",
434 (unsigned int)*pmd);
435 if ((*pmd) & PMD_SECT_BUFFERABLE)
436 descriptor |= DESCRIPTOR_B_MASK;
437 if ((*pmd) & PMD_SECT_CACHEABLE)
438 descriptor |= DESCRIPTOR_C_MASK;
439 if ((*pmd) & PMD_SECT_S)
440 descriptor |= DESCRIPTOR_S_MASK;
441 tex = ((*pmd) >> 12) & 7;
442 } else {
443 /* We have a table */
444 ptep = pte_offset_map(pmd, vaddr);
445 if (pte_present(*ptep)) {
446 dprintk_desc(KERN_INFO "L2 descr=%x\n",
447 (unsigned int) *ptep);
448 if ((*ptep) & L_PTE_MT_BUFFERABLE)
449 descriptor |= DESCRIPTOR_B_MASK;
450 if ((*ptep) & L_PTE_MT_WRITETHROUGH)
451 descriptor |= DESCRIPTOR_C_MASK;
452 if ((*ptep) & L_PTE_MT_DEV_SHARED)
453 descriptor |= DESCRIPTOR_S_MASK;
454
455 /*
456 * Linux's pte doesn't keep track of TEX value.
457 * Have to jump to hwpte see include/asm/pgtable.h
458 * (-2k before 2.6.38, then +2k)
459 */
460#ifdef PTE_HWTABLE_SIZE
461 hwpte = (u32 *) (ptep+PTE_HWTABLE_PTRS);
462#else
463 hwpte = (u32 *) (ptep-PTRS_PER_PTE);
464#endif
465 if (((*hwpte) & L2_DESCRIPTOR_ADDR_MASK) !=
466 ((*ptep) & L2_DESCRIPTOR_ADDR_MASK))
467 goto error;
468 dprintk_desc(KERN_INFO "hw descr=%x\n", *hwpte);
469 tex = ((*hwpte) >> 6) & 7;
470 pte_unmap(ptep);
471 } else {
472 pte_unmap(ptep);
473 goto error;
474 }
475 }
476
477 descriptor |= (tex << 6);
478
479 return descriptor;
480
481error:
482 dprintk(KERN_ERR "Error occured in %s\n", __func__);
483 return 0;
484}
485
486
487/*
488 * Changes an L2 page descriptor back to a pointer to a physical page
489 */
490inline struct page *tf_l2_page_descriptor_to_page(u32 l2_page_descriptor)
491{
492 return pte_page(l2_page_descriptor & L2_DESCRIPTOR_ADDR_MASK);
493}
494
495
496/*
497 * Returns the L1 descriptor for the 1KB-aligned coarse page table. The address
498 * must be in the kernel address space.
499 */
500static void tf_get_l2_page_descriptor(
501 u32 *l2_page_descriptor,
502 u32 flags, struct mm_struct *mm)
503{
504 unsigned long page_vaddr;
505 u32 descriptor;
506 struct page *page;
507 bool unmap_page = false;
508
509#if 0
510 dprintk(KERN_INFO
511 "tf_get_l2_page_descriptor():"
512 "*l2_page_descriptor=%x\n",
513 *l2_page_descriptor);
514#endif
515
516 if (*l2_page_descriptor == L2_DESCRIPTOR_FAULT)
517 return;
518
519 page = (struct page *) (*l2_page_descriptor);
520
521 page_vaddr = (unsigned long) page_address(page);
522 if (page_vaddr == 0) {
523 dprintk(KERN_INFO "page_address returned 0\n");
524 /* Should we use kmap_atomic(page, KM_USER0) instead ? */
525 page_vaddr = (unsigned long) kmap(page);
526 if (page_vaddr == 0) {
527 *l2_page_descriptor = L2_DESCRIPTOR_FAULT;
528 dprintk(KERN_ERR "kmap returned 0\n");
529 return;
530 }
531 unmap_page = true;
532 }
533
534 descriptor = tf_get_l2_descriptor_common(page_vaddr, mm);
535 if (descriptor == 0) {
536 *l2_page_descriptor = L2_DESCRIPTOR_FAULT;
537 return;
538 }
539 descriptor |= L2_PAGE_DESCRIPTOR_BASE;
540
541 descriptor |= (page_to_phys(page) & L2_DESCRIPTOR_ADDR_MASK);
542
543 if (!(flags & TF_SHMEM_TYPE_WRITE))
544 /* only read access */
545 descriptor |= L2_PAGE_DESCRIPTOR_AP_APX_READ;
546 else
547 /* read and write access */
548 descriptor |= L2_PAGE_DESCRIPTOR_AP_APX_READ_WRITE;
549
550 if (unmap_page)
551 kunmap(page);
552
553 *l2_page_descriptor = descriptor;
554}
555
556
557/*
558 * Unlocks the physical memory pages
559 * and frees the coarse pages that need to
560 */
561void tf_cleanup_shared_memory(
562 struct tf_coarse_page_table_allocation_context *alloc_context,
563 struct tf_shmem_desc *shmem_desc,
564 u32 full_cleanup)
565{
566 u32 coarse_page_index;
567
568 dprintk(KERN_INFO "tf_cleanup_shared_memory(%p)\n",
569 shmem_desc);
570
571#ifdef DEBUG_COARSE_TABLES
572 printk(KERN_DEBUG "tf_cleanup_shared_memory "
573 "- number of coarse page tables=%d\n",
574 shmem_desc->coarse_pg_table_count);
575
576 for (coarse_page_index = 0;
577 coarse_page_index < shmem_desc->coarse_pg_table_count;
578 coarse_page_index++) {
579 u32 j;
580
581 printk(KERN_DEBUG " Descriptor=%p address=%p index=%d\n",
582 shmem_desc->coarse_pg_table[coarse_page_index],
583 shmem_desc->coarse_pg_table[coarse_page_index]->
584 descriptors,
585 coarse_page_index);
586 if (shmem_desc->coarse_pg_table[coarse_page_index] != NULL) {
587 for (j = 0;
588 j < TF_DESCRIPTOR_TABLE_CAPACITY;
589 j += 8) {
590 int k;
591 printk(KERN_DEBUG " ");
592 for (k = j; k < j + 8; k++)
593 printk(KERN_DEBUG "%p ",
594 shmem_desc->coarse_pg_table[
595 coarse_page_index]->
596 descriptors);
597 printk(KERN_DEBUG "\n");
598 }
599 }
600 }
601 printk(KERN_DEBUG "tf_cleanup_shared_memory() - done\n\n");
602#endif
603
604 /* Parse the coarse page descriptors */
605 for (coarse_page_index = 0;
606 coarse_page_index < shmem_desc->coarse_pg_table_count;
607 coarse_page_index++) {
608 u32 j;
609 u32 found = 0;
610
611 /* parse the page descriptors of the coarse page */
612 for (j = 0; j < TF_DESCRIPTOR_TABLE_CAPACITY; j++) {
613 u32 l2_page_descriptor = (u32) (shmem_desc->
614 coarse_pg_table[coarse_page_index]->
615 descriptors[j]);
616
617 if (l2_page_descriptor != L2_DESCRIPTOR_FAULT) {
618 struct page *page =
619 tf_l2_page_descriptor_to_page(
620 l2_page_descriptor);
621
622 if (!PageReserved(page))
623 SetPageDirty(page);
624 internal_page_cache_release(page);
625
626 found = 1;
627 } else if (found == 1) {
628 break;
629 }
630 }
631
632 /*
633 * Only free the coarse pages of descriptors not preallocated
634 */
635 if ((shmem_desc->type == TF_SHMEM_TYPE_REGISTERED_SHMEM) ||
636 (full_cleanup != 0))
637 tf_free_coarse_page_table(alloc_context,
638 shmem_desc->coarse_pg_table[coarse_page_index],
639 0);
640 }
641
642 shmem_desc->coarse_pg_table_count = 0;
643 dprintk(KERN_INFO "tf_cleanup_shared_memory(%p) done\n",
644 shmem_desc);
645}
646
647/*
648 * Make sure the coarse pages are allocated. If not allocated, do it.
649 * Locks down the physical memory pages.
650 * Verifies the memory attributes depending on flags.
651 */
652int tf_fill_descriptor_table(
653 struct tf_coarse_page_table_allocation_context *alloc_context,
654 struct tf_shmem_desc *shmem_desc,
655 u32 buffer,
656 struct vm_area_struct **vmas,
657 u32 descriptors[TF_MAX_COARSE_PAGES],
658 u32 buffer_size,
659 u32 *buffer_start_offset,
660 bool in_user_space,
661 u32 flags,
662 u32 *descriptor_count)
663{
664 u32 coarse_page_index;
665 u32 coarse_page_count;
666 u32 page_count;
667 u32 page_shift = 0;
668 int ret = 0;
669 unsigned int info = read_cpuid(CPUID_CACHETYPE);
670
671 dprintk(KERN_INFO "tf_fill_descriptor_table"
672 "(%p, buffer=0x%08X, size=0x%08X, user=%01x "
673 "flags = 0x%08x)\n",
674 shmem_desc,
675 buffer,
676 buffer_size,
677 in_user_space,
678 flags);
679
680 /*
681 * Compute the number of pages
682 * Compute the number of coarse pages
683 * Compute the page offset
684 */
685 page_count = ((buffer & ~PAGE_MASK) +
686 buffer_size + ~PAGE_MASK) >> PAGE_SHIFT;
687
688 /* check whether the 16k alignment restriction applies */
689 if (CACHE_S(info) && (CACHE_DSIZE(info) & (1 << 11)))
690 /*
691 * The 16k alignment restriction applies.
692 * Shift data to get them 16k aligned
693 */
694 page_shift = DESCRIPTOR_V13_12_GET(buffer);
695 page_count += page_shift;
696
697
698 /*
699 * Check the number of pages fit in the coarse pages
700 */
701 if (page_count > (TF_DESCRIPTOR_TABLE_CAPACITY *
702 TF_MAX_COARSE_PAGES)) {
703 dprintk(KERN_ERR "tf_fill_descriptor_table(%p): "
704 "%u pages required to map shared memory!\n",
705 shmem_desc, page_count);
706 ret = -ENOMEM;
707 goto error;
708 }
709
710 /* coarse page describe 256 pages */
711 coarse_page_count = ((page_count +
712 TF_DESCRIPTOR_TABLE_CAPACITY_MASK) >>
713 TF_DESCRIPTOR_TABLE_CAPACITY_BIT_SHIFT);
714
715 /*
716 * Compute the buffer offset
717 */
718 *buffer_start_offset = (buffer & ~PAGE_MASK) |
719 (page_shift << PAGE_SHIFT);
720
721 /* map each coarse page */
722 for (coarse_page_index = 0;
723 coarse_page_index < coarse_page_count;
724 coarse_page_index++) {
725 u32 j;
726 struct tf_coarse_page_table *coarse_pg_table;
727
728 /* compute a virtual address with appropriate offset */
729 u32 buffer_offset_vaddr = buffer +
730 (coarse_page_index * TF_MAX_COARSE_PAGE_MAPPED_SIZE);
731 u32 pages_to_get;
732
733 /*
734 * Compute the number of pages left for this coarse page.
735 * Decrement page_count each time
736 */
737 pages_to_get = (page_count >>
738 TF_DESCRIPTOR_TABLE_CAPACITY_BIT_SHIFT) ?
739 TF_DESCRIPTOR_TABLE_CAPACITY : page_count;
740 page_count -= pages_to_get;
741
742 /*
743 * Check if the coarse page has already been allocated
744 * If not, do it now
745 */
746 if ((shmem_desc->type == TF_SHMEM_TYPE_REGISTERED_SHMEM)
747 || (shmem_desc->type ==
748 TF_SHMEM_TYPE_PM_HIBERNATE)) {
749 coarse_pg_table = tf_alloc_coarse_page_table(
750 alloc_context,
751 TF_PAGE_DESCRIPTOR_TYPE_NORMAL);
752
753 if (coarse_pg_table == NULL) {
754 dprintk(KERN_ERR
755 "tf_fill_descriptor_table(%p): "
756 "tf_alloc_coarse_page_table "
757 "failed for coarse page %d\n",
758 shmem_desc, coarse_page_index);
759 ret = -ENOMEM;
760 goto error;
761 }
762
763 shmem_desc->coarse_pg_table[coarse_page_index] =
764 coarse_pg_table;
765 } else {
766 coarse_pg_table =
767 shmem_desc->coarse_pg_table[coarse_page_index];
768 }
769
770 /*
771 * The page is not necessarily filled with zeroes.
772 * Set the fault descriptors ( each descriptor is 4 bytes long)
773 */
774 memset(coarse_pg_table->descriptors, 0x00,
775 TF_DESCRIPTOR_TABLE_CAPACITY * sizeof(u32));
776
777 if (in_user_space) {
778 int pages;
779
780 /*
781 * TRICK: use pCoarsePageDescriptor->descriptors to
782 * hold the (struct page*) items before getting their
783 * physical address
784 */
785 down_read(&(current->mm->mmap_sem));
786 pages = internal_get_user_pages(
787 current,
788 current->mm,
789 buffer_offset_vaddr,
790 /*
791 * page_shift is cleared after retrieving first
792 * coarse page
793 */
794 (pages_to_get - page_shift),
795 (flags & TF_SHMEM_TYPE_WRITE) ? 1 : 0,
796 0,
797 (struct page **) (coarse_pg_table->descriptors
798 + page_shift),
799 vmas);
800 up_read(&(current->mm->mmap_sem));
801
802 if ((pages <= 0) ||
803 (pages != (pages_to_get - page_shift))) {
804 dprintk(KERN_ERR "tf_fill_descriptor_table:"
805 " get_user_pages got %d pages while "
806 "trying to get %d pages!\n",
807 pages, pages_to_get - page_shift);
808 ret = -EFAULT;
809 goto error;
810 }
811
812 for (j = page_shift;
813 j < page_shift + pages;
814 j++) {
815 /* Get the actual L2 descriptors */
816 tf_get_l2_page_descriptor(
817 &coarse_pg_table->descriptors[j],
818 flags,
819 current->mm);
820 /*
821 * Reject Strongly-Ordered or Device Memory
822 */
823#define IS_STRONGLY_ORDERED_OR_DEVICE_MEM(x) \
824 ((((x) & L2_TEX_C_B_MASK) == L2_TEX_C_B_STRONGLY_ORDERED) || \
825 (((x) & L2_TEX_C_B_MASK) == L2_TEX_C_B_SHARED_DEVICE) || \
826 (((x) & L2_TEX_C_B_MASK) == L2_TEX_C_B_NON_SHARED_DEVICE))
827
828 if (IS_STRONGLY_ORDERED_OR_DEVICE_MEM(
829 coarse_pg_table->
830 descriptors[j])) {
831 dprintk(KERN_ERR
832 "tf_fill_descriptor_table:"
833 " descriptor 0x%08X use "
834 "strongly-ordered or device "
835 "memory. Rejecting!\n",
836 coarse_pg_table->
837 descriptors[j]);
838 ret = -EFAULT;
839 goto error;
840 }
841 }
842 } else if (is_vmalloc_addr((void *)buffer_offset_vaddr)) {
843 /* Kernel-space memory obtained through vmalloc */
844 dprintk(KERN_INFO
845 "tf_fill_descriptor_table: "
846 "vmalloc'ed buffer starting at %p\n",
847 (void *)buffer_offset_vaddr);
848 for (j = page_shift; j < pages_to_get; j++) {
849 struct page *page;
850 void *addr =
851 (void *)(buffer_offset_vaddr +
852 (j - page_shift) * PAGE_SIZE);
853 page = vmalloc_to_page(addr);
854 if (page == NULL) {
855 dprintk(KERN_ERR
856 "tf_fill_descriptor_table: "
857 "cannot map %p (vmalloc) "
858 "to page\n",
859 addr);
860 ret = -EFAULT;
861 goto error;
862 }
863 coarse_pg_table->descriptors[j] = (u32)page;
864 get_page(page);
865
866 /* change coarse page "page address" */
867 tf_get_l2_page_descriptor(
868 &coarse_pg_table->descriptors[j],
869 flags,
870 &init_mm);
871 }
872 } else {
873 /* Kernel-space memory given by a virtual address */
874 dprintk(KERN_INFO
875 "tf_fill_descriptor_table: "
876 "buffer starting at virtual address %p\n",
877 (void *)buffer_offset_vaddr);
878 for (j = page_shift; j < pages_to_get; j++) {
879 struct page *page;
880 void *addr =
881 (void *)(buffer_offset_vaddr +
882 (j - page_shift) * PAGE_SIZE);
883 page = virt_to_page(addr);
884 if (page == NULL) {
885 dprintk(KERN_ERR
886 "tf_fill_descriptor_table: "
887 "cannot map %p (virtual) "
888 "to page\n",
889 addr);
890 ret = -EFAULT;
891 goto error;
892 }
893 coarse_pg_table->descriptors[j] = (u32)page;
894 get_page(page);
895
896 /* change coarse page "page address" */
897 tf_get_l2_page_descriptor(
898 &coarse_pg_table->descriptors[j],
899 flags,
900 &init_mm);
901 }
902 }
903
904 dmac_flush_range((void *)coarse_pg_table->descriptors,
905 (void *)(((u32)(coarse_pg_table->descriptors)) +
906 TF_DESCRIPTOR_TABLE_CAPACITY * sizeof(u32)));
907
908 outer_clean_range(
909 __pa(coarse_pg_table->descriptors),
910 __pa(coarse_pg_table->descriptors) +
911 TF_DESCRIPTOR_TABLE_CAPACITY * sizeof(u32));
912 wmb();
913
914 /* Update the coarse page table address */
915 descriptors[coarse_page_index] =
916 tf_get_l1_coarse_descriptor(
917 coarse_pg_table->descriptors);
918
919 /*
920 * The next coarse page has no page shift, reset the
921 * page_shift
922 */
923 page_shift = 0;
924 }
925
926 *descriptor_count = coarse_page_count;
927 shmem_desc->coarse_pg_table_count = coarse_page_count;
928
929#ifdef DEBUG_COARSE_TABLES
930 printk(KERN_DEBUG "ntf_fill_descriptor_table - size=0x%08X "
931 "numberOfCoarsePages=%d\n", buffer_size,
932 shmem_desc->coarse_pg_table_count);
933 for (coarse_page_index = 0;
934 coarse_page_index < shmem_desc->coarse_pg_table_count;
935 coarse_page_index++) {
936 u32 j;
937 struct tf_coarse_page_table *coarse_page_table =
938 shmem_desc->coarse_pg_table[coarse_page_index];
939
940 printk(KERN_DEBUG " Descriptor=%p address=%p index=%d\n",
941 coarse_page_table,
942 coarse_page_table->descriptors,
943 coarse_page_index);
944 for (j = 0;
945 j < TF_DESCRIPTOR_TABLE_CAPACITY;
946 j += 8) {
947 int k;
948 printk(KERN_DEBUG " ");
949 for (k = j; k < j + 8; k++)
950 printk(KERN_DEBUG "0x%08X ",
951 coarse_page_table->descriptors[k]);
952 printk(KERN_DEBUG "\n");
953 }
954 }
955 printk(KERN_DEBUG "ntf_fill_descriptor_table() - done\n\n");
956#endif
957
958 return 0;
959
960error:
961 tf_cleanup_shared_memory(
962 alloc_context,
963 shmem_desc,
964 0);
965
966 return ret;
967}
968
969
970/*----------------------------------------------------------------------------
971 * Standard communication operations
972 *----------------------------------------------------------------------------*/
973
974u8 *tf_get_description(struct tf_comm *comm)
975{
976 if (test_bit(TF_COMM_FLAG_L1_SHARED_ALLOCATED, &(comm->flags)))
977 return comm->l1_buffer->version_description;
978
979 return NULL;
980}
981
982/*
983 * Returns a non-zero value if the specified S-timeout has expired, zero
984 * otherwise.
985 *
986 * The placeholder referenced to by relative_timeout_jiffies gives the relative
987 * timeout from now in jiffies. It is set to zero if the S-timeout has expired,
988 * or to MAX_SCHEDULE_TIMEOUT if the S-timeout is infinite.
989 */
990static int tf_test_s_timeout(
991 u64 timeout,
992 signed long *relative_timeout_jiffies)
993{
994 struct timeval now;
995 u64 time64;
996
997 *relative_timeout_jiffies = 0;
998
999 /* immediate timeout */
1000 if (timeout == TIME_IMMEDIATE)
1001 return 1;
1002
1003 /* infinite timeout */
1004 if (timeout == TIME_INFINITE) {
1005 dprintk(KERN_DEBUG "tf_test_s_timeout: "
1006 "timeout is infinite\n");
1007 *relative_timeout_jiffies = MAX_SCHEDULE_TIMEOUT;
1008 return 0;
1009 }
1010
1011 do_gettimeofday(&now);
1012 time64 = now.tv_sec;
1013 /* will not overflow as operations are done on 64bit values */
1014 time64 = (time64 * 1000) + (now.tv_usec / 1000);
1015
1016 /* timeout expired */
1017 if (time64 >= timeout) {
1018 dprintk(KERN_DEBUG "tf_test_s_timeout: timeout expired\n");
1019 return 1;
1020 }
1021
1022 /*
1023 * finite timeout, compute relative_timeout_jiffies
1024 */
1025 /* will not overflow as time64 < timeout */
1026 timeout -= time64;
1027
1028 /* guarantee *relative_timeout_jiffies is a valid timeout */
1029 if ((timeout >> 32) != 0)
1030 *relative_timeout_jiffies = MAX_JIFFY_OFFSET;
1031 else
1032 *relative_timeout_jiffies =
1033 msecs_to_jiffies((unsigned int) timeout);
1034
1035 dprintk(KERN_DEBUG "tf_test_s_timeout: timeout is 0x%lx\n",
1036 *relative_timeout_jiffies);
1037 return 0;
1038}
1039
1040static void tf_copy_answers(struct tf_comm *comm)
1041{
1042 u32 first_answer;
1043 u32 first_free_answer;
1044 struct tf_answer_struct *answerStructureTemp;
1045
1046 if (test_bit(TF_COMM_FLAG_L1_SHARED_ALLOCATED, &(comm->flags))) {
1047 spin_lock(&comm->lock);
1048 first_free_answer = tf_read_reg32(
1049 &comm->l1_buffer->first_free_answer);
1050 first_answer = tf_read_reg32(
1051 &comm->l1_buffer->first_answer);
1052
1053 while (first_answer != first_free_answer) {
1054 /* answer queue not empty */
1055 union tf_answer sComAnswer;
1056 struct tf_answer_header header;
1057
1058 /*
1059 * the size of the command in words of 32bit, not in
1060 * bytes
1061 */
1062 u32 command_size;
1063 u32 i;
1064 u32 *temp = (uint32_t *) &header;
1065
1066 dprintk(KERN_INFO
1067 "[pid=%d] tf_copy_answers(%p): "
1068 "Read answers from L1\n",
1069 current->pid, comm);
1070
1071 /* Read the answer header */
1072 for (i = 0;
1073 i < sizeof(struct tf_answer_header)/sizeof(u32);
1074 i++)
1075 temp[i] = comm->l1_buffer->answer_queue[
1076 (first_answer + i) %
1077 TF_S_ANSWER_QUEUE_CAPACITY];
1078
1079 /* Read the answer from the L1_Buffer*/
1080 command_size = header.message_size +
1081 sizeof(struct tf_answer_header)/sizeof(u32);
1082 temp = (uint32_t *) &sComAnswer;
1083 for (i = 0; i < command_size; i++)
1084 temp[i] = comm->l1_buffer->answer_queue[
1085 (first_answer + i) %
1086 TF_S_ANSWER_QUEUE_CAPACITY];
1087
1088 answerStructureTemp = (struct tf_answer_struct *)
1089 sComAnswer.header.operation_id;
1090
1091 tf_dump_answer(&sComAnswer);
1092
1093 memcpy(answerStructureTemp->answer, &sComAnswer,
1094 command_size * sizeof(u32));
1095 answerStructureTemp->answer_copied = true;
1096
1097 first_answer += command_size;
1098 tf_write_reg32(&comm->l1_buffer->first_answer,
1099 first_answer);
1100 }
1101 spin_unlock(&(comm->lock));
1102 }
1103}
1104
1105static void tf_copy_command(
1106 struct tf_comm *comm,
1107 union tf_command *command,
1108 struct tf_connection *connection,
1109 enum TF_COMMAND_STATE *command_status)
1110{
1111 if ((test_bit(TF_COMM_FLAG_L1_SHARED_ALLOCATED, &(comm->flags)))
1112 && (command != NULL)) {
1113 /*
1114 * Write the message in the message queue.
1115 */
1116
1117 if (*command_status == TF_COMMAND_STATE_PENDING) {
1118 u32 command_size;
1119 u32 queue_words_count;
1120 u32 i;
1121 u32 first_free_command;
1122 u32 first_command;
1123
1124 spin_lock(&comm->lock);
1125
1126 first_command = tf_read_reg32(
1127 &comm->l1_buffer->first_command);
1128 first_free_command = tf_read_reg32(
1129 &comm->l1_buffer->first_free_command);
1130
1131 queue_words_count = first_free_command - first_command;
1132 command_size = command->header.message_size +
1133 sizeof(struct tf_command_header)/sizeof(u32);
1134 if ((queue_words_count + command_size) <
1135 TF_N_MESSAGE_QUEUE_CAPACITY) {
1136 /*
1137 * Command queue is not full.
1138 * If the Command queue is full,
1139 * the command will be copied at
1140 * another iteration
1141 * of the current function.
1142 */
1143
1144 /*
1145 * Change the conn state
1146 */
1147 if (connection == NULL)
1148 goto copy;
1149
1150 spin_lock(&(connection->state_lock));
1151
1152 if ((connection->state ==
1153 TF_CONN_STATE_NO_DEVICE_CONTEXT)
1154 &&
1155 (command->header.message_type ==
1156 TF_MESSAGE_TYPE_CREATE_DEVICE_CONTEXT)) {
1157
1158 dprintk(KERN_INFO
1159 "tf_copy_command(%p):"
1160 "Conn state is DEVICE_CONTEXT_SENT\n",
1161 connection);
1162 connection->state =
1163 TF_CONN_STATE_CREATE_DEVICE_CONTEXT_SENT;
1164 } else if ((connection->state !=
1165 TF_CONN_STATE_VALID_DEVICE_CONTEXT)
1166 &&
1167 (command->header.message_type !=
1168 TF_MESSAGE_TYPE_CREATE_DEVICE_CONTEXT)) {
1169 /* The connection
1170 * is no longer valid.
1171 * We may not send any command on it,
1172 * not even another
1173 * DESTROY_DEVICE_CONTEXT.
1174 */
1175 dprintk(KERN_INFO
1176 "[pid=%d] tf_copy_command(%p): "
1177 "Connection no longer valid."
1178 "ABORT\n",
1179 current->pid, connection);
1180 *command_status =
1181 TF_COMMAND_STATE_ABORTED;
1182 spin_unlock(
1183 &(connection->state_lock));
1184 spin_unlock(
1185 &comm->lock);
1186 return;
1187 } else if (
1188 (command->header.message_type ==
1189 TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT) &&
1190 (connection->state ==
1191 TF_CONN_STATE_VALID_DEVICE_CONTEXT)
1192 ) {
1193 dprintk(KERN_INFO
1194 "[pid=%d] tf_copy_command(%p): "
1195 "Conn state is "
1196 "DESTROY_DEVICE_CONTEXT_SENT\n",
1197 current->pid, connection);
1198 connection->state =
1199 TF_CONN_STATE_DESTROY_DEVICE_CONTEXT_SENT;
1200 }
1201 spin_unlock(&(connection->state_lock));
1202copy:
1203 /*
1204 * Copy the command to L1 Buffer
1205 */
1206 dprintk(KERN_INFO
1207 "[pid=%d] tf_copy_command(%p): "
1208 "Write Message in the queue\n",
1209 current->pid, command);
1210 tf_dump_command(command);
1211
1212 for (i = 0; i < command_size; i++)
1213 comm->l1_buffer->command_queue[
1214 (first_free_command + i) %
1215 TF_N_MESSAGE_QUEUE_CAPACITY] =
1216 ((uint32_t *) command)[i];
1217
1218 *command_status =
1219 TF_COMMAND_STATE_SENT;
1220 first_free_command += command_size;
1221
1222 tf_write_reg32(
1223 &comm->
1224 l1_buffer->first_free_command,
1225 first_free_command);
1226 }
1227 spin_unlock(&comm->lock);
1228 }
1229 }
1230}
1231
1232/*
1233 * Sends the specified message through the specified communication channel.
1234 *
1235 * This function sends the command and waits for the answer
1236 *
1237 * Returns zero upon successful completion, or an appropriate error code upon
1238 * failure.
1239 */
1240static int tf_send_recv(struct tf_comm *comm,
1241 union tf_command *command,
1242 struct tf_answer_struct *answerStruct,
1243 struct tf_connection *connection,
1244 int bKillable
1245 )
1246{
1247 int result;
1248 u64 timeout;
1249 signed long nRelativeTimeoutJiffies;
1250 bool wait_prepared = false;
1251 enum TF_COMMAND_STATE command_status = TF_COMMAND_STATE_PENDING;
1252 DEFINE_WAIT(wait);
1253#ifdef CONFIG_FREEZER
1254 unsigned long saved_flags;
1255#endif
1256 dprintk(KERN_INFO "[pid=%d] tf_send_recv(%p)\n",
1257 current->pid, command);
1258
1259#ifdef CONFIG_TF_ZEBRA
1260 tf_clock_timer_start();
1261#endif
1262
1263#ifdef CONFIG_FREEZER
1264 saved_flags = current->flags;
1265 current->flags |= PF_FREEZER_NOSIG;
1266#endif
1267
1268 /*
1269 * Read all answers from the answer queue
1270 */
1271copy_answers:
1272 tf_copy_answers(comm);
1273
1274 tf_copy_command(comm, command, connection, &command_status);
1275
1276 /*
1277 * Notify all waiting threads
1278 */
1279 wake_up(&(comm->wait_queue));
1280
1281#ifdef CONFIG_FREEZER
1282 if (unlikely(freezing(current))) {
1283
1284 dprintk(KERN_INFO
1285 "Entering refrigerator.\n");
1286 refrigerator();
1287 dprintk(KERN_INFO
1288 "Left refrigerator.\n");
1289 goto copy_answers;
1290 }
1291#endif
1292
1293#ifndef CONFIG_PREEMPT
1294 if (need_resched())
1295 schedule();
1296#endif
1297
1298#ifdef CONFIG_TF_ZEBRA
1299 /*
1300 * Handle RPC (if any)
1301 */
1302 if (tf_rpc_execute(comm) == RPC_NON_YIELD)
1303 goto schedule_secure_world;
1304#endif
1305
1306 /*
1307 * Join wait queue
1308 */
1309 /*dprintk(KERN_INFO "[pid=%d] tf_send_recv(%p): Prepare to wait\n",
1310 current->pid, command);*/
1311 prepare_to_wait(&comm->wait_queue, &wait,
1312 bKillable ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
1313 wait_prepared = true;
1314
1315 /*
1316 * Check if our answer is available
1317 */
1318 if (command_status == TF_COMMAND_STATE_ABORTED) {
1319 /* Not waiting for an answer, return error code */
1320 result = -EINTR;
1321 dprintk(KERN_ERR "[pid=%d] tf_send_recv: "
1322 "Command status is ABORTED."
1323 "Exit with 0x%x\n",
1324 current->pid, result);
1325 goto exit;
1326 }
1327 if (answerStruct->answer_copied) {
1328 dprintk(KERN_INFO "[pid=%d] tf_send_recv: "
1329 "Received answer (type 0x%02X)\n",
1330 current->pid,
1331 answerStruct->answer->header.message_type);
1332 result = 0;
1333 goto exit;
1334 }
1335
1336 /*
1337 * Check if a signal is pending
1338 */
1339 if (bKillable && (sigkill_pending())) {
1340 if (command_status == TF_COMMAND_STATE_PENDING)
1341 /*Command was not sent. */
1342 result = -EINTR;
1343 else
1344 /* Command was sent but no answer was received yet. */
1345 result = -EIO;
1346
1347 dprintk(KERN_ERR "[pid=%d] tf_send_recv: "
1348 "Signal Pending. Return error %d\n",
1349 current->pid, result);
1350 goto exit;
1351 }
1352
1353 /*
1354 * Check if secure world is schedulable. It is schedulable if at
1355 * least one of the following conditions holds:
1356 * + it is still initializing (TF_COMM_FLAG_L1_SHARED_ALLOCATED
1357 * is not set);
1358 * + there is a command in the queue;
1359 * + the secure world timeout is zero.
1360 */
1361 if (test_bit(TF_COMM_FLAG_L1_SHARED_ALLOCATED, &(comm->flags))) {
1362 u32 first_free_command;
1363 u32 first_command;
1364 spin_lock(&comm->lock);
1365 first_command = tf_read_reg32(
1366 &comm->l1_buffer->first_command);
1367 first_free_command = tf_read_reg32(
1368 &comm->l1_buffer->first_free_command);
1369 spin_unlock(&comm->lock);
1370 tf_read_timeout(comm, &timeout);
1371 if ((first_free_command == first_command) &&
1372 (tf_test_s_timeout(timeout,
1373 &nRelativeTimeoutJiffies) == 0))
1374 /*
1375 * If command queue is empty and if timeout has not
1376 * expired secure world is not schedulable
1377 */
1378 goto wait;
1379 }
1380
1381 finish_wait(&comm->wait_queue, &wait);
1382 wait_prepared = false;
1383
1384 /*
1385 * Yield to the Secure World
1386 */
1387#ifdef CONFIG_TF_ZEBRA
1388schedule_secure_world:
1389#endif
1390
1391 result = tf_schedule_secure_world(comm);
1392 if (result < 0)
1393 goto exit;
1394 goto copy_answers;
1395
1396wait:
1397 if (bKillable && (sigkill_pending())) {
1398 if (command_status == TF_COMMAND_STATE_PENDING)
1399 result = -EINTR; /* Command was not sent. */
1400 else
1401 /* Command was sent but no answer was received yet. */
1402 result = -EIO;
1403
1404 dprintk(KERN_ERR "[pid=%d] tf_send_recv: "
1405 "Signal Pending while waiting. Return error %d\n",
1406 current->pid, result);
1407 goto exit;
1408 }
1409
1410 if (nRelativeTimeoutJiffies == MAX_SCHEDULE_TIMEOUT)
1411 dprintk(KERN_INFO "[pid=%d] tf_send_recv: "
1412 "prepare to sleep infinitely\n", current->pid);
1413 else
1414 dprintk(KERN_INFO "tf_send_recv: "
1415 "prepare to sleep 0x%lx jiffies\n",
1416 nRelativeTimeoutJiffies);
1417
1418 /* go to sleep */
1419 if (schedule_timeout(nRelativeTimeoutJiffies) == 0)
1420 dprintk(KERN_INFO
1421 "tf_send_recv: timeout expired\n");
1422 else
1423 dprintk(KERN_INFO
1424 "tf_send_recv: signal delivered\n");
1425
1426 finish_wait(&comm->wait_queue, &wait);
1427 wait_prepared = false;
1428 goto copy_answers;
1429
1430exit:
1431 if (wait_prepared) {
1432 finish_wait(&comm->wait_queue, &wait);
1433 wait_prepared = false;
1434 }
1435
1436#ifdef CONFIG_FREEZER
1437 current->flags &= ~(PF_FREEZER_NOSIG);
1438 current->flags |= (saved_flags & PF_FREEZER_NOSIG);
1439#endif
1440
1441 return result;
1442}
1443
1444/*
1445 * Sends the specified message through the specified communication channel.
1446 *
1447 * This function sends the message and waits for the corresponding answer
1448 * It may return if a signal needs to be delivered.
1449 *
1450 * Returns zero upon successful completion, or an appropriate error code upon
1451 * failure.
1452 */
1453int tf_send_receive(struct tf_comm *comm,
1454 union tf_command *command,
1455 union tf_answer *answer,
1456 struct tf_connection *connection,
1457 bool bKillable)
1458{
1459 int error;
1460 struct tf_answer_struct answerStructure;
1461#ifdef CONFIG_SMP
1462 long ret_affinity;
1463 cpumask_t saved_cpu_mask;
1464 cpumask_t local_cpu_mask = CPU_MASK_NONE;
1465#endif
1466
1467 answerStructure.answer = answer;
1468 answerStructure.answer_copied = false;
1469
1470 if (command != NULL)
1471 command->header.operation_id = (u32) &answerStructure;
1472
1473 dprintk(KERN_INFO "tf_send_receive\n");
1474
1475#ifdef CONFIG_TF_ZEBRA
1476 if (!test_bit(TF_COMM_FLAG_PA_AVAILABLE, &comm->flags)) {
1477 dprintk(KERN_ERR "tf_send_receive(%p): "
1478 "Secure world not started\n", comm);
1479
1480 return -EFAULT;
1481 }
1482#endif
1483
1484 if (test_bit(TF_COMM_FLAG_TERMINATING, &(comm->flags)) != 0) {
1485 dprintk(KERN_DEBUG
1486 "tf_send_receive: Flag Terminating is set\n");
1487 return 0;
1488 }
1489
1490#ifdef CONFIG_SMP
1491 cpu_set(0, local_cpu_mask);
1492 sched_getaffinity(0, &saved_cpu_mask);
1493 ret_affinity = sched_setaffinity(0, &local_cpu_mask);
1494 if (ret_affinity != 0)
1495 dprintk(KERN_ERR "sched_setaffinity #1 -> 0x%lX", ret_affinity);
1496#endif
1497
1498
1499 /*
1500 * Send the command
1501 */
1502 error = tf_send_recv(comm,
1503 command, &answerStructure, connection, bKillable);
1504
1505 if (!bKillable && sigkill_pending()) {
1506 if ((command->header.message_type ==
1507 TF_MESSAGE_TYPE_CREATE_DEVICE_CONTEXT) &&
1508 (answer->create_device_context.error_code ==
1509 S_SUCCESS)) {
1510
1511 /*
1512 * CREATE_DEVICE_CONTEXT was interrupted.
1513 */
1514 dprintk(KERN_INFO "tf_send_receive: "
1515 "sending DESTROY_DEVICE_CONTEXT\n");
1516 answerStructure.answer = answer;
1517 answerStructure.answer_copied = false;
1518
1519 command->header.message_type =
1520 TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT;
1521 command->header.message_size =
1522 (sizeof(struct
1523 tf_command_destroy_device_context) -
1524 sizeof(struct tf_command_header))/sizeof(u32);
1525 command->header.operation_id =
1526 (u32) &answerStructure;
1527 command->destroy_device_context.device_context =
1528 answer->create_device_context.
1529 device_context;
1530
1531 goto destroy_context;
1532 }
1533 }
1534
1535 if (error == 0) {
1536 /*
1537 * tf_send_recv returned Success.
1538 */
1539 if (command->header.message_type ==
1540 TF_MESSAGE_TYPE_CREATE_DEVICE_CONTEXT) {
1541 spin_lock(&(connection->state_lock));
1542 connection->state = TF_CONN_STATE_VALID_DEVICE_CONTEXT;
1543 spin_unlock(&(connection->state_lock));
1544 } else if (command->header.message_type ==
1545 TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT) {
1546 spin_lock(&(connection->state_lock));
1547 connection->state = TF_CONN_STATE_NO_DEVICE_CONTEXT;
1548 spin_unlock(&(connection->state_lock));
1549 }
1550 } else if (error == -EINTR) {
1551 /*
1552 * No command was sent, return failure.
1553 */
1554 dprintk(KERN_ERR
1555 "tf_send_receive: "
1556 "tf_send_recv failed (error %d) !\n",
1557 error);
1558 } else if (error == -EIO) {
1559 /*
1560 * A command was sent but its answer is still pending.
1561 */
1562
1563 /* means bKillable is true */
1564 dprintk(KERN_ERR
1565 "tf_send_receive: "
1566 "tf_send_recv interrupted (error %d)."
1567 "Send DESTROY_DEVICE_CONTEXT.\n", error);
1568
1569 /* Send the DESTROY_DEVICE_CONTEXT. */
1570 answerStructure.answer = answer;
1571 answerStructure.answer_copied = false;
1572
1573 command->header.message_type =
1574 TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT;
1575 command->header.message_size =
1576 (sizeof(struct tf_command_destroy_device_context) -
1577 sizeof(struct tf_command_header))/sizeof(u32);
1578 command->header.operation_id =
1579 (u32) &answerStructure;
1580 command->destroy_device_context.device_context =
1581 connection->device_context;
1582
1583 error = tf_send_recv(comm,
1584 command, &answerStructure, connection, false);
1585 if (error == -EINTR) {
1586 /*
1587 * Another thread already sent
1588 * DESTROY_DEVICE_CONTEXT.
1589 * We must still wait for the answer
1590 * to the original command.
1591 */
1592 command = NULL;
1593 goto destroy_context;
1594 } else {
1595 /* An answer was received.
1596 * Check if it is the answer
1597 * to the DESTROY_DEVICE_CONTEXT.
1598 */
1599 spin_lock(&comm->lock);
1600 if (answer->header.message_type !=
1601 TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT) {
1602 answerStructure.answer_copied = false;
1603 }
1604 spin_unlock(&comm->lock);
1605 if (!answerStructure.answer_copied) {
1606 /* Answer to DESTROY_DEVICE_CONTEXT
1607 * was not yet received.
1608 * Wait for the answer.
1609 */
1610 dprintk(KERN_INFO
1611 "[pid=%d] tf_send_receive:"
1612 "Answer to DESTROY_DEVICE_CONTEXT"
1613 "not yet received.Retry\n",
1614 current->pid);
1615 command = NULL;
1616 goto destroy_context;
1617 }
1618 }
1619 }
1620
1621 dprintk(KERN_INFO "tf_send_receive(): Message answer ready\n");
1622 goto exit;
1623
1624destroy_context:
1625 error = tf_send_recv(comm,
1626 command, &answerStructure, connection, false);
1627
1628 /*
1629 * tf_send_recv cannot return an error because
1630 * it's not killable and not within a connection
1631 */
1632 BUG_ON(error != 0);
1633
1634 /* Reset the state, so a new CREATE DEVICE CONTEXT can be sent */
1635 spin_lock(&(connection->state_lock));
1636 connection->state = TF_CONN_STATE_NO_DEVICE_CONTEXT;
1637 spin_unlock(&(connection->state_lock));
1638
1639exit:
1640
1641#ifdef CONFIG_SMP
1642 ret_affinity = sched_setaffinity(0, &saved_cpu_mask);
1643 if (ret_affinity != 0)
1644 dprintk(KERN_ERR "sched_setaffinity #2 -> 0x%lX", ret_affinity);
1645#endif
1646 return error;
1647}
1648
1649/*----------------------------------------------------------------------------
1650 * Power management
1651 *----------------------------------------------------------------------------*/
1652
1653
1654/*
1655 * Handles all the power management calls.
1656 * The operation is the type of power management
1657 * operation to be performed.
1658 *
1659 * This routine will only return if a failure occured or if
1660 * the required opwer management is of type "resume".
1661 * "Hibernate" and "Shutdown" should lock when doing the
1662 * corresponding SMC to the Secure World
1663 */
1664int tf_power_management(struct tf_comm *comm,
1665 enum TF_POWER_OPERATION operation)
1666{
1667 u32 status;
1668 int error = 0;
1669
1670 dprintk(KERN_INFO "tf_power_management(%d)\n", operation);
1671
1672#ifdef CONFIG_TF_ZEBRA
1673 if (!test_bit(TF_COMM_FLAG_PA_AVAILABLE, &comm->flags)) {
1674 dprintk(KERN_INFO "tf_power_management(%p): "
1675 "succeeded (not started)\n", comm);
1676
1677 return 0;
1678 }
1679#endif
1680
1681 status = ((tf_read_reg32(&(comm->l1_buffer->status_s))
1682 & TF_STATUS_POWER_STATE_MASK)
1683 >> TF_STATUS_POWER_STATE_SHIFT);
1684
1685 switch (operation) {
1686 case TF_POWER_OPERATION_SHUTDOWN:
1687 switch (status) {
1688 case TF_POWER_MODE_ACTIVE:
1689 error = tf_pm_shutdown(comm);
1690
1691 if (error) {
1692 dprintk(KERN_ERR "tf_power_management(): "
1693 "Failed with error code 0x%08x\n",
1694 error);
1695 goto error;
1696 }
1697 break;
1698
1699 default:
1700 goto not_allowed;
1701 }
1702 break;
1703
1704 case TF_POWER_OPERATION_HIBERNATE:
1705 switch (status) {
1706 case TF_POWER_MODE_ACTIVE:
1707 error = tf_pm_hibernate(comm);
1708
1709 if (error) {
1710 dprintk(KERN_ERR "tf_power_management(): "
1711 "Failed with error code 0x%08x\n",
1712 error);
1713 goto error;
1714 }
1715 break;
1716
1717 default:
1718 goto not_allowed;
1719 }
1720 break;
1721
1722 case TF_POWER_OPERATION_RESUME:
1723 error = tf_pm_resume(comm);
1724
1725 if (error != 0) {
1726 dprintk(KERN_ERR "tf_power_management(): "
1727 "Failed with error code 0x%08x\n",
1728 error);
1729 goto error;
1730 }
1731 break;
1732 }
1733
1734 dprintk(KERN_INFO "tf_power_management(): succeeded\n");
1735 return 0;
1736
1737not_allowed:
1738 dprintk(KERN_ERR "tf_power_management(): "
1739 "Power command not allowed in current "
1740 "Secure World state %d\n", status);
1741 error = -ENOTTY;
1742error:
1743 return error;
1744}
1745
diff --git a/security/tf_driver/tf_comm.h b/security/tf_driver/tf_comm.h
new file mode 100644
index 00000000000..8921dc1d1be
--- /dev/null
+++ b/security/tf_driver/tf_comm.h
@@ -0,0 +1,202 @@
1/**
2 * Copyright (c) 2011 Trusted Logic S.A.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#ifndef __TF_COMM_H__
21#define __TF_COMM_H__
22
23#include "tf_defs.h"
24#include "tf_protocol.h"
25
26/*----------------------------------------------------------------------------
27 * Misc
28 *----------------------------------------------------------------------------*/
29
30void tf_set_current_time(struct tf_comm *comm);
31
32/*
33 * Atomic accesses to 32-bit variables in the L1 Shared buffer
34 */
35static inline u32 tf_read_reg32(const u32 *comm_buffer)
36{
37 u32 result;
38
39 __asm__ __volatile__("@ tf_read_reg32\n"
40 "ldrex %0, [%1]\n"
41 : "=&r" (result)
42 : "r" (comm_buffer)
43 );
44
45 return result;
46}
47
48static inline void tf_write_reg32(void *comm_buffer, u32 value)
49{
50 u32 tmp;
51
52 __asm__ __volatile__("@ tf_write_reg32\n"
53 "1: ldrex %0, [%2]\n"
54 " strex %0, %1, [%2]\n"
55 " teq %0, #0\n"
56 " bne 1b"
57 : "=&r" (tmp)
58 : "r" (value), "r" (comm_buffer)
59 : "cc"
60 );
61}
62
63/*
64 * Atomic accesses to 64-bit variables in the L1 Shared buffer
65 */
66static inline u64 tf_read_reg64(void *comm_buffer)
67{
68 u64 result;
69
70 __asm__ __volatile__("@ tf_read_reg64\n"
71 "ldrexd %0, [%1]\n"
72 : "=&r" (result)
73 : "r" (comm_buffer)
74 );
75
76 return result;
77}
78
79static inline void tf_write_reg64(void *comm_buffer, u64 value)
80{
81 u64 tmp;
82
83 __asm__ __volatile__("@ tf_write_reg64\n"
84 "1: ldrexd %0, [%2]\n"
85 " strexd %0, %1, [%2]\n"
86 " teq %0, #0\n"
87 " bne 1b"
88 : "=&r" (tmp)
89 : "r" (value), "r" (comm_buffer)
90 : "cc"
91 );
92}
93
94/*----------------------------------------------------------------------------
95 * SMC operations
96 *----------------------------------------------------------------------------*/
97
98/* RPC return values */
99#define RPC_NO 0x00 /* No RPC to execute */
100#define RPC_YIELD 0x01 /* Yield RPC */
101#define RPC_NON_YIELD 0x02 /* non-Yield RPC */
102
103int tf_rpc_execute(struct tf_comm *comm);
104
105/*----------------------------------------------------------------------------
106 * Shared memory related operations
107 *----------------------------------------------------------------------------*/
108
109#define L1_DESCRIPTOR_FAULT (0x00000000)
110#define L2_DESCRIPTOR_FAULT (0x00000000)
111
112#define L2_DESCRIPTOR_ADDR_MASK (0xFFFFF000)
113
114#define DESCRIPTOR_V13_12_MASK (0x3 << PAGE_SHIFT)
115#define DESCRIPTOR_V13_12_GET(a) ((a & DESCRIPTOR_V13_12_MASK) >> PAGE_SHIFT)
116
117struct tf_coarse_page_table *tf_alloc_coarse_page_table(
118 struct tf_coarse_page_table_allocation_context *alloc_context,
119 u32 type);
120
121void tf_free_coarse_page_table(
122 struct tf_coarse_page_table_allocation_context *alloc_context,
123 struct tf_coarse_page_table *coarse_pg_table,
124 int force);
125
126void tf_init_coarse_page_table_allocator(
127 struct tf_coarse_page_table_allocation_context *alloc_context);
128
129void tf_release_coarse_page_table_allocator(
130 struct tf_coarse_page_table_allocation_context *alloc_context);
131
132struct page *tf_l2_page_descriptor_to_page(u32 l2_page_descriptor);
133
134u32 tf_get_l2_descriptor_common(u32 vaddr, struct mm_struct *mm);
135
136void tf_cleanup_shared_memory(
137 struct tf_coarse_page_table_allocation_context *alloc_context,
138 struct tf_shmem_desc *shmem_desc,
139 u32 full_cleanup);
140
141int tf_fill_descriptor_table(
142 struct tf_coarse_page_table_allocation_context *alloc_context,
143 struct tf_shmem_desc *shmem_desc,
144 u32 buffer,
145 struct vm_area_struct **vmas,
146 u32 descriptors[TF_MAX_COARSE_PAGES],
147 u32 buffer_size,
148 u32 *buffer_start_offset,
149 bool in_user_space,
150 u32 flags,
151 u32 *descriptor_count);
152
153/*----------------------------------------------------------------------------
154 * Standard communication operations
155 *----------------------------------------------------------------------------*/
156
157int tf_schedule_secure_world(struct tf_comm *comm);
158
159int tf_send_receive(
160 struct tf_comm *comm,
161 union tf_command *command,
162 union tf_answer *answer,
163 struct tf_connection *connection,
164 bool bKillable);
165
166
167/**
168 * get a pointer to the secure world description.
169 * This points directly into the L1 shared buffer
170 * and is valid only once the communication has
171 * been initialized
172 **/
173u8 *tf_get_description(struct tf_comm *comm);
174
175/*----------------------------------------------------------------------------
176 * Power management
177 *----------------------------------------------------------------------------*/
178
179enum TF_POWER_OPERATION {
180 TF_POWER_OPERATION_HIBERNATE = 1,
181 TF_POWER_OPERATION_SHUTDOWN = 2,
182 TF_POWER_OPERATION_RESUME = 3,
183};
184
185int tf_pm_hibernate(struct tf_comm *comm);
186int tf_pm_resume(struct tf_comm *comm);
187int tf_pm_shutdown(struct tf_comm *comm);
188
189int tf_power_management(struct tf_comm *comm,
190 enum TF_POWER_OPERATION operation);
191
192
193/*----------------------------------------------------------------------------
194 * Communication initialization and termination
195 *----------------------------------------------------------------------------*/
196
197int tf_init(struct tf_comm *comm);
198
199void tf_terminate(struct tf_comm *comm);
200
201
202#endif /* __TF_COMM_H__ */
diff --git a/security/tf_driver/tf_comm_tz.c b/security/tf_driver/tf_comm_tz.c
new file mode 100644
index 00000000000..4c89de84acc
--- /dev/null
+++ b/security/tf_driver/tf_comm_tz.c
@@ -0,0 +1,885 @@
1/**
2 * Copyright (c) 2011 Trusted Logic S.A.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#include <asm/div64.h>
21#include <asm/system.h>
22#include <linux/version.h>
23#include <asm/cputype.h>
24#include <linux/interrupt.h>
25#include <linux/page-flags.h>
26#include <linux/pagemap.h>
27#include <linux/vmalloc.h>
28#include <linux/jiffies.h>
29
30#include "tf_defs.h"
31#include "tf_comm.h"
32#include "tf_protocol.h"
33#include "tf_util.h"
34#include "tf_conn.h"
35
36/*
37 * Structure common to all SMC operations
38 */
39struct tf_generic_smc {
40 u32 reg0;
41 u32 reg1;
42 u32 reg2;
43 u32 reg3;
44 u32 reg4;
45};
46
47/*----------------------------------------------------------------------------
48 * SMC operations
49 *----------------------------------------------------------------------------*/
50
51static inline void tf_smc_generic_call(
52 struct tf_generic_smc *generic_smc)
53{
54#ifdef CONFIG_SMP
55 long ret;
56 cpumask_t saved_cpu_mask;
57 cpumask_t local_cpu_mask = CPU_MASK_NONE;
58
59 cpu_set(0, local_cpu_mask);
60 sched_getaffinity(0, &saved_cpu_mask);
61 ret = sched_setaffinity(0, &local_cpu_mask);
62 if (ret != 0)
63 dprintk(KERN_ERR "sched_setaffinity #1 -> 0x%lX", ret);
64#endif
65
66 __asm__ volatile(
67 "mov r0, %2\n"
68 "mov r1, %3\n"
69 "mov r2, %4\n"
70 "mov r3, %5\n"
71 "mov r4, %6\n"
72 ".word 0xe1600070 @ SMC 0\n"
73 "mov %0, r0\n"
74 "mov %1, r1\n"
75 : "=r" (generic_smc->reg0), "=r" (generic_smc->reg1)
76 : "r" (generic_smc->reg0), "r" (generic_smc->reg1),
77 "r" (generic_smc->reg2), "r" (generic_smc->reg3),
78 "r" (generic_smc->reg4)
79 : "r0", "r1", "r2", "r3", "r4");
80
81#ifdef CONFIG_SMP
82 ret = sched_setaffinity(0, &saved_cpu_mask);
83 if (ret != 0)
84 dprintk(KERN_ERR "sched_setaffinity #2 -> 0x%lX", ret);
85#endif
86}
87
88/*
89 * Calls the get protocol version SMC.
90 * Fills the parameter pProtocolVersion with the version number returned by the
91 * SMC
92 */
93static inline void tf_smc_get_protocol_version(u32 *protocol_version)
94{
95 struct tf_generic_smc generic_smc;
96
97 generic_smc.reg0 = TF_SMC_GET_PROTOCOL_VERSION;
98 generic_smc.reg1 = 0;
99 generic_smc.reg2 = 0;
100 generic_smc.reg3 = 0;
101 generic_smc.reg4 = 0;
102
103 tf_smc_generic_call(&generic_smc);
104 *protocol_version = generic_smc.reg1;
105}
106
107
108/*
109 * Calls the init SMC with the specified parameters.
110 * Returns zero upon successful completion, or an appropriate error code upon
111 * failure.
112 */
113static inline int tf_smc_init(u32 shared_page_descriptor)
114{
115 struct tf_generic_smc generic_smc;
116
117 generic_smc.reg0 = TF_SMC_INIT;
118 /* Descriptor for the layer 1 shared buffer */
119 generic_smc.reg1 = shared_page_descriptor;
120 generic_smc.reg2 = 0;
121 generic_smc.reg3 = 0;
122 generic_smc.reg4 = 0;
123
124 tf_smc_generic_call(&generic_smc);
125 if (generic_smc.reg0 != S_SUCCESS)
126 printk(KERN_ERR "tf_smc_init:"
127 " r0=0x%08X upon return (expected 0x%08X)!\n",
128 generic_smc.reg0,
129 S_SUCCESS);
130
131 return generic_smc.reg0;
132}
133
134
135/*
136 * Calls the reset irq SMC.
137 */
138static inline void tf_smc_reset_irq(void)
139{
140 struct tf_generic_smc generic_smc;
141
142 generic_smc.reg0 = TF_SMC_RESET_IRQ;
143 generic_smc.reg1 = 0;
144 generic_smc.reg2 = 0;
145 generic_smc.reg3 = 0;
146 generic_smc.reg4 = 0;
147
148 tf_smc_generic_call(&generic_smc);
149}
150
151
152/*
153 * Calls the WAKE_UP SMC.
154 * Returns zero upon successful completion, or an appropriate error code upon
155 * failure.
156 */
157static inline int tf_smc_wake_up(u32 l1_shared_buffer_descriptor,
158 u32 shared_mem_start_offset,
159 u32 shared_mem_size)
160{
161 struct tf_generic_smc generic_smc;
162
163 generic_smc.reg0 = TF_SMC_WAKE_UP;
164 generic_smc.reg1 = shared_mem_start_offset;
165 /* long form command */
166 generic_smc.reg2 = shared_mem_size | 0x80000000;
167 generic_smc.reg3 = l1_shared_buffer_descriptor;
168 generic_smc.reg4 = 0;
169
170 tf_smc_generic_call(&generic_smc);
171
172 if (generic_smc.reg0 != S_SUCCESS)
173 printk(KERN_ERR "tf_smc_wake_up:"
174 " r0=0x%08X upon return (expected 0x%08X)!\n",
175 generic_smc.reg0,
176 S_SUCCESS);
177
178 return generic_smc.reg0;
179}
180
181/*
182 * Calls the N-Yield SMC.
183 */
184static inline void tf_smc_nyield(void)
185{
186 struct tf_generic_smc generic_smc;
187
188 generic_smc.reg0 = TF_SMC_N_YIELD;
189 generic_smc.reg1 = 0;
190 generic_smc.reg2 = 0;
191 generic_smc.reg3 = 0;
192 generic_smc.reg4 = 0;
193
194 tf_smc_generic_call(&generic_smc);
195}
196
197/* Yields the Secure World */
198int tf_schedule_secure_world(struct tf_comm *comm)
199{
200 tf_set_current_time(comm);
201
202 /* yield to the Secure World */
203 tf_smc_nyield();
204
205 return 0;
206}
207
208/*
209 * Returns the L2 descriptor for the specified user page.
210 */
211
212#define L2_INIT_DESCRIPTOR_BASE (0x00000003)
213#define L2_INIT_DESCRIPTOR_V13_12_SHIFT (4)
214
215static u32 tf_get_l2init_descriptor(u32 vaddr)
216{
217 struct page *page;
218 u32 paddr;
219 u32 descriptor;
220
221 descriptor = L2_INIT_DESCRIPTOR_BASE;
222
223 /* get physical address and add to descriptor */
224 page = virt_to_page(vaddr);
225 paddr = page_to_phys(page);
226 descriptor |= (paddr & L2_DESCRIPTOR_ADDR_MASK);
227
228 /* Add virtual address v[13:12] bits to descriptor */
229 descriptor |= (DESCRIPTOR_V13_12_GET(vaddr)
230 << L2_INIT_DESCRIPTOR_V13_12_SHIFT);
231
232 descriptor |= tf_get_l2_descriptor_common(vaddr, &init_mm);
233
234
235 return descriptor;
236}
237
238
239/*----------------------------------------------------------------------------
240 * Power management
241 *----------------------------------------------------------------------------*/
242
243/*
244 * Free the memory used by the W3B buffer for the specified comm.
245 * This function does nothing if no W3B buffer is allocated for the device.
246 */
247static inline void tf_free_w3b(struct tf_comm *comm)
248{
249 tf_cleanup_shared_memory(
250 &(comm->w3b_cpt_alloc_context),
251 &(comm->w3b_shmem_desc),
252 0);
253
254 tf_release_coarse_page_table_allocator(&(comm->w3b_cpt_alloc_context));
255
256 internal_vfree((void *)comm->w3b);
257 comm->w3b = 0;
258 comm->w3b_shmem_size = 0;
259 clear_bit(TF_COMM_FLAG_W3B_ALLOCATED, &(comm->flags));
260}
261
262
263/*
264 * Allocates the W3B buffer for the specified comm.
265 * Returns zero upon successful completion, or an appropriate error code upon
266 * failure.
267 */
268static inline int tf_allocate_w3b(struct tf_comm *comm)
269{
270 int error;
271 u32 flags;
272 u32 config_flag_s;
273 u32 *w3b_descriptors;
274 u32 w3b_descriptor_count;
275 u32 w3b_current_size;
276
277 config_flag_s = tf_read_reg32(&comm->l1_buffer->config_flag_s);
278
279retry:
280 if ((test_bit(TF_COMM_FLAG_W3B_ALLOCATED, &(comm->flags))) == 0) {
281 /*
282 * Initialize the shared memory for the W3B
283 */
284 tf_init_coarse_page_table_allocator(
285 &comm->w3b_cpt_alloc_context);
286 } else {
287 /*
288 * The W3B is allocated but do we have to reallocate a bigger
289 * one?
290 */
291 /* Check H bit */
292 if ((config_flag_s & (1<<4)) != 0) {
293 /* The size of the W3B may change after SMC_INIT */
294 /* Read the current value */
295 w3b_current_size = tf_read_reg32(
296 &comm->l1_buffer->w3b_size_current_s);
297 if (comm->w3b_shmem_size > w3b_current_size)
298 return 0;
299
300 tf_free_w3b(comm);
301 goto retry;
302 } else {
303 return 0;
304 }
305 }
306
307 /* check H bit */
308 if ((config_flag_s & (1<<4)) != 0)
309 /* The size of the W3B may change after SMC_INIT */
310 /* Read the current value */
311 comm->w3b_shmem_size = tf_read_reg32(
312 &comm->l1_buffer->w3b_size_current_s);
313 else
314 comm->w3b_shmem_size = tf_read_reg32(
315 &comm->l1_buffer->w3b_size_max_s);
316
317 comm->w3b = (u32) internal_vmalloc(comm->w3b_shmem_size);
318 if (comm->w3b == 0) {
319 printk(KERN_ERR "tf_allocate_w3b():"
320 " Out of memory for W3B buffer (%u bytes)!\n",
321 (unsigned int)(comm->w3b_shmem_size));
322 error = -ENOMEM;
323 goto error;
324 }
325
326 /* initialize the w3b_shmem_desc structure */
327 comm->w3b_shmem_desc.type = TF_SHMEM_TYPE_PM_HIBERNATE;
328 INIT_LIST_HEAD(&(comm->w3b_shmem_desc.list));
329
330 flags = (TF_SHMEM_TYPE_READ | TF_SHMEM_TYPE_WRITE);
331
332 /* directly point to the L1 shared buffer W3B descriptors */
333 w3b_descriptors = comm->l1_buffer->w3b_descriptors;
334
335 /*
336 * tf_fill_descriptor_table uses the following parameter as an
337 * IN/OUT
338 */
339
340 error = tf_fill_descriptor_table(
341 &(comm->w3b_cpt_alloc_context),
342 &(comm->w3b_shmem_desc),
343 comm->w3b,
344 NULL,
345 w3b_descriptors,
346 comm->w3b_shmem_size,
347 &(comm->w3b_shmem_offset),
348 false,
349 flags,
350 &w3b_descriptor_count);
351 if (error != 0) {
352 printk(KERN_ERR "tf_allocate_w3b():"
353 " tf_fill_descriptor_table failed with "
354 "error code 0x%08x!\n",
355 error);
356 goto error;
357 }
358
359 set_bit(TF_COMM_FLAG_W3B_ALLOCATED, &(comm->flags));
360
361 /* successful completion */
362 return 0;
363
364error:
365 tf_free_w3b(comm);
366
367 return error;
368}
369
370/*
371 * Perform a Secure World shutdown operation.
372 * The routine does not return if the operation succeeds.
373 * the routine returns an appropriate error code if
374 * the operation fails.
375 */
376int tf_pm_shutdown(struct tf_comm *comm)
377{
378#ifdef CONFIG_TFN
379 /* this function is useless for the TEGRA product */
380 return 0;
381#else
382 int error;
383 union tf_command command;
384 union tf_answer answer;
385
386 dprintk(KERN_INFO "tf_pm_shutdown()\n");
387
388 memset(&command, 0, sizeof(command));
389
390 command.header.message_type = TF_MESSAGE_TYPE_MANAGEMENT;
391 command.header.message_size =
392 (sizeof(struct tf_command_management) -
393 sizeof(struct tf_command_header))/sizeof(u32);
394
395 command.management.command = TF_MANAGEMENT_SHUTDOWN;
396
397 error = tf_send_receive(
398 comm,
399 &command,
400 &answer,
401 NULL,
402 false);
403
404 if (error != 0) {
405 dprintk(KERN_ERR "tf_pm_shutdown(): "
406 "tf_send_receive failed (error %d)!\n",
407 error);
408 return error;
409 }
410
411#ifdef CONFIG_TF_DRIVER_DEBUG_SUPPORT
412 if (answer.header.error_code != 0)
413 dprintk(KERN_ERR "tf_driver: shutdown failed.\n");
414 else
415 dprintk(KERN_INFO "tf_driver: shutdown succeeded.\n");
416#endif
417
418 return answer.header.error_code;
419#endif
420}
421
422
423/*
424 * Perform a Secure World hibernate operation.
425 * The routine does not return if the operation succeeds.
426 * the routine returns an appropriate error code if
427 * the operation fails.
428 */
429int tf_pm_hibernate(struct tf_comm *comm)
430{
431#ifdef CONFIG_TFN
432 /* this function is useless for the TEGRA product */
433 return 0;
434#else
435 int error;
436 union tf_command command;
437 union tf_answer answer;
438 u32 first_command;
439 u32 first_free_command;
440
441 dprintk(KERN_INFO "tf_pm_hibernate()\n");
442
443 error = tf_allocate_w3b(comm);
444 if (error != 0) {
445 dprintk(KERN_ERR "tf_pm_hibernate(): "
446 "tf_allocate_w3b failed (error %d)!\n",
447 error);
448 return error;
449 }
450
451 /*
452 * As the polling thread is already hibernating, we
453 * should send the message and receive the answer ourself
454 */
455
456 /* build the "prepare to hibernate" message */
457 command.header.message_type = TF_MESSAGE_TYPE_MANAGEMENT;
458 command.management.command = TF_MANAGEMENT_HIBERNATE;
459 /* Long Form Command */
460 command.management.shared_mem_descriptors[0] = 0;
461 command.management.shared_mem_descriptors[1] = 0;
462 command.management.w3b_size =
463 comm->w3b_shmem_size | 0x80000000;
464 command.management.w3b_start_offset =
465 comm->w3b_shmem_offset;
466 command.header.operation_id = (u32) &answer;
467
468 tf_dump_command(&command);
469
470 /* find a slot to send the message in */
471
472 /* AFY: why not use the function tf_send_receive?? We are
473 * duplicating a lot of subtle code here. And it's not going to be
474 * tested because power management is currently not supported by the
475 * secure world. */
476 for (;;) {
477 int queue_words_count, command_size;
478
479 spin_lock(&(comm->lock));
480
481 first_command = tf_read_reg32(
482 &comm->l1_buffer->first_command);
483 first_free_command = tf_read_reg32(
484 &comm->l1_buffer->first_free_command);
485
486 queue_words_count = first_free_command - first_command;
487 command_size = command.header.message_size
488 + sizeof(struct tf_command_header);
489 if ((queue_words_count + command_size) <
490 TF_N_MESSAGE_QUEUE_CAPACITY) {
491 /* Command queue is not full */
492 memcpy(&comm->l1_buffer->command_queue[
493 first_free_command %
494 TF_N_MESSAGE_QUEUE_CAPACITY],
495 &command,
496 command_size * sizeof(u32));
497
498 tf_write_reg32(&comm->l1_buffer->first_free_command,
499 first_free_command + command_size);
500
501 spin_unlock(&(comm->lock));
502 break;
503 }
504
505 spin_unlock(&(comm->lock));
506 (void)tf_schedule_secure_world(comm);
507 }
508
509 /* now wait for the answer, dispatching other answers */
510 while (1) {
511 u32 first_answer;
512 u32 first_free_answer;
513
514 /* check all the answers */
515 first_free_answer = tf_read_reg32(
516 &comm->l1_buffer->first_free_answer);
517 first_answer = tf_read_reg32(
518 &comm->l1_buffer->first_answer);
519
520 if (first_answer != first_free_answer) {
521 int bFoundAnswer = 0;
522
523 do {
524 /* answer queue not empty */
525 union tf_answer tmp_answer;
526 struct tf_answer_header header;
527 /* size of the command in words of 32bit */
528 int command_size;
529
530 /* get the message_size */
531 memcpy(&header,
532 &comm->l1_buffer->answer_queue[
533 first_answer %
534 TF_S_ANSWER_QUEUE_CAPACITY],
535 sizeof(struct tf_answer_header));
536 command_size = header.message_size +
537 sizeof(struct tf_answer_header);
538
539 /*
540 * NOTE: message_size is the number of words
541 * following the first word
542 */
543 memcpy(&tmp_answer,
544 &comm->l1_buffer->answer_queue[
545 first_answer %
546 TF_S_ANSWER_QUEUE_CAPACITY],
547 command_size * sizeof(u32));
548
549 tf_dump_answer(&tmp_answer);
550
551 if (tmp_answer.header.operation_id ==
552 (u32) &answer) {
553 /*
554 * this is the answer to the "prepare to
555 * hibernate" message
556 */
557 memcpy(&answer,
558 &tmp_answer,
559 command_size * sizeof(u32));
560
561 bFoundAnswer = 1;
562 tf_write_reg32(
563 &comm->l1_buffer->first_answer,
564 first_answer + command_size);
565 break;
566 } else {
567 /*
568 * this is a standard message answer,
569 * dispatch it
570 */
571 struct tf_answer_struct
572 *answerStructure;
573
574 answerStructure =
575 (struct tf_answer_struct *)
576 tmp_answer.header.operation_id;
577
578 memcpy(answerStructure->answer,
579 &tmp_answer,
580 command_size * sizeof(u32));
581
582 answerStructure->answer_copied = true;
583 }
584
585 tf_write_reg32(
586 &comm->l1_buffer->first_answer,
587 first_answer + command_size);
588 } while (first_answer != first_free_answer);
589
590 if (bFoundAnswer)
591 break;
592 }
593
594 /*
595 * since the Secure World is at least running the "prepare to
596 * hibernate" message, its timeout must be immediate So there is
597 * no need to check its timeout and schedule() the current
598 * thread
599 */
600 (void)tf_schedule_secure_world(comm);
601 } /* while (1) */
602
603 printk(KERN_INFO "tf_driver: hibernate.\n");
604 return 0;
605#endif
606}
607
608
609/*
610 * Perform a Secure World resume operation.
611 * The routine returns once the Secure World is active again
612 * or if an error occurs during the "resume" process
613 */
614int tf_pm_resume(struct tf_comm *comm)
615{
616#ifdef CONFIG_TFN
617 /* this function is useless for the TEGRA product */
618 return 0;
619#else
620 int error;
621 u32 status;
622
623 dprintk(KERN_INFO "tf_pm_resume()\n");
624
625 error = tf_smc_wake_up(
626 tf_get_l2init_descriptor((u32)comm->l1_buffer),
627 comm->w3b_shmem_offset,
628 comm->w3b_shmem_size);
629
630 if (error != 0) {
631 dprintk(KERN_ERR "tf_pm_resume(): "
632 "tf_smc_wake_up failed (error %d)!\n",
633 error);
634 return error;
635 }
636
637 status = ((tf_read_reg32(&(comm->l1_buffer->status_s))
638 & TF_STATUS_POWER_STATE_MASK)
639 >> TF_STATUS_POWER_STATE_SHIFT);
640
641 while ((status != TF_POWER_MODE_ACTIVE)
642 && (status != TF_POWER_MODE_PANIC)) {
643 tf_smc_nyield();
644
645 status = ((tf_read_reg32(&(comm->l1_buffer->status_s))
646 & TF_STATUS_POWER_STATE_MASK)
647 >> TF_STATUS_POWER_STATE_SHIFT);
648
649 /*
650 * As this may last quite a while, call the kernel scheduler to
651 * hand over CPU for other operations
652 */
653 schedule();
654 }
655
656 switch (status) {
657 case TF_POWER_MODE_ACTIVE:
658 break;
659
660 case TF_POWER_MODE_PANIC:
661 dprintk(KERN_ERR "tf_pm_resume(): "
662 "Secure World POWER_MODE_PANIC!\n");
663 return -EINVAL;
664
665 default:
666 dprintk(KERN_ERR "tf_pm_resume(): "
667 "unexpected Secure World POWER_MODE (%d)!\n", status);
668 return -EINVAL;
669 }
670
671 dprintk(KERN_INFO "tf_pm_resume() succeeded\n");
672 return 0;
673#endif
674}
675
676/*----------------------------------------------------------------------------
677 * Communication initialization and termination
678 *----------------------------------------------------------------------------*/
679
680/*
681 * Handles the software interrupts issued by the Secure World.
682 */
683static irqreturn_t tf_soft_int_handler(int irq, void *dev_id)
684{
685 struct tf_comm *comm = (struct tf_comm *) dev_id;
686
687 if (comm->l1_buffer == NULL)
688 return IRQ_NONE;
689
690 if ((tf_read_reg32(&comm->l1_buffer->status_s) &
691 TF_STATUS_P_MASK) == 0)
692 /* interrupt not issued by the Trusted Foundations Software */
693 return IRQ_NONE;
694
695 tf_smc_reset_irq();
696
697 /* signal N_SM_EVENT */
698 wake_up(&comm->wait_queue);
699
700 return IRQ_HANDLED;
701}
702
703/*
704 * Initializes the communication with the Secure World.
705 * The L1 shared buffer is allocated and the Secure World
706 * is yielded for the first time.
707 * returns successfuly once the communication with
708 * the Secure World is up and running
709 *
710 * Returns 0 upon success or appropriate error code
711 * upon failure
712 */
713int tf_init(struct tf_comm *comm)
714{
715 int error;
716 struct page *buffer_page;
717 u32 protocol_version;
718
719 dprintk(KERN_INFO "tf_init()\n");
720
721 spin_lock_init(&(comm->lock));
722 comm->flags = 0;
723 comm->l1_buffer = NULL;
724 init_waitqueue_head(&(comm->wait_queue));
725
726 /*
727 * Check the Secure World protocol version is the expected one.
728 */
729 tf_smc_get_protocol_version(&protocol_version);
730
731 if ((GET_PROTOCOL_MAJOR_VERSION(protocol_version))
732 != TF_S_PROTOCOL_MAJOR_VERSION) {
733 printk(KERN_ERR "tf_init():"
734 " Unsupported Secure World Major Version "
735 "(0x%02X, expected 0x%02X)!\n",
736 GET_PROTOCOL_MAJOR_VERSION(protocol_version),
737 TF_S_PROTOCOL_MAJOR_VERSION);
738 error = -EIO;
739 goto error;
740 }
741
742 /*
743 * Register the software interrupt handler if required to.
744 */
745 if (comm->soft_int_irq != -1) {
746 dprintk(KERN_INFO "tf_init(): "
747 "Registering software interrupt handler (IRQ %d)\n",
748 comm->soft_int_irq);
749
750 error = request_irq(comm->soft_int_irq,
751 tf_soft_int_handler,
752 IRQF_SHARED,
753 TF_DEVICE_BASE_NAME,
754 comm);
755 if (error != 0) {
756 dprintk(KERN_ERR "tf_init(): "
757 "request_irq failed for irq %d (error %d)\n",
758 comm->soft_int_irq, error);
759 goto error;
760 }
761 set_bit(TF_COMM_FLAG_IRQ_REQUESTED, &(comm->flags));
762 }
763
764 /*
765 * Allocate and initialize the L1 shared buffer.
766 */
767 comm->l1_buffer = (void *) internal_get_zeroed_page(GFP_KERNEL);
768 if (comm->l1_buffer == NULL) {
769 printk(KERN_ERR "tf_init():"
770 " get_zeroed_page failed for L1 shared buffer!\n");
771 error = -ENOMEM;
772 goto error;
773 }
774
775 /*
776 * Ensure the page storing the L1 shared buffer is mapped.
777 */
778 buffer_page = virt_to_page(comm->l1_buffer);
779 trylock_page(buffer_page);
780
781 dprintk(KERN_INFO "tf_init(): "
782 "L1 shared buffer allocated at virtual:%p, "
783 "physical:%p (page:%p)\n",
784 comm->l1_buffer,
785 (void *)virt_to_phys(comm->l1_buffer),
786 buffer_page);
787
788 set_bit(TF_COMM_FLAG_L1_SHARED_ALLOCATED, &(comm->flags));
789
790 /*
791 * Init SMC
792 */
793 error = tf_smc_init(
794 tf_get_l2init_descriptor((u32)comm->l1_buffer));
795 if (error != S_SUCCESS) {
796 dprintk(KERN_ERR "tf_init(): "
797 "tf_smc_init failed (error 0x%08X)!\n",
798 error);
799 goto error;
800 }
801
802 /*
803 * check whether the interrupts are actually enabled
804 * If not, remove irq handler
805 */
806 if ((tf_read_reg32(&comm->l1_buffer->config_flag_s) &
807 TF_CONFIG_FLAG_S) == 0) {
808 if (test_and_clear_bit(TF_COMM_FLAG_IRQ_REQUESTED,
809 &(comm->flags)) != 0) {
810 dprintk(KERN_INFO "tf_init(): "
811 "Interrupts not used, unregistering "
812 "softint (IRQ %d)\n",
813 comm->soft_int_irq);
814
815 free_irq(comm->soft_int_irq, comm);
816 }
817 } else {
818 if (test_bit(TF_COMM_FLAG_IRQ_REQUESTED,
819 &(comm->flags)) == 0) {
820 /*
821 * Interrupts are enabled in the Secure World, but not
822 * handled by driver
823 */
824 dprintk(KERN_ERR "tf_init(): "
825 "soft_interrupt argument not provided\n");
826 error = -EINVAL;
827 goto error;
828 }
829 }
830
831 /*
832 * Successful completion.
833 */
834
835 /* yield for the first time */
836 (void)tf_schedule_secure_world(comm);
837
838 dprintk(KERN_INFO "tf_init(): Success\n");
839 return S_SUCCESS;
840
841error:
842 /*
843 * Error handling.
844 */
845 dprintk(KERN_INFO "tf_init(): Failure (error %d)\n",
846 error);
847 tf_terminate(comm);
848 return error;
849}
850
851
852/*
853 * Attempt to terminate the communication with the Secure World.
854 * The L1 shared buffer is freed.
855 * Calling this routine terminates definitaly the communication
856 * with the Secure World : there is no way to inform the Secure World of a new
857 * L1 shared buffer to be used once it has been initialized.
858 */
859void tf_terminate(struct tf_comm *comm)
860{
861 dprintk(KERN_INFO "tf_terminate()\n");
862
863 set_bit(TF_COMM_FLAG_TERMINATING, &(comm->flags));
864
865 if ((test_bit(TF_COMM_FLAG_W3B_ALLOCATED,
866 &(comm->flags))) != 0) {
867 dprintk(KERN_INFO "tf_terminate(): "
868 "Freeing the W3B buffer...\n");
869 tf_free_w3b(comm);
870 }
871
872 if ((test_bit(TF_COMM_FLAG_L1_SHARED_ALLOCATED,
873 &(comm->flags))) != 0) {
874 __clear_page_locked(virt_to_page(comm->l1_buffer));
875 internal_free_page((unsigned long) comm->l1_buffer);
876 }
877
878 if ((test_bit(TF_COMM_FLAG_IRQ_REQUESTED,
879 &(comm->flags))) != 0) {
880 dprintk(KERN_INFO "tf_terminate(): "
881 "Unregistering softint (IRQ %d)\n",
882 comm->soft_int_irq);
883 free_irq(comm->soft_int_irq, comm);
884 }
885}
diff --git a/security/tf_driver/tf_conn.c b/security/tf_driver/tf_conn.c
new file mode 100644
index 00000000000..3148fec4635
--- /dev/null
+++ b/security/tf_driver/tf_conn.c
@@ -0,0 +1,1574 @@
1/**
2 * Copyright (c) 2011 Trusted Logic S.A.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#include <linux/atomic.h>
21#include <linux/uaccess.h>
22#include <linux/delay.h>
23#include <linux/errno.h>
24#include <linux/list.h>
25#include <linux/mm.h>
26#include <linux/pagemap.h>
27#include <linux/stddef.h>
28#include <linux/types.h>
29
30#include "s_version.h"
31
32#include "tf_protocol.h"
33#include "tf_defs.h"
34#include "tf_util.h"
35#include "tf_comm.h"
36#include "tf_conn.h"
37
38#ifdef CONFIG_TF_ZEBRA
39#include "tf_crypto.h"
40#endif
41
42#ifdef CONFIG_ANDROID
43#define TF_PRIVILEGED_UID_GID 1000 /* Android system AID */
44#else
45#define TF_PRIVILEGED_UID_GID 0
46#endif
47
48/*----------------------------------------------------------------------------
49 * Management of the shared memory blocks.
50 *
51 * Shared memory blocks are the blocks registered through
52 * the commands REGISTER_SHARED_MEMORY and POWER_MANAGEMENT
53 *----------------------------------------------------------------------------*/
54
55/**
56 * Unmaps a shared memory
57 **/
58void tf_unmap_shmem(
59 struct tf_connection *connection,
60 struct tf_shmem_desc *shmem_desc,
61 u32 full_cleanup)
62{
63 /* check shmem_desc contains a descriptor */
64 if (shmem_desc == NULL)
65 return;
66
67 dprintk(KERN_DEBUG "tf_unmap_shmem(%p)\n", shmem_desc);
68
69retry:
70 mutex_lock(&(connection->shmem_mutex));
71 if (atomic_read(&shmem_desc->ref_count) > 1) {
72 /*
73 * Shared mem still in use, wait for other operations completion
74 * before actually unmapping it.
75 */
76 dprintk(KERN_INFO "Descriptor in use\n");
77 mutex_unlock(&(connection->shmem_mutex));
78 schedule();
79 goto retry;
80 }
81
82 tf_cleanup_shared_memory(
83 &(connection->cpt_alloc_context),
84 shmem_desc,
85 full_cleanup);
86
87 list_del(&(shmem_desc->list));
88
89 if ((shmem_desc->type == TF_SHMEM_TYPE_REGISTERED_SHMEM) ||
90 (full_cleanup != 0)) {
91 internal_kfree(shmem_desc);
92
93 atomic_dec(&(connection->shmem_count));
94 } else {
95 /*
96 * This is a preallocated shared memory, add to free list
97 * Since the device context is unmapped last, it is
98 * always the first element of the free list if no
99 * device context has been created
100 */
101 shmem_desc->block_identifier = 0;
102 list_add(&(shmem_desc->list), &(connection->free_shmem_list));
103 }
104
105 mutex_unlock(&(connection->shmem_mutex));
106}
107
108
109/**
110 * Find the first available slot for a new block of shared memory
111 * and map the user buffer.
112 * Update the descriptors to L1 descriptors
113 * Update the buffer_start_offset and buffer_size fields
114 * shmem_desc is updated to the mapped shared memory descriptor
115 **/
116int tf_map_shmem(
117 struct tf_connection *connection,
118 u32 buffer,
119 /* flags for read-write access rights on the memory */
120 u32 flags,
121 bool in_user_space,
122 u32 descriptors[TF_MAX_COARSE_PAGES],
123 u32 *buffer_start_offset,
124 u32 buffer_size,
125 struct tf_shmem_desc **shmem_desc,
126 u32 *descriptor_count)
127{
128 struct tf_shmem_desc *desc = NULL;
129 int error;
130
131 dprintk(KERN_INFO "tf_map_shmem(%p, %p, flags = 0x%08x)\n",
132 connection,
133 (void *) buffer,
134 flags);
135
136 mutex_lock(&(connection->shmem_mutex));
137
138 /*
139 * Check the list of free shared memory
140 * is not empty
141 */
142 if (list_empty(&(connection->free_shmem_list))) {
143 if (atomic_read(&(connection->shmem_count)) ==
144 TF_SHMEM_MAX_COUNT) {
145 printk(KERN_ERR "tf_map_shmem(%p):"
146 " maximum shared memories already registered\n",
147 connection);
148 error = -ENOMEM;
149 goto error;
150 }
151
152 /* no descriptor available, allocate a new one */
153
154 desc = (struct tf_shmem_desc *) internal_kmalloc(
155 sizeof(*desc), GFP_KERNEL);
156 if (desc == NULL) {
157 printk(KERN_ERR "tf_map_shmem(%p):"
158 " failed to allocate descriptor\n",
159 connection);
160 error = -ENOMEM;
161 goto error;
162 }
163
164 /* Initialize the structure */
165 desc->type = TF_SHMEM_TYPE_REGISTERED_SHMEM;
166 atomic_set(&desc->ref_count, 1);
167 INIT_LIST_HEAD(&(desc->list));
168
169 atomic_inc(&(connection->shmem_count));
170 } else {
171 /* take the first free shared memory descriptor */
172 desc = list_first_entry(&(connection->free_shmem_list),
173 struct tf_shmem_desc, list);
174 list_del(&(desc->list));
175 }
176
177 /* Add the descriptor to the used list */
178 list_add(&(desc->list), &(connection->used_shmem_list));
179
180 error = tf_fill_descriptor_table(
181 &(connection->cpt_alloc_context),
182 desc,
183 buffer,
184 connection->vmas,
185 descriptors,
186 buffer_size,
187 buffer_start_offset,
188 in_user_space,
189 flags,
190 descriptor_count);
191
192 if (error != 0) {
193 dprintk(KERN_ERR "tf_map_shmem(%p):"
194 " tf_fill_descriptor_table failed with error "
195 "code %d!\n",
196 connection,
197 error);
198 goto error;
199 }
200 desc->client_buffer = (u8 *) buffer;
201
202 /*
203 * Successful completion.
204 */
205 *shmem_desc = desc;
206 mutex_unlock(&(connection->shmem_mutex));
207 dprintk(KERN_DEBUG "tf_map_shmem: success\n");
208 return 0;
209
210
211 /*
212 * Error handling.
213 */
214error:
215 mutex_unlock(&(connection->shmem_mutex));
216 dprintk(KERN_ERR "tf_map_shmem: failure with error code %d\n",
217 error);
218
219 tf_unmap_shmem(
220 connection,
221 desc,
222 0);
223
224 return error;
225}
226
227
228
229/* This function is a copy of the find_vma() function
230in linux kernel 2.6.15 version with some fixes :
231 - memory block may end on vm_end
232 - check the full memory block is in the memory area
233 - guarantee NULL is returned if no memory area is found */
234struct vm_area_struct *tf_find_vma(struct mm_struct *mm,
235 unsigned long addr, unsigned long size)
236{
237 struct vm_area_struct *vma = NULL;
238
239 dprintk(KERN_INFO
240 "tf_find_vma addr=0x%lX size=0x%lX\n", addr, size);
241
242 if (mm) {
243 /* Check the cache first. */
244 /* (Cache hit rate is typically around 35%.) */
245 vma = mm->mmap_cache;
246 if (!(vma && vma->vm_end >= (addr+size) &&
247 vma->vm_start <= addr)) {
248 struct rb_node *rb_node;
249
250 rb_node = mm->mm_rb.rb_node;
251 vma = NULL;
252
253 while (rb_node) {
254 struct vm_area_struct *vma_tmp;
255
256 vma_tmp = rb_entry(rb_node,
257 struct vm_area_struct, vm_rb);
258
259 dprintk(KERN_INFO
260 "vma_tmp->vm_start=0x%lX"
261 "vma_tmp->vm_end=0x%lX\n",
262 vma_tmp->vm_start,
263 vma_tmp->vm_end);
264
265 if (vma_tmp->vm_end >= (addr+size)) {
266 vma = vma_tmp;
267 if (vma_tmp->vm_start <= addr)
268 break;
269
270 rb_node = rb_node->rb_left;
271 } else {
272 rb_node = rb_node->rb_right;
273 }
274 }
275
276 if (vma)
277 mm->mmap_cache = vma;
278 if (rb_node == NULL)
279 vma = NULL;
280 }
281 }
282 return vma;
283}
284
285int tf_validate_shmem_and_flags(
286 u32 shmem,
287 u32 shmem_size,
288 u32 flags)
289{
290 struct vm_area_struct *vma;
291 u32 chunk;
292
293 if (shmem_size == 0)
294 /* This is always valid */
295 return 0;
296
297 if ((shmem + shmem_size) < shmem)
298 /* Overflow */
299 return -EINVAL;
300
301 down_read(&current->mm->mmap_sem);
302
303 /*
304 * When looking for a memory address, split buffer into chunks of
305 * size=PAGE_SIZE.
306 */
307 chunk = PAGE_SIZE - (shmem & (PAGE_SIZE-1));
308 if (chunk > shmem_size)
309 chunk = shmem_size;
310
311 do {
312 vma = tf_find_vma(current->mm, shmem, chunk);
313
314 if (vma == NULL) {
315 dprintk(KERN_ERR "%s: area not found\n", __func__);
316 goto error;
317 }
318
319 if (flags & TF_SHMEM_TYPE_READ)
320 if (!(vma->vm_flags & VM_READ)) {
321 dprintk(KERN_ERR "%s: no read permission\n",
322 __func__);
323 goto error;
324 }
325 if (flags & TF_SHMEM_TYPE_WRITE)
326 if (!(vma->vm_flags & VM_WRITE)) {
327 dprintk(KERN_ERR "%s: no write permission\n",
328 __func__);
329 goto error;
330 }
331
332 shmem_size -= chunk;
333 shmem += chunk;
334 chunk = (shmem_size <= PAGE_SIZE ?
335 shmem_size : PAGE_SIZE);
336 } while (shmem_size != 0);
337
338 up_read(&current->mm->mmap_sem);
339 return 0;
340
341error:
342 up_read(&current->mm->mmap_sem);
343 return -EFAULT;
344}
345
346
347static int tf_map_temp_shmem(struct tf_connection *connection,
348 struct tf_command_param_temp_memref *temp_memref,
349 u32 param_type,
350 struct tf_shmem_desc **shmem_desc)
351{
352 u32 flags;
353 u32 error = S_SUCCESS;
354 bool in_user_space = connection->owner != TF_CONNECTION_OWNER_KERNEL;
355
356 dprintk(KERN_INFO "tf_map_temp_shmem(%p, "
357 "0x%08x[size=0x%08x], offset=0x%08x)\n",
358 connection,
359 temp_memref->descriptor,
360 temp_memref->size,
361 temp_memref->offset);
362
363 switch (param_type) {
364 case TF_PARAM_TYPE_MEMREF_TEMP_INPUT:
365 flags = TF_SHMEM_TYPE_READ;
366 break;
367 case TF_PARAM_TYPE_MEMREF_TEMP_OUTPUT:
368 flags = TF_SHMEM_TYPE_WRITE;
369 break;
370 case TF_PARAM_TYPE_MEMREF_TEMP_INOUT:
371 flags = TF_SHMEM_TYPE_WRITE | TF_SHMEM_TYPE_READ;
372 break;
373 default:
374 error = -EINVAL;
375 goto error;
376 }
377
378 if (temp_memref->descriptor == 0) {
379 /* NULL tmpref */
380 temp_memref->offset = 0;
381 *shmem_desc = NULL;
382 } else if ((temp_memref->descriptor != 0) &&
383 (temp_memref->size == 0)) {
384 /* Empty tmpref */
385 temp_memref->offset = temp_memref->descriptor;
386 temp_memref->descriptor = 0;
387 temp_memref->size = 0;
388 *shmem_desc = NULL;
389 } else {
390 /* Map the temp shmem block */
391
392 u32 shared_mem_descriptors[TF_MAX_COARSE_PAGES];
393 u32 descriptor_count;
394
395 if (in_user_space) {
396 error = tf_validate_shmem_and_flags(
397 temp_memref->descriptor,
398 temp_memref->size,
399 flags);
400 if (error != 0)
401 goto error;
402 }
403
404 error = tf_map_shmem(
405 connection,
406 temp_memref->descriptor,
407 flags,
408 in_user_space,
409 shared_mem_descriptors,
410 &(temp_memref->offset),
411 temp_memref->size,
412 shmem_desc,
413 &descriptor_count);
414 temp_memref->descriptor = shared_mem_descriptors[0];
415 }
416
417error:
418 return error;
419}
420
421/*
422 * Clean up a list of shared memory descriptors.
423 */
424static void tf_shared_memory_cleanup_list(
425 struct tf_connection *connection,
426 struct list_head *shmem_desc_list)
427{
428 while (!list_empty(shmem_desc_list)) {
429 struct tf_shmem_desc *shmem_desc;
430
431 shmem_desc = list_first_entry(shmem_desc_list,
432 struct tf_shmem_desc, list);
433
434 tf_unmap_shmem(connection, shmem_desc, 1);
435 }
436}
437
438
439/*
440 * Clean up the shared memory information in the connection.
441 * Releases all allocated pages.
442 */
443static void tf_cleanup_shared_memories(struct tf_connection *connection)
444{
445 /* clean up the list of used and free descriptors.
446 * done outside the mutex, because tf_unmap_shmem already
447 * mutex()ed
448 */
449 tf_shared_memory_cleanup_list(connection,
450 &connection->used_shmem_list);
451 tf_shared_memory_cleanup_list(connection,
452 &connection->free_shmem_list);
453
454 mutex_lock(&(connection->shmem_mutex));
455
456 /* Free the Vmas page */
457 if (connection->vmas) {
458 internal_free_page((unsigned long) connection->vmas);
459 connection->vmas = NULL;
460 }
461
462 tf_release_coarse_page_table_allocator(
463 &(connection->cpt_alloc_context));
464
465 mutex_unlock(&(connection->shmem_mutex));
466}
467
468
469/*
470 * Initialize the shared memory in a connection.
471 * Allocates the minimum memory to be provided
472 * for shared memory management
473 */
474int tf_init_shared_memory(struct tf_connection *connection)
475{
476 int error;
477 int i;
478 int coarse_page_index;
479
480 /*
481 * We only need to initialize special elements and attempt to allocate
482 * the minimum shared memory descriptors we want to support
483 */
484
485 mutex_init(&(connection->shmem_mutex));
486 INIT_LIST_HEAD(&(connection->free_shmem_list));
487 INIT_LIST_HEAD(&(connection->used_shmem_list));
488 atomic_set(&(connection->shmem_count), 0);
489
490 tf_init_coarse_page_table_allocator(
491 &(connection->cpt_alloc_context));
492
493
494 /*
495 * Preallocate 3 pages to increase the chances that a connection
496 * succeeds in allocating shared mem
497 */
498 for (i = 0;
499 i < 3;
500 i++) {
501 struct tf_shmem_desc *shmem_desc =
502 (struct tf_shmem_desc *) internal_kmalloc(
503 sizeof(*shmem_desc), GFP_KERNEL);
504
505 if (shmem_desc == NULL) {
506 printk(KERN_ERR "tf_init_shared_memory(%p):"
507 " failed to pre allocate descriptor %d\n",
508 connection,
509 i);
510 error = -ENOMEM;
511 goto error;
512 }
513
514 for (coarse_page_index = 0;
515 coarse_page_index < TF_MAX_COARSE_PAGES;
516 coarse_page_index++) {
517 struct tf_coarse_page_table *coarse_pg_table;
518
519 coarse_pg_table = tf_alloc_coarse_page_table(
520 &(connection->cpt_alloc_context),
521 TF_PAGE_DESCRIPTOR_TYPE_PREALLOCATED);
522
523 if (coarse_pg_table == NULL) {
524 printk(KERN_ERR "tf_init_shared_memory(%p)"
525 ": descriptor %d coarse page %d - "
526 "tf_alloc_coarse_page_table() "
527 "failed\n",
528 connection,
529 i,
530 coarse_page_index);
531 error = -ENOMEM;
532 goto error;
533 }
534
535 shmem_desc->coarse_pg_table[coarse_page_index] =
536 coarse_pg_table;
537 }
538 shmem_desc->coarse_pg_table_count = 0;
539
540 shmem_desc->type = TF_SHMEM_TYPE_PREALLOC_REGISTERED_SHMEM;
541 atomic_set(&shmem_desc->ref_count, 1);
542
543 /*
544 * add this preallocated descriptor to the list of free
545 * descriptors Keep the device context specific one at the
546 * beginning of the list
547 */
548 INIT_LIST_HEAD(&(shmem_desc->list));
549 list_add_tail(&(shmem_desc->list),
550 &(connection->free_shmem_list));
551 }
552
553 /* allocate memory for the vmas structure */
554 connection->vmas =
555 (struct vm_area_struct **) internal_get_zeroed_page(GFP_KERNEL);
556 if (connection->vmas == NULL) {
557 printk(KERN_ERR "tf_init_shared_memory(%p):"
558 " vmas - failed to get_zeroed_page\n",
559 connection);
560 error = -ENOMEM;
561 goto error;
562 }
563
564 return 0;
565
566error:
567 tf_cleanup_shared_memories(connection);
568 return error;
569}
570
571/*----------------------------------------------------------------------------
572 * Connection operations to the Secure World
573 *----------------------------------------------------------------------------*/
574
575int tf_create_device_context(
576 struct tf_connection *connection)
577{
578 union tf_command command;
579 union tf_answer answer;
580 int error = 0;
581
582 dprintk(KERN_INFO "tf_create_device_context(%p)\n",
583 connection);
584
585 command.create_device_context.message_type =
586 TF_MESSAGE_TYPE_CREATE_DEVICE_CONTEXT;
587 command.create_device_context.message_size =
588 (sizeof(struct tf_command_create_device_context)
589 - sizeof(struct tf_command_header))/sizeof(u32);
590 command.create_device_context.operation_id = (u32) &answer;
591 command.create_device_context.device_context_id = (u32) connection;
592
593 error = tf_send_receive(
594 &connection->dev->sm,
595 &command,
596 &answer,
597 connection,
598 true);
599
600 if ((error != 0) ||
601 (answer.create_device_context.error_code != S_SUCCESS))
602 goto error;
603
604 /*
605 * CREATE_DEVICE_CONTEXT succeeded,
606 * store device context handler and update connection status
607 */
608 connection->device_context =
609 answer.create_device_context.device_context;
610 spin_lock(&(connection->state_lock));
611 connection->state = TF_CONN_STATE_VALID_DEVICE_CONTEXT;
612 spin_unlock(&(connection->state_lock));
613
614 /* successful completion */
615 dprintk(KERN_INFO "tf_create_device_context(%p):"
616 " device_context=0x%08x\n",
617 connection,
618 answer.create_device_context.device_context);
619 return 0;
620
621error:
622 if (error != 0) {
623 dprintk(KERN_ERR "tf_create_device_context failed with "
624 "error %d\n", error);
625 } else {
626 /*
627 * We sent a DeviceCreateContext. The state is now
628 * TF_CONN_STATE_CREATE_DEVICE_CONTEXT_SENT It has to be
629 * reset if we ever want to send a DeviceCreateContext again
630 */
631 spin_lock(&(connection->state_lock));
632 connection->state = TF_CONN_STATE_NO_DEVICE_CONTEXT;
633 spin_unlock(&(connection->state_lock));
634 dprintk(KERN_ERR "tf_create_device_context failed with "
635 "error_code 0x%08X\n",
636 answer.create_device_context.error_code);
637 if (answer.create_device_context.error_code ==
638 S_ERROR_OUT_OF_MEMORY)
639 error = -ENOMEM;
640 else
641 error = -EFAULT;
642 }
643
644 return error;
645}
646
647/* Check that the current application belongs to the
648 * requested GID */
649static bool tf_check_gid(gid_t requested_gid)
650{
651 if (requested_gid == current_egid()) {
652 return true;
653 } else {
654 u32 size;
655 u32 i;
656 /* Look in the supplementary GIDs */
657 get_group_info(GROUP_INFO);
658 size = GROUP_INFO->ngroups;
659 for (i = 0; i < size; i++)
660 if (requested_gid == GROUP_AT(GROUP_INFO , i))
661 return true;
662 }
663 return false;
664}
665
666/*
667 * Opens a client session to the Secure World
668 */
669int tf_open_client_session(
670 struct tf_connection *connection,
671 union tf_command *command,
672 union tf_answer *answer)
673{
674 int error = 0;
675 struct tf_shmem_desc *shmem_desc[4] = {NULL};
676 u32 i;
677
678 dprintk(KERN_INFO "tf_open_client_session(%p)\n", connection);
679
680 /*
681 * Initialize the message size with no login data. This will be later
682 * adjusted the the cases below
683 */
684 command->open_client_session.message_size =
685 (sizeof(struct tf_command_open_client_session) - 20
686 - sizeof(struct tf_command_header))/4;
687
688 switch (command->open_client_session.login_type) {
689 case TF_LOGIN_PUBLIC:
690 /* Nothing to do */
691 break;
692
693 case TF_LOGIN_USER:
694 /*
695 * Send the EUID of the calling application in the login data.
696 * Update message size.
697 */
698 *(u32 *) &command->open_client_session.login_data =
699 current_euid();
700#ifndef CONFIG_ANDROID
701 command->open_client_session.login_type =
702 (u32) TF_LOGIN_USER_LINUX_EUID;
703#else
704 command->open_client_session.login_type =
705 (u32) TF_LOGIN_USER_ANDROID_EUID;
706#endif
707
708 /* Added one word */
709 command->open_client_session.message_size += 1;
710 break;
711
712 case TF_LOGIN_GROUP: {
713 /* Check requested GID */
714 gid_t requested_gid =
715 *(u32 *) command->open_client_session.login_data;
716
717 if (!tf_check_gid(requested_gid)) {
718 dprintk(KERN_ERR "tf_open_client_session(%p) "
719 "TF_LOGIN_GROUP: requested GID (0x%x) does "
720 "not match real eGID (0x%x)"
721 "or any of the supplementary GIDs\n",
722 connection, requested_gid, current_egid());
723 error = -EACCES;
724 goto error;
725 }
726#ifndef CONFIG_ANDROID
727 command->open_client_session.login_type =
728 TF_LOGIN_GROUP_LINUX_GID;
729#else
730 command->open_client_session.login_type =
731 TF_LOGIN_GROUP_ANDROID_GID;
732#endif
733
734 command->open_client_session.message_size += 1; /* GID */
735 break;
736 }
737
738#ifndef CONFIG_ANDROID
739 case TF_LOGIN_APPLICATION: {
740 /*
741 * Compute SHA-1 hash of the application fully-qualified path
742 * name. Truncate the hash to 16 bytes and send it as login
743 * data. Update message size.
744 */
745 u8 pSHA1Hash[SHA1_DIGEST_SIZE];
746
747 error = tf_hash_application_path_and_data(pSHA1Hash,
748 NULL, 0);
749 if (error != 0) {
750 dprintk(KERN_ERR "tf_open_client_session: "
751 "error in tf_hash_application_path_and_data\n");
752 goto error;
753 }
754 memcpy(&command->open_client_session.login_data,
755 pSHA1Hash, 16);
756 command->open_client_session.login_type =
757 TF_LOGIN_APPLICATION_LINUX_PATH_SHA1_HASH;
758 /* 16 bytes */
759 command->open_client_session.message_size += 4;
760 break;
761 }
762#else
763 case TF_LOGIN_APPLICATION:
764 /*
765 * Send the real UID of the calling application in the login
766 * data. Update message size.
767 */
768 *(u32 *) &command->open_client_session.login_data =
769 current_uid();
770
771 command->open_client_session.login_type =
772 (u32) TF_LOGIN_APPLICATION_ANDROID_UID;
773
774 /* Added one word */
775 command->open_client_session.message_size += 1;
776 break;
777#endif
778
779#ifndef CONFIG_ANDROID
780 case TF_LOGIN_APPLICATION_USER: {
781 /*
782 * Compute SHA-1 hash of the concatenation of the application
783 * fully-qualified path name and the EUID of the calling
784 * application. Truncate the hash to 16 bytes and send it as
785 * login data. Update message size.
786 */
787 u8 pSHA1Hash[SHA1_DIGEST_SIZE];
788
789 error = tf_hash_application_path_and_data(pSHA1Hash,
790 (u8 *) &(current_euid()), sizeof(current_euid()));
791 if (error != 0) {
792 dprintk(KERN_ERR "tf_open_client_session: "
793 "error in tf_hash_application_path_and_data\n");
794 goto error;
795 }
796 memcpy(&command->open_client_session.login_data,
797 pSHA1Hash, 16);
798 command->open_client_session.login_type =
799 TF_LOGIN_APPLICATION_USER_LINUX_PATH_EUID_SHA1_HASH;
800
801 /* 16 bytes */
802 command->open_client_session.message_size += 4;
803
804 break;
805 }
806#else
807 case TF_LOGIN_APPLICATION_USER:
808 /*
809 * Send the real UID and the EUID of the calling application in
810 * the login data. Update message size.
811 */
812 *(u32 *) &command->open_client_session.login_data =
813 current_uid();
814 *(u32 *) &command->open_client_session.login_data[4] =
815 current_euid();
816
817 command->open_client_session.login_type =
818 TF_LOGIN_APPLICATION_USER_ANDROID_UID_EUID;
819
820 /* Added two words */
821 command->open_client_session.message_size += 2;
822 break;
823#endif
824
825#ifndef CONFIG_ANDROID
826 case TF_LOGIN_APPLICATION_GROUP: {
827 /*
828 * Check requested GID. Compute SHA-1 hash of the concatenation
829 * of the application fully-qualified path name and the
830 * requested GID. Update message size
831 */
832 gid_t requested_gid;
833 u8 pSHA1Hash[SHA1_DIGEST_SIZE];
834
835 requested_gid = *(u32 *) &command->open_client_session.
836 login_data;
837
838 if (!tf_check_gid(requested_gid)) {
839 dprintk(KERN_ERR "tf_open_client_session(%p) "
840 "TF_LOGIN_APPLICATION_GROUP: requested GID (0x%x) "
841 "does not match real eGID (0x%x)"
842 "or any of the supplementary GIDs\n",
843 connection, requested_gid, current_egid());
844 error = -EACCES;
845 goto error;
846 }
847
848 error = tf_hash_application_path_and_data(pSHA1Hash,
849 &requested_gid, sizeof(u32));
850 if (error != 0) {
851 dprintk(KERN_ERR "tf_open_client_session: "
852 "error in tf_hash_application_path_and_data\n");
853 goto error;
854 }
855
856 memcpy(&command->open_client_session.login_data,
857 pSHA1Hash, 16);
858 command->open_client_session.login_type =
859 TF_LOGIN_APPLICATION_GROUP_LINUX_PATH_GID_SHA1_HASH;
860
861 /* 16 bytes */
862 command->open_client_session.message_size += 4;
863 break;
864 }
865#else
866 case TF_LOGIN_APPLICATION_GROUP: {
867 /*
868 * Check requested GID. Send the real UID and the requested GID
869 * in the login data. Update message size.
870 */
871 gid_t requested_gid;
872
873 requested_gid = *(u32 *) &command->open_client_session.
874 login_data;
875
876 if (!tf_check_gid(requested_gid)) {
877 dprintk(KERN_ERR "tf_open_client_session(%p) "
878 "TF_LOGIN_APPLICATION_GROUP: requested GID (0x%x) "
879 "does not match real eGID (0x%x)"
880 "or any of the supplementary GIDs\n",
881 connection, requested_gid, current_egid());
882 error = -EACCES;
883 goto error;
884 }
885
886 *(u32 *) &command->open_client_session.login_data =
887 current_uid();
888 *(u32 *) &command->open_client_session.login_data[4] =
889 requested_gid;
890
891 command->open_client_session.login_type =
892 TF_LOGIN_APPLICATION_GROUP_ANDROID_UID_GID;
893
894 /* Added two words */
895 command->open_client_session.message_size += 2;
896
897 break;
898 }
899#endif
900
901 case TF_LOGIN_PRIVILEGED:
902 /* A privileged login may be performed only on behalf of the
903 kernel itself or on behalf of a process with euid=0 or
904 egid=0 or euid=system or egid=system. */
905 if (connection->owner == TF_CONNECTION_OWNER_KERNEL) {
906 dprintk(KERN_DEBUG "tf_open_client_session: "
907 "TF_LOGIN_PRIVILEGED for kernel API\n");
908 } else if ((current_euid() != TF_PRIVILEGED_UID_GID) &&
909 (current_egid() != TF_PRIVILEGED_UID_GID) &&
910 (current_euid() != 0) && (current_egid() != 0)) {
911 dprintk(KERN_ERR "tf_open_client_session: "
912 " user %d, group %d not allowed to open "
913 "session with TF_LOGIN_PRIVILEGED\n",
914 current_euid(), current_egid());
915 error = -EACCES;
916 goto error;
917 } else {
918 dprintk(KERN_DEBUG "tf_open_client_session: "
919 "TF_LOGIN_PRIVILEGED for %u:%u\n",
920 current_euid(), current_egid());
921 }
922 command->open_client_session.login_type =
923 TF_LOGIN_PRIVILEGED;
924 break;
925
926 case TF_LOGIN_AUTHENTICATION: {
927 /*
928 * Compute SHA-1 hash of the application binary
929 * Send this hash as the login data (20 bytes)
930 */
931
932 u8 *hash;
933 hash = &(command->open_client_session.login_data[0]);
934
935 error = tf_get_current_process_hash(hash);
936 if (error != 0) {
937 dprintk(KERN_ERR "tf_open_client_session: "
938 "error in tf_get_current_process_hash\n");
939 goto error;
940 }
941 command->open_client_session.login_type =
942 TF_LOGIN_AUTHENTICATION_BINARY_SHA1_HASH;
943
944 /* 20 bytes */
945 command->open_client_session.message_size += 5;
946 break;
947 }
948
949 case TF_LOGIN_PRIVILEGED_KERNEL:
950 /* A kernel login may be performed only on behalf of the
951 kernel itself. */
952 if (connection->owner == TF_CONNECTION_OWNER_KERNEL) {
953 dprintk(KERN_DEBUG "tf_open_client_session: "
954 "TF_LOGIN_PRIVILEGED_KERNEL for kernel API\n");
955 command->open_client_session.login_type =
956 TF_LOGIN_PRIVILEGED_KERNEL;
957 } else {
958 dprintk(KERN_ERR "tf_open_client_session: "
959 " user %d, group %d not allowed to open "
960 "session with TF_LOGIN_PRIVILEGED_KERNEL\n",
961 current_euid(), current_egid());
962 error = -EACCES;
963 goto error;
964 }
965 command->open_client_session.login_type =
966 TF_LOGIN_PRIVILEGED_KERNEL;
967 break;
968
969 default:
970 dprintk(KERN_ERR "tf_open_client_session: "
971 "unknown login_type(%08X)\n",
972 command->open_client_session.login_type);
973 error = -EOPNOTSUPP;
974 goto error;
975 }
976
977 /* Map the temporary memory references */
978 for (i = 0; i < 4; i++) {
979 int param_type;
980 param_type = TF_GET_PARAM_TYPE(
981 command->open_client_session.param_types, i);
982 if ((param_type & (TF_PARAM_TYPE_MEMREF_FLAG |
983 TF_PARAM_TYPE_REGISTERED_MEMREF_FLAG))
984 == TF_PARAM_TYPE_MEMREF_FLAG) {
985 /* Map temp mem ref */
986 error = tf_map_temp_shmem(connection,
987 &command->open_client_session.
988 params[i].temp_memref,
989 param_type,
990 &shmem_desc[i]);
991 if (error != 0) {
992 dprintk(KERN_ERR "tf_open_client_session: "
993 "unable to map temporary memory block "
994 "(%08X)\n", error);
995 goto error;
996 }
997 }
998 }
999
1000 /* Fill the handle of the Device Context */
1001 command->open_client_session.device_context =
1002 connection->device_context;
1003
1004 error = tf_send_receive(
1005 &connection->dev->sm,
1006 command,
1007 answer,
1008 connection,
1009 true);
1010
1011error:
1012 /* Unmap the temporary memory references */
1013 for (i = 0; i < 4; i++)
1014 if (shmem_desc[i] != NULL)
1015 tf_unmap_shmem(connection, shmem_desc[i], 0);
1016
1017 if (error != 0)
1018 dprintk(KERN_ERR "tf_open_client_session returns %d\n",
1019 error);
1020 else
1021 dprintk(KERN_ERR "tf_open_client_session returns "
1022 "error_code 0x%08X\n",
1023 answer->open_client_session.error_code);
1024
1025 return error;
1026}
1027
1028
1029/*
1030 * Closes a client session from the Secure World
1031 */
1032int tf_close_client_session(
1033 struct tf_connection *connection,
1034 union tf_command *command,
1035 union tf_answer *answer)
1036{
1037 int error = 0;
1038
1039 dprintk(KERN_DEBUG "tf_close_client_session(%p)\n", connection);
1040
1041 command->close_client_session.message_size =
1042 (sizeof(struct tf_command_close_client_session) -
1043 sizeof(struct tf_command_header)) / 4;
1044 command->close_client_session.device_context =
1045 connection->device_context;
1046
1047 error = tf_send_receive(
1048 &connection->dev->sm,
1049 command,
1050 answer,
1051 connection,
1052 true);
1053
1054 if (error != 0)
1055 dprintk(KERN_ERR "tf_close_client_session returns %d\n",
1056 error);
1057 else
1058 dprintk(KERN_ERR "tf_close_client_session returns "
1059 "error 0x%08X\n",
1060 answer->close_client_session.error_code);
1061
1062 return error;
1063}
1064
1065
1066/*
1067 * Registers a shared memory to the Secure World
1068 */
1069int tf_register_shared_memory(
1070 struct tf_connection *connection,
1071 union tf_command *command,
1072 union tf_answer *answer)
1073{
1074 int error = 0;
1075 struct tf_shmem_desc *shmem_desc = NULL;
1076 bool in_user_space = connection->owner != TF_CONNECTION_OWNER_KERNEL;
1077 struct tf_command_register_shared_memory *msg =
1078 &command->register_shared_memory;
1079
1080 dprintk(KERN_INFO "tf_register_shared_memory(%p) "
1081 "%p[0x%08X][0x%08x]\n",
1082 connection,
1083 (void *)msg->shared_mem_descriptors[0],
1084 msg->shared_mem_size,
1085 (u32)msg->memory_flags);
1086
1087 if (in_user_space) {
1088 error = tf_validate_shmem_and_flags(
1089 msg->shared_mem_descriptors[0],
1090 msg->shared_mem_size,
1091 (u32)msg->memory_flags);
1092 if (error != 0)
1093 goto error;
1094 }
1095
1096 /* Initialize message_size with no descriptors */
1097 msg->message_size
1098 = (offsetof(struct tf_command_register_shared_memory,
1099 shared_mem_descriptors) -
1100 sizeof(struct tf_command_header)) / 4;
1101
1102 /* Map the shmem block and update the message */
1103 if (msg->shared_mem_size == 0) {
1104 /* Empty shared mem */
1105 msg->shared_mem_start_offset = msg->shared_mem_descriptors[0];
1106 } else {
1107 u32 descriptor_count;
1108 error = tf_map_shmem(
1109 connection,
1110 msg->shared_mem_descriptors[0],
1111 msg->memory_flags,
1112 in_user_space,
1113 msg->shared_mem_descriptors,
1114 &(msg->shared_mem_start_offset),
1115 msg->shared_mem_size,
1116 &shmem_desc,
1117 &descriptor_count);
1118 if (error != 0) {
1119 dprintk(KERN_ERR "tf_register_shared_memory: "
1120 "unable to map shared memory block\n");
1121 goto error;
1122 }
1123 msg->message_size += descriptor_count;
1124 }
1125
1126 /*
1127 * write the correct device context handle and the address of the shared
1128 * memory descriptor in the message
1129 */
1130 msg->device_context = connection->device_context;
1131 msg->block_id = (u32)shmem_desc;
1132
1133 /* Send the updated message */
1134 error = tf_send_receive(
1135 &connection->dev->sm,
1136 command,
1137 answer,
1138 connection,
1139 true);
1140
1141 if ((error != 0) ||
1142 (answer->register_shared_memory.error_code
1143 != S_SUCCESS)) {
1144 dprintk(KERN_ERR "tf_register_shared_memory: "
1145 "operation failed. Unmap block\n");
1146 goto error;
1147 }
1148
1149 /* Saves the block handle returned by the secure world */
1150 if (shmem_desc != NULL)
1151 shmem_desc->block_identifier =
1152 answer->register_shared_memory.block;
1153
1154 /* successful completion */
1155 dprintk(KERN_INFO "tf_register_shared_memory(%p):"
1156 " block_id=0x%08x block=0x%08x\n",
1157 connection, msg->block_id,
1158 answer->register_shared_memory.block);
1159 return 0;
1160
1161 /* error completion */
1162error:
1163 tf_unmap_shmem(
1164 connection,
1165 shmem_desc,
1166 0);
1167
1168 if (error != 0)
1169 dprintk(KERN_ERR "tf_register_shared_memory returns %d\n",
1170 error);
1171 else
1172 dprintk(KERN_ERR "tf_register_shared_memory returns "
1173 "error_code 0x%08X\n",
1174 answer->register_shared_memory.error_code);
1175
1176 return error;
1177}
1178
1179
1180/*
1181 * Releases a shared memory from the Secure World
1182 */
1183int tf_release_shared_memory(
1184 struct tf_connection *connection,
1185 union tf_command *command,
1186 union tf_answer *answer)
1187{
1188 int error = 0;
1189
1190 dprintk(KERN_DEBUG "tf_release_shared_memory(%p)\n", connection);
1191
1192 command->release_shared_memory.message_size =
1193 (sizeof(struct tf_command_release_shared_memory) -
1194 sizeof(struct tf_command_header)) / 4;
1195 command->release_shared_memory.device_context =
1196 connection->device_context;
1197
1198 error = tf_send_receive(
1199 &connection->dev->sm,
1200 command,
1201 answer,
1202 connection,
1203 true);
1204
1205 if ((error != 0) ||
1206 (answer->release_shared_memory.error_code != S_SUCCESS))
1207 goto error;
1208
1209 /* Use block_id to get back the pointer to shmem_desc */
1210 tf_unmap_shmem(
1211 connection,
1212 (struct tf_shmem_desc *)
1213 answer->release_shared_memory.block_id,
1214 0);
1215
1216 /* successful completion */
1217 dprintk(KERN_INFO "tf_release_shared_memory(%p):"
1218 " block_id=0x%08x block=0x%08x\n",
1219 connection, answer->release_shared_memory.block_id,
1220 command->release_shared_memory.block);
1221 return 0;
1222
1223
1224error:
1225 if (error != 0)
1226 dprintk(KERN_ERR "tf_release_shared_memory returns %d\n",
1227 error);
1228 else
1229 dprintk(KERN_ERR "tf_release_shared_memory returns "
1230 "nChannelStatus 0x%08X\n",
1231 answer->release_shared_memory.error_code);
1232
1233 return error;
1234
1235}
1236
1237
1238/*
1239 * Invokes a client command to the Secure World
1240 */
1241int tf_invoke_client_command(
1242 struct tf_connection *connection,
1243 union tf_command *command,
1244 union tf_answer *answer)
1245{
1246 int error = 0;
1247 struct tf_shmem_desc *shmem_desc[4] = {NULL};
1248 int i;
1249
1250 dprintk(KERN_INFO "tf_invoke_client_command(%p)\n", connection);
1251
1252 command->release_shared_memory.message_size =
1253 (sizeof(struct tf_command_invoke_client_command) -
1254 sizeof(struct tf_command_header)) / 4;
1255
1256#ifdef CONFIG_TF_ZEBRA
1257 error = tf_crypto_try_shortcuted_update(connection,
1258 (struct tf_command_invoke_client_command *) command,
1259 (struct tf_answer_invoke_client_command *) answer);
1260 if (error == 0)
1261 return error;
1262#endif
1263
1264 /* Map the tmprefs */
1265 for (i = 0; i < 4; i++) {
1266 int param_type = TF_GET_PARAM_TYPE(
1267 command->invoke_client_command.param_types, i);
1268 if ((param_type & (TF_PARAM_TYPE_MEMREF_FLAG |
1269 TF_PARAM_TYPE_REGISTERED_MEMREF_FLAG))
1270 == TF_PARAM_TYPE_MEMREF_FLAG) {
1271 /* A temporary memref: map it */
1272 error = tf_map_temp_shmem(connection,
1273 &command->invoke_client_command.
1274 params[i].temp_memref,
1275 param_type, &shmem_desc[i]);
1276 if (error != 0) {
1277 dprintk(KERN_ERR
1278 "tf_invoke_client_command: "
1279 "unable to map temporary memory "
1280 "block\n (%08X)", error);
1281 goto error;
1282 }
1283 }
1284 }
1285
1286 command->invoke_client_command.device_context =
1287 connection->device_context;
1288
1289 error = tf_send_receive(&connection->dev->sm, command,
1290 answer, connection, true);
1291
1292error:
1293 /* Unmap de temp mem refs */
1294 for (i = 0; i < 4; i++) {
1295 if (shmem_desc[i] != NULL) {
1296 dprintk(KERN_INFO "tf_invoke_client_command: "
1297 "UnMatemp_memref %d\n ", i);
1298 tf_unmap_shmem(connection, shmem_desc[i], 0);
1299 }
1300 }
1301
1302 if (error != 0)
1303 dprintk(KERN_ERR "tf_invoke_client_command returns %d\n",
1304 error);
1305 else
1306 dprintk(KERN_ERR "tf_invoke_client_command returns "
1307 "error_code 0x%08X\n",
1308 answer->invoke_client_command.error_code);
1309
1310 return error;
1311}
1312
1313
1314/*
1315 * Cancels a client command from the Secure World
1316 */
1317int tf_cancel_client_command(
1318 struct tf_connection *connection,
1319 union tf_command *command,
1320 union tf_answer *answer)
1321{
1322 int error = 0;
1323
1324 dprintk(KERN_DEBUG "tf_cancel_client_command(%p)\n", connection);
1325
1326 command->cancel_client_operation.device_context =
1327 connection->device_context;
1328 command->cancel_client_operation.message_size =
1329 (sizeof(struct tf_command_cancel_client_operation) -
1330 sizeof(struct tf_command_header)) / 4;
1331
1332 error = tf_send_receive(
1333 &connection->dev->sm,
1334 command,
1335 answer,
1336 connection,
1337 true);
1338
1339 if ((error != 0) ||
1340 (answer->cancel_client_operation.error_code != S_SUCCESS))
1341 goto error;
1342
1343
1344 /* successful completion */
1345 return 0;
1346
1347error:
1348 if (error != 0)
1349 dprintk(KERN_ERR "tf_cancel_client_command returns %d\n",
1350 error);
1351 else
1352 dprintk(KERN_ERR "tf_cancel_client_command returns "
1353 "nChannelStatus 0x%08X\n",
1354 answer->cancel_client_operation.error_code);
1355
1356 return error;
1357}
1358
1359
1360
1361/*
1362 * Destroys a device context from the Secure World
1363 */
1364int tf_destroy_device_context(
1365 struct tf_connection *connection)
1366{
1367 int error;
1368 /*
1369 * AFY: better use the specialized tf_command_destroy_device_context
1370 * structure: this will save stack
1371 */
1372 union tf_command command;
1373 union tf_answer answer;
1374
1375 dprintk(KERN_INFO "tf_destroy_device_context(%p)\n", connection);
1376
1377 BUG_ON(connection == NULL);
1378
1379 command.header.message_type = TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT;
1380 command.header.message_size =
1381 (sizeof(struct tf_command_destroy_device_context) -
1382 sizeof(struct tf_command_header))/sizeof(u32);
1383
1384 /*
1385 * fill in the device context handler
1386 * it is guarantied that the first shared memory descriptor describes
1387 * the device context
1388 */
1389 command.destroy_device_context.device_context =
1390 connection->device_context;
1391
1392 error = tf_send_receive(
1393 &connection->dev->sm,
1394 &command,
1395 &answer,
1396 connection,
1397 false);
1398
1399 if ((error != 0) ||
1400 (answer.destroy_device_context.error_code != S_SUCCESS))
1401 goto error;
1402
1403 spin_lock(&(connection->state_lock));
1404 connection->state = TF_CONN_STATE_NO_DEVICE_CONTEXT;
1405 spin_unlock(&(connection->state_lock));
1406
1407 /* successful completion */
1408 dprintk(KERN_INFO "tf_destroy_device_context(%p)\n",
1409 connection);
1410 return 0;
1411
1412error:
1413 if (error != 0) {
1414 dprintk(KERN_ERR "tf_destroy_device_context failed with "
1415 "error %d\n", error);
1416 } else {
1417 dprintk(KERN_ERR "tf_destroy_device_context failed with "
1418 "error_code 0x%08X\n",
1419 answer.destroy_device_context.error_code);
1420 if (answer.destroy_device_context.error_code ==
1421 S_ERROR_OUT_OF_MEMORY)
1422 error = -ENOMEM;
1423 else
1424 error = -EFAULT;
1425 }
1426
1427 return error;
1428}
1429
1430
1431/*----------------------------------------------------------------------------
1432 * Connection initialization and cleanup operations
1433 *----------------------------------------------------------------------------*/
1434
1435/*
1436 * Opens a connection to the specified device.
1437 *
1438 * The placeholder referenced by connection is set to the address of the
1439 * new connection; it is set to NULL upon failure.
1440 *
1441 * Returns zero upon successful completion, or an appropriate error code upon
1442 * failure.
1443 */
1444int tf_open(struct tf_device *dev,
1445 struct file *file,
1446 struct tf_connection **connection)
1447{
1448 int error;
1449 struct tf_connection *conn = NULL;
1450
1451 dprintk(KERN_INFO "tf_open(%p, %p)\n", file, connection);
1452
1453 /*
1454 * Allocate and initialize the conn.
1455 * kmalloc only allocates sizeof(*conn) virtual memory
1456 */
1457 conn = (struct tf_connection *) internal_kmalloc(sizeof(*conn),
1458 GFP_KERNEL);
1459 if (conn == NULL) {
1460 printk(KERN_ERR "tf_open(): "
1461 "Out of memory for conn!\n");
1462 error = -ENOMEM;
1463 goto error;
1464 }
1465
1466 memset(conn, 0, sizeof(*conn));
1467
1468 conn->state = TF_CONN_STATE_NO_DEVICE_CONTEXT;
1469 conn->dev = dev;
1470 spin_lock_init(&(conn->state_lock));
1471 atomic_set(&(conn->pending_op_count), 0);
1472 INIT_LIST_HEAD(&(conn->list));
1473
1474 /*
1475 * Initialize the shared memory
1476 */
1477 error = tf_init_shared_memory(conn);
1478 if (error != 0)
1479 goto error;
1480
1481#ifdef CONFIG_TF_ZEBRA
1482 /*
1483 * Initialize CUS specifics
1484 */
1485 tf_crypto_init_cus(conn);
1486#endif
1487
1488 /*
1489 * Attach the conn to the device.
1490 */
1491 spin_lock(&(dev->connection_list_lock));
1492 list_add(&(conn->list), &(dev->connection_list));
1493 spin_unlock(&(dev->connection_list_lock));
1494
1495 /*
1496 * Successful completion.
1497 */
1498
1499 *connection = conn;
1500
1501 dprintk(KERN_INFO "tf_open(): Success (conn=%p)\n", conn);
1502 return 0;
1503
1504 /*
1505 * Error handling.
1506 */
1507
1508error:
1509 dprintk(KERN_ERR "tf_open(): Failure (error %d)\n", error);
1510 /* Deallocate the descriptor pages if necessary */
1511 internal_kfree(conn);
1512 *connection = NULL;
1513 return error;
1514}
1515
1516
1517/*
1518 * Closes the specified connection.
1519 *
1520 * Upon return, the connection has been destroyed and cannot be used anymore.
1521 *
1522 * This function does nothing if connection is set to NULL.
1523 */
1524void tf_close(struct tf_connection *connection)
1525{
1526 int error;
1527 enum TF_CONN_STATE state;
1528
1529 dprintk(KERN_DEBUG "tf_close(%p)\n", connection);
1530
1531 if (connection == NULL)
1532 return;
1533
1534 /*
1535 * Assumption: Linux guarantees that no other operation is in progress
1536 * and that no other operation will be started when close is called
1537 */
1538 BUG_ON(atomic_read(&(connection->pending_op_count)) != 0);
1539
1540 /*
1541 * Exchange a Destroy Device Context message if needed.
1542 */
1543 spin_lock(&(connection->state_lock));
1544 state = connection->state;
1545 spin_unlock(&(connection->state_lock));
1546 if (state == TF_CONN_STATE_VALID_DEVICE_CONTEXT) {
1547 /*
1548 * A DestroyDeviceContext operation was not performed. Do it
1549 * now.
1550 */
1551 error = tf_destroy_device_context(connection);
1552 if (error != 0)
1553 /* avoid cleanup if destroy device context fails */
1554 goto error;
1555 }
1556
1557 /*
1558 * Clean up the shared memory
1559 */
1560 tf_cleanup_shared_memories(connection);
1561
1562 spin_lock(&(connection->dev->connection_list_lock));
1563 list_del(&(connection->list));
1564 spin_unlock(&(connection->dev->connection_list_lock));
1565
1566 internal_kfree(connection);
1567
1568 return;
1569
1570error:
1571 dprintk(KERN_DEBUG "tf_close(%p) failed with error code %d\n",
1572 connection, error);
1573}
1574
diff --git a/security/tf_driver/tf_conn.h b/security/tf_driver/tf_conn.h
new file mode 100644
index 00000000000..8bed16f19d5
--- /dev/null
+++ b/security/tf_driver/tf_conn.h
@@ -0,0 +1,106 @@
1/**
2 * Copyright (c) 2011 Trusted Logic S.A.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#ifndef __TF_CONN_H__
21#define __TF_CONN_H__
22
23#include "tf_defs.h"
24
25/*
26 * Returns a pointer to the connection referenced by the
27 * specified file.
28 */
29static inline struct tf_connection *tf_conn_from_file(
30 struct file *file)
31{
32 return file->private_data;
33}
34
35int tf_validate_shmem_and_flags(u32 shmem, u32 shmem_size, u32 flags);
36
37int tf_map_shmem(
38 struct tf_connection *connection,
39 u32 buffer,
40 /* flags for read-write access rights on the memory */
41 u32 flags,
42 bool in_user_space,
43 u32 descriptors[TF_MAX_COARSE_PAGES],
44 u32 *buffer_start_offset,
45 u32 buffer_size,
46 struct tf_shmem_desc **shmem_desc,
47 u32 *descriptor_count);
48
49void tf_unmap_shmem(
50 struct tf_connection *connection,
51 struct tf_shmem_desc *shmem_desc,
52 u32 full_cleanup);
53
54/*----------------------------------------------------------------------------
55 * Connection operations to the Secure World
56 *----------------------------------------------------------------------------*/
57
58int tf_create_device_context(
59 struct tf_connection *connection);
60
61int tf_destroy_device_context(
62 struct tf_connection *connection);
63
64int tf_open_client_session(
65 struct tf_connection *connection,
66 union tf_command *command,
67 union tf_answer *answer);
68
69int tf_close_client_session(
70 struct tf_connection *connection,
71 union tf_command *command,
72 union tf_answer *answer);
73
74int tf_register_shared_memory(
75 struct tf_connection *connection,
76 union tf_command *command,
77 union tf_answer *answer);
78
79int tf_release_shared_memory(
80 struct tf_connection *connection,
81 union tf_command *command,
82 union tf_answer *answer);
83
84int tf_invoke_client_command(
85 struct tf_connection *connection,
86 union tf_command *command,
87 union tf_answer *answer);
88
89int tf_cancel_client_command(
90 struct tf_connection *connection,
91 union tf_command *command,
92 union tf_answer *answer);
93
94/*----------------------------------------------------------------------------
95 * Connection initialization and cleanup operations
96 *----------------------------------------------------------------------------*/
97
98int tf_open(struct tf_device *dev,
99 struct file *file,
100 struct tf_connection **connection);
101
102void tf_close(
103 struct tf_connection *connection);
104
105
106#endif /* !defined(__TF_CONN_H__) */
diff --git a/security/tf_driver/tf_defs.h b/security/tf_driver/tf_defs.h
new file mode 100644
index 00000000000..ac209370c55
--- /dev/null
+++ b/security/tf_driver/tf_defs.h
@@ -0,0 +1,538 @@
1/**
2 * Copyright (c) 2011 Trusted Logic S.A.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#ifndef __TF_DEFS_H__
21#define __TF_DEFS_H__
22
23#include <linux/atomic.h>
24#include <linux/version.h>
25#include <linux/fs.h>
26#include <linux/cdev.h>
27#include <linux/completion.h>
28#include <linux/list.h>
29#include <linux/spinlock.h>
30#include <linux/sysfs.h>
31#include <linux/sched.h>
32#include <linux/semaphore.h>
33#ifdef CONFIG_HAS_WAKELOCK
34#include <linux/wakelock.h>
35#endif
36
37#include "tf_protocol.h"
38
39/*----------------------------------------------------------------------------*/
40
41#define SIZE_1KB 0x400
42
43/*
44 * Maximum number of shared memory blocks that can be reigsters in a connection
45 */
46#define TF_SHMEM_MAX_COUNT (64)
47
48/*
49 * Describes the possible types of shared memories
50 *
51 * TF_SHMEM_TYPE_PREALLOC_REGISTERED_SHMEM :
52 * The descriptor describes a registered shared memory.
53 * Its coarse pages are preallocated when initializing the
54 * connection
55 * TF_SHMEM_TYPE_REGISTERED_SHMEM :
56 * The descriptor describes a registered shared memory.
57 * Its coarse pages are not preallocated
58 * TF_SHMEM_TYPE_PM_HIBERNATE :
59 * The descriptor describes a power management shared memory.
60 */
61enum TF_SHMEM_TYPE {
62 TF_SHMEM_TYPE_PREALLOC_REGISTERED_SHMEM = 0,
63 TF_SHMEM_TYPE_REGISTERED_SHMEM,
64 TF_SHMEM_TYPE_PM_HIBERNATE,
65};
66
67
68/*
69 * This structure contains a pointer on a coarse page table
70 */
71struct tf_coarse_page_table {
72 /*
73 * Identifies the coarse page table descriptor in
74 * free_coarse_page_tables list
75 */
76 struct list_head list;
77
78 /*
79 * The address of the coarse page table
80 */
81 u32 *descriptors;
82
83 /*
84 * The address of the array containing this coarse page table
85 */
86 struct tf_coarse_page_table_array *parent;
87};
88
89
90#define TF_PAGE_DESCRIPTOR_TYPE_NORMAL 0
91#define TF_PAGE_DESCRIPTOR_TYPE_PREALLOCATED 1
92
93/*
94 * This structure describes an array of up to 4 coarse page tables
95 * allocated within a single 4KB page.
96 */
97struct tf_coarse_page_table_array {
98 /*
99 * identifies the element in the coarse_page_table_arrays list
100 */
101 struct list_head list;
102
103 /*
104 * Type of page descriptor
105 * can take any of TF_PAGE_DESCRIPTOR_TYPE_XXX value
106 */
107 u32 type;
108
109 struct tf_coarse_page_table coarse_page_tables[4];
110
111 /*
112 * A counter of the number of coarse pages currently used
113 * the max value should be 4 (one coarse page table is 1KB while one
114 * page is 4KB)
115 */
116 u8 ref_count;
117};
118
119
120/*
121 * This structure describes a list of coarse page table arrays
122 * with some of the coarse page tables free. It is used
123 * when the driver needs to allocate a new coarse page
124 * table.
125 */
126struct tf_coarse_page_table_allocation_context {
127 /*
128 * The spin lock protecting concurrent access to the structure.
129 */
130 spinlock_t lock;
131
132 /*
133 * The list of allocated coarse page table arrays
134 */
135 struct list_head coarse_page_table_arrays;
136
137 /*
138 * The list of free coarse page tables
139 */
140 struct list_head free_coarse_page_tables;
141};
142
143
144/*
145 * Fully describes a shared memory block
146 */
147struct tf_shmem_desc {
148 /*
149 * Identifies the shared memory descriptor in the list of free shared
150 * memory descriptors
151 */
152 struct list_head list;
153
154 /*
155 * Identifies the type of shared memory descriptor
156 */
157 enum TF_SHMEM_TYPE type;
158
159 /*
160 * The identifier of the block of shared memory, as returned by the
161 * Secure World.
162 * This identifier is block field of a REGISTER_SHARED_MEMORY answer
163 */
164 u32 block_identifier;
165
166 /* Client buffer */
167 u8 *client_buffer;
168
169 /* Up to eight coarse page table context */
170 struct tf_coarse_page_table *coarse_pg_table[TF_MAX_COARSE_PAGES];
171
172 u32 coarse_pg_table_count;
173
174 /* Reference counter */
175 atomic_t ref_count;
176};
177
178
179/*----------------------------------------------------------------------------*/
180
181/*
182 * This structure describes the communication with the Secure World
183 *
184 * Note that this driver supports only one instance of the Secure World
185 */
186struct tf_comm {
187 /*
188 * The spin lock protecting concurrent access to the structure.
189 */
190 spinlock_t lock;
191
192 /*
193 * Bit vector with the following possible flags:
194 * - TF_COMM_FLAG_IRQ_REQUESTED: If set, indicates that
195 * the IRQ has been successfuly requested.
196 * - TF_COMM_FLAG_TERMINATING: If set, indicates that the
197 * communication with the Secure World is being terminated.
198 * Transmissions to the Secure World are not permitted
199 * - TF_COMM_FLAG_W3B_ALLOCATED: If set, indicates that the
200 * W3B buffer has been allocated.
201 *
202 * This bit vector must be accessed with the kernel's atomic bitwise
203 * operations.
204 */
205 unsigned long flags;
206
207 /*
208 * The virtual address of the L1 shared buffer.
209 */
210 struct tf_l1_shared_buffer *l1_buffer;
211
212 /*
213 * The wait queue the client threads are waiting on.
214 */
215 wait_queue_head_t wait_queue;
216
217#ifdef CONFIG_TF_TRUSTZONE
218 /*
219 * The interrupt line used by the Secure World.
220 */
221 int soft_int_irq;
222
223 /* ----- W3B ----- */
224 /* shared memory descriptor to identify the W3B */
225 struct tf_shmem_desc w3b_shmem_desc;
226
227 /* Virtual address of the kernel allocated shared memory */
228 u32 w3b;
229
230 /* offset of data in shared memory coarse pages */
231 u32 w3b_shmem_offset;
232
233 u32 w3b_shmem_size;
234
235 struct tf_coarse_page_table_allocation_context
236 w3b_cpt_alloc_context;
237#endif
238#ifdef CONFIG_TF_ZEBRA
239 /*
240 * The SE SDP can only be initialized once...
241 */
242 int se_initialized;
243
244 /*
245 * Lock to be held by a client when executing an RPC
246 */
247 struct mutex rpc_mutex;
248
249 /*
250 * Lock to protect concurrent accesses to DMA channels
251 */
252 struct mutex dma_mutex;
253#endif
254};
255
256
257#define TF_COMM_FLAG_IRQ_REQUESTED (0)
258#define TF_COMM_FLAG_PA_AVAILABLE (1)
259#define TF_COMM_FLAG_TERMINATING (2)
260#define TF_COMM_FLAG_W3B_ALLOCATED (3)
261#define TF_COMM_FLAG_L1_SHARED_ALLOCATED (4)
262
263/*----------------------------------------------------------------------------*/
264
265struct tf_device_stats {
266 atomic_t stat_pages_allocated;
267 atomic_t stat_memories_allocated;
268 atomic_t stat_pages_locked;
269};
270
271/*
272 * This structure describes the information about one device handled by the
273 * driver. Note that the driver supports only a single device. see the global
274 * variable g_tf_dev
275
276 */
277struct tf_device {
278 /*
279 * The kernel object for the device
280 */
281 struct kobject kobj;
282
283 /*
284 * The device number for the device.
285 */
286 dev_t dev_number;
287
288 /*
289 * Interfaces the char device with the kernel.
290 */
291 struct cdev cdev;
292
293#ifdef CONFIG_TF_TEEC
294 struct cdev cdev_teec;
295#endif
296
297#ifdef CONFIG_TF_ZEBRA
298 struct cdev cdev_ctrl;
299
300 /*
301 * Globals for CUS
302 */
303 /* Current key handles loaded in HWAs */
304 u32 aes1_key_context;
305 u32 des_key_context;
306 bool sham1_is_public;
307
308 /* Object used to serialize HWA accesses */
309 struct semaphore aes1_sema;
310 struct semaphore des_sema;
311 struct semaphore sha_sema;
312
313 /*
314 * An aligned and correctly shaped pre-allocated buffer used for DMA
315 * transfers
316 */
317 u32 dma_buffer_length;
318 u8 *dma_buffer;
319 dma_addr_t dma_buffer_phys;
320
321 /* Workspace allocated at boot time and reserved to the Secure World */
322 u32 workspace_addr;
323 u32 workspace_size;
324
325 /*
326 * A Mutex to provide exclusive locking of the ioctl()
327 */
328 struct mutex dev_mutex;
329#endif
330
331 /*
332 * Communications with the SM.
333 */
334 struct tf_comm sm;
335
336 /*
337 * Lists the connections attached to this device. A connection is
338 * created each time a user space application "opens" a file descriptor
339 * on the driver
340 */
341 struct list_head connection_list;
342
343 /*
344 * The spin lock used to protect concurrent access to the connection
345 * list.
346 */
347 spinlock_t connection_list_lock;
348
349 struct tf_device_stats stats;
350};
351
352/*----------------------------------------------------------------------------*/
353/*
354 * This type describes a connection state.
355 * This is used to determine whether a message is valid or not.
356 *
357 * Messages are only valid in a certain device state.
358 * Messages may be invalidated between the start of the ioctl call and the
359 * moment the message is sent to the Secure World.
360 *
361 * TF_CONN_STATE_NO_DEVICE_CONTEXT :
362 * The connection has no DEVICE_CONTEXT created and no
363 * CREATE_DEVICE_CONTEXT being processed by the Secure World
364 * TF_CONN_STATE_CREATE_DEVICE_CONTEXT_SENT :
365 * The connection has a CREATE_DEVICE_CONTEXT being processed by the Secure
366 * World
367 * TF_CONN_STATE_VALID_DEVICE_CONTEXT :
368 * The connection has a DEVICE_CONTEXT created and no
369 * DESTROY_DEVICE_CONTEXT is being processed by the Secure World
370 * TF_CONN_STATE_DESTROY_DEVICE_CONTEXT_SENT :
371 * The connection has a DESTROY_DEVICE_CONTEXT being processed by the Secure
372 * World
373 */
374enum TF_CONN_STATE {
375 TF_CONN_STATE_NO_DEVICE_CONTEXT = 0,
376 TF_CONN_STATE_CREATE_DEVICE_CONTEXT_SENT,
377 TF_CONN_STATE_VALID_DEVICE_CONTEXT,
378 TF_CONN_STATE_DESTROY_DEVICE_CONTEXT_SENT
379};
380
381
382/*
383 * This type describes the status of the command.
384 *
385 * PENDING:
386 * The initial state; the command has not been sent yet.
387 * SENT:
388 * The command has been sent, we are waiting for an answer.
389 * ABORTED:
390 * The command cannot be sent because the device context is invalid.
391 * Note that this only covers the case where some other thread
392 * sent a DESTROY_DEVICE_CONTEXT command.
393 */
394enum TF_COMMAND_STATE {
395 TF_COMMAND_STATE_PENDING = 0,
396 TF_COMMAND_STATE_SENT,
397 TF_COMMAND_STATE_ABORTED
398};
399
400/*
401 * The origin of connection parameters such as login data and
402 * memory reference pointers.
403 *
404 * PROCESS: the calling process. All arguments must be validated.
405 * KERNEL: kernel code. All arguments can be trusted by this driver.
406 */
407enum TF_CONNECTION_OWNER {
408 TF_CONNECTION_OWNER_PROCESS = 0,
409 TF_CONNECTION_OWNER_KERNEL,
410};
411
412
413/*
414 * This structure describes a connection to the driver
415 * A connection is created each time an application opens a file descriptor on
416 * the driver
417 */
418struct tf_connection {
419 /*
420 * Identifies the connection in the list of the connections attached to
421 * the same device.
422 */
423 struct list_head list;
424
425 /*
426 * State of the connection.
427 */
428 enum TF_CONN_STATE state;
429
430 /*
431 * A pointer to the corresponding device structure
432 */
433 struct tf_device *dev;
434
435 /*
436 * A spinlock to use to access state
437 */
438 spinlock_t state_lock;
439
440 /*
441 * Counts the number of operations currently pending on the connection.
442 * (for debug only)
443 */
444 atomic_t pending_op_count;
445
446 /*
447 * A handle for the device context
448 */
449 u32 device_context;
450
451 /*
452 * Lists the used shared memory descriptors
453 */
454 struct list_head used_shmem_list;
455
456 /*
457 * Lists the free shared memory descriptors
458 */
459 struct list_head free_shmem_list;
460
461 /*
462 * A mutex to use to access this structure
463 */
464 struct mutex shmem_mutex;
465
466 /*
467 * Counts the number of shared memories registered.
468 */
469 atomic_t shmem_count;
470
471 /*
472 * Page to retrieve memory properties when
473 * registering shared memory through REGISTER_SHARED_MEMORY
474 * messages
475 */
476 struct vm_area_struct **vmas;
477
478 /*
479 * coarse page table allocation context
480 */
481 struct tf_coarse_page_table_allocation_context cpt_alloc_context;
482
483 /* The origin of connection parameters such as login data and
484 memory reference pointers. */
485 enum TF_CONNECTION_OWNER owner;
486
487#ifdef CONFIG_TF_ZEBRA
488 /* Lists all the Cryptoki Update Shortcuts */
489 struct list_head shortcut_list;
490
491 /* Lock to protect concurrent accesses to shortcut_list */
492 spinlock_t shortcut_list_lock;
493#endif
494};
495
496/*----------------------------------------------------------------------------*/
497
498/*
499 * The operation_id field of a message points to this structure.
500 * It is used to identify the thread that triggered the message transmission
501 * Whoever reads an answer can wake up that thread using the completion event
502 */
503struct tf_answer_struct {
504 bool answer_copied;
505 union tf_answer *answer;
506};
507
508/*----------------------------------------------------------------------------*/
509
510/**
511 * The ASCII-C string representation of the base name of the devices managed by
512 * this driver.
513 */
514#define TF_DEVICE_BASE_NAME "tf_driver"
515
516
517/**
518 * The major and minor numbers of the registered character device driver.
519 * Only 1 instance of the driver is supported.
520 */
521#define TF_DEVICE_MINOR_NUMBER (0)
522
523struct tf_device *tf_get_device(void);
524
525#define CLEAN_CACHE_CFG_MASK (~0xC) /* 1111 0011 */
526
527/*----------------------------------------------------------------------------*/
528/*
529 * Kernel Differences
530 */
531
532#ifdef CONFIG_ANDROID
533#define GROUP_INFO get_current_groups()
534#else
535#define GROUP_INFO (current->group_info)
536#endif
537
538#endif /* !defined(__TF_DEFS_H__) */
diff --git a/security/tf_driver/tf_device.c b/security/tf_driver/tf_device.c
new file mode 100644
index 00000000000..ad44b46c206
--- /dev/null
+++ b/security/tf_driver/tf_device.c
@@ -0,0 +1,796 @@
1/**
2 * Copyright (c) 2011 Trusted Logic S.A.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#include <linux/atomic.h>
21#include <linux/uaccess.h>
22#include <linux/module.h>
23#include <linux/errno.h>
24#include <linux/mm.h>
25#include <linux/page-flags.h>
26#include <linux/pm.h>
27#include <linux/syscore_ops.h>
28#include <linux/vmalloc.h>
29#include <linux/signal.h>
30#ifdef CONFIG_ANDROID
31#include <linux/device.h>
32#endif
33
34#include "tf_protocol.h"
35#include "tf_defs.h"
36#include "tf_util.h"
37#include "tf_conn.h"
38#include "tf_comm.h"
39#ifdef CONFIG_TF_ZEBRA
40#include <plat/cpu.h>
41#include "tf_zebra.h"
42#endif
43#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
44#include "tf_crypto.h"
45#endif
46
47#include "s_version.h"
48
49/*----------------------------------------------------------------------------
50 * Forward Declarations
51 *----------------------------------------------------------------------------*/
52
53/*
54 * Creates and registers the device to be managed by the specified driver.
55 *
56 * Returns zero upon successful completion, or an appropriate error code upon
57 * failure.
58 */
59static int tf_device_register(void);
60
61
62/*
63 * Implements the device Open callback.
64 */
65static int tf_device_open(
66 struct inode *inode,
67 struct file *file);
68
69
70/*
71 * Implements the device Release callback.
72 */
73static int tf_device_release(
74 struct inode *inode,
75 struct file *file);
76
77
78/*
79 * Implements the device ioctl callback.
80 */
81static long tf_device_ioctl(
82 struct file *file,
83 unsigned int ioctl_num,
84 unsigned long ioctl_param);
85
86
87/*
88 * Implements the device shutdown callback.
89 */
90static int tf_device_shutdown(void);
91
92
93/*
94 * Implements the device suspend callback.
95 */
96static int tf_device_suspend(void);
97
98
99/*
100 * Implements the device resume callback.
101 */
102static int tf_device_resume(void);
103
104
105/*---------------------------------------------------------------------------
106 * Module Parameters
107 *---------------------------------------------------------------------------*/
108
109/*
110 * The device major number used to register a unique character device driver.
111 * Let the default value be 122
112 */
113static int device_major_number = 122;
114
115module_param(device_major_number, int, 0000);
116MODULE_PARM_DESC(device_major_number,
117 "The device major number used to register a unique character "
118 "device driver");
119
120#ifdef CONFIG_TF_TRUSTZONE
121/**
122 * The softint interrupt line used by the Secure World.
123 */
124static int soft_interrupt = -1;
125
126module_param(soft_interrupt, int, 0000);
127MODULE_PARM_DESC(soft_interrupt,
128 "The softint interrupt line used by the Secure world");
129#endif
130
131#ifdef CONFIG_TF_DRIVER_DEBUG_SUPPORT
132unsigned tf_debug_level = UINT_MAX;
133module_param_named(debug, tf_debug_level, uint, 0644);
134#endif
135
136#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
137char *tf_integrity_hmac_sha256_expected_value;
138module_param_named(hmac_sha256, tf_integrity_hmac_sha256_expected_value,
139 charp, 0444);
140
141#ifdef CONFIG_TF_DRIVER_FAULT_INJECTION
142unsigned tf_fault_injection_mask;
143module_param_named(fault, tf_fault_injection_mask, uint, 0644);
144#endif
145
146int tf_self_test_blkcipher_align;
147module_param_named(post_align, tf_self_test_blkcipher_align, int, 0644);
148int tf_self_test_blkcipher_use_vmalloc;
149module_param_named(post_vmalloc, tf_self_test_blkcipher_use_vmalloc, int, 0644);
150#endif
151
152#ifdef CONFIG_ANDROID
153static struct class *tf_class;
154#endif
155
156/*----------------------------------------------------------------------------
157 * Global Variables
158 *----------------------------------------------------------------------------*/
159
160/*
161 * tf_driver character device definitions.
162 * read and write methods are not defined
163 * and will return an error if used by user space
164 */
165static const struct file_operations g_tf_device_file_ops = {
166 .owner = THIS_MODULE,
167 .open = tf_device_open,
168 .release = tf_device_release,
169 .unlocked_ioctl = tf_device_ioctl,
170 .llseek = no_llseek,
171};
172
173
174static struct syscore_ops g_tf_device_syscore_ops = {
175 .shutdown = tf_device_shutdown,
176 .suspend = tf_device_suspend,
177 .resume = tf_device_resume,
178};
179
180/* The single device supported by this driver */
181static struct tf_device g_tf_dev;
182
183/*----------------------------------------------------------------------------
184 * Implementations
185 *----------------------------------------------------------------------------*/
186
187struct tf_device *tf_get_device(void)
188{
189 return &g_tf_dev;
190}
191
192/*
193 * sysfs entries
194 */
195struct tf_sysfs_entry {
196 struct attribute attr;
197 ssize_t (*show)(struct tf_device *, char *);
198 ssize_t (*store)(struct tf_device *, const char *, size_t);
199};
200
201/*
202 * sysfs entry showing allocation stats
203 */
204static ssize_t info_show(struct tf_device *dev, char *buf)
205{
206 struct tf_device_stats *dev_stats = &dev->stats;
207
208 return snprintf(buf, PAGE_SIZE,
209 "stat.memories.allocated: %d\n"
210 "stat.pages.allocated: %d\n"
211 "stat.pages.locked: %d\n",
212 atomic_read(&dev_stats->stat_memories_allocated),
213 atomic_read(&dev_stats->stat_pages_allocated),
214 atomic_read(&dev_stats->stat_pages_locked));
215}
216static struct tf_sysfs_entry tf_info_entry = __ATTR_RO(info);
217
218#ifdef CONFIG_TF_ZEBRA
219/*
220 * sysfs entry showing whether secure world is up and running
221 */
222static ssize_t tf_started_show(struct tf_device *dev, char *buf)
223{
224 int tf_started = test_bit(TF_COMM_FLAG_PA_AVAILABLE,
225 &dev->sm.flags);
226
227 return snprintf(buf, PAGE_SIZE, "%s\n", tf_started ? "yes" : "no");
228}
229static struct tf_sysfs_entry tf_started_entry =
230 __ATTR_RO(tf_started);
231
232static ssize_t workspace_addr_show(struct tf_device *dev, char *buf)
233{
234 return snprintf(buf, PAGE_SIZE, "0x%08x\n", dev->workspace_addr);
235}
236static struct tf_sysfs_entry tf_workspace_addr_entry =
237 __ATTR_RO(workspace_addr);
238
239static ssize_t workspace_size_show(struct tf_device *dev, char *buf)
240{
241 return snprintf(buf, PAGE_SIZE, "0x%08x\n", dev->workspace_size);
242}
243static struct tf_sysfs_entry tf_workspace_size_entry =
244 __ATTR_RO(workspace_size);
245#endif
246
247static ssize_t tf_attr_show(struct kobject *kobj, struct attribute *attr,
248 char *page)
249{
250 struct tf_sysfs_entry *entry = container_of(attr, struct tf_sysfs_entry,
251 attr);
252 struct tf_device *dev = container_of(kobj, struct tf_device, kobj);
253
254 if (!entry->show)
255 return -EIO;
256
257 return entry->show(dev, page);
258}
259
260static ssize_t tf_attr_store(struct kobject *kobj, struct attribute *attr,
261 const char *page, size_t length)
262{
263 struct tf_sysfs_entry *entry = container_of(attr, struct tf_sysfs_entry,
264 attr);
265 struct tf_device *dev = container_of(kobj, struct tf_device, kobj);
266
267 if (!entry->store)
268 return -EIO;
269
270 return entry->store(dev, page, length);
271}
272
273static void tf_kobj_release(struct kobject *kobj) {}
274
275static struct attribute *tf_default_attrs[] = {
276 &tf_info_entry.attr,
277#ifdef CONFIG_TF_ZEBRA
278 &tf_started_entry.attr,
279 &tf_workspace_addr_entry.attr,
280 &tf_workspace_size_entry.attr,
281#endif
282 NULL,
283};
284static const struct sysfs_ops tf_sysfs_ops = {
285 .show = tf_attr_show,
286 .store = tf_attr_store,
287};
288static struct kobj_type tf_ktype = {
289 .release = tf_kobj_release,
290 .sysfs_ops = &tf_sysfs_ops,
291 .default_attrs = tf_default_attrs
292};
293
294/*----------------------------------------------------------------------------*/
295
296#if defined(MODULE) && defined(CONFIG_TF_ZEBRA)
297static char *smc_mem;
298module_param(smc_mem, charp, S_IRUGO);
299#endif
300
301/*
302 * First routine called when the kernel module is loaded
303 */
304static int __init tf_device_register(void)
305{
306 int error;
307 struct tf_device *dev = &g_tf_dev;
308
309 dprintk(KERN_INFO "tf_device_register()\n");
310
311 /*
312 * Initialize the device
313 */
314 dev->dev_number = MKDEV(device_major_number,
315 TF_DEVICE_MINOR_NUMBER);
316 cdev_init(&dev->cdev, &g_tf_device_file_ops);
317 dev->cdev.owner = THIS_MODULE;
318
319 INIT_LIST_HEAD(&dev->connection_list);
320 spin_lock_init(&dev->connection_list_lock);
321
322#if defined(MODULE) && defined(CONFIG_TF_ZEBRA)
323 error = (*tf_comm_early_init)();
324 if (error)
325 goto module_early_init_failed;
326
327 error = tf_device_mshield_init(smc_mem);
328 if (error)
329 goto mshield_init_failed;
330
331#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
332 error = tf_crypto_hmac_module_init();
333 if (error)
334 goto hmac_init_failed;
335
336 error = tf_self_test_register_device();
337 if (error)
338 goto self_test_register_device_failed;
339#endif
340#endif
341
342 /* register the sysfs object driver stats */
343 error = kobject_init_and_add(&dev->kobj, &tf_ktype, NULL, "%s",
344 TF_DEVICE_BASE_NAME);
345 if (error) {
346 printk(KERN_ERR "tf_device_register(): "
347 "kobject_init_and_add failed (error %d)!\n", error);
348 kobject_put(&dev->kobj);
349 goto kobject_init_and_add_failed;
350 }
351
352 /*
353 * Register the system device.
354 */
355 register_syscore_ops(&g_tf_device_syscore_ops);
356
357 /*
358 * Register the char device.
359 */
360 printk(KERN_INFO "Registering char device %s (%u:%u)\n",
361 TF_DEVICE_BASE_NAME,
362 MAJOR(dev->dev_number),
363 MINOR(dev->dev_number));
364 error = register_chrdev_region(dev->dev_number, 1,
365 TF_DEVICE_BASE_NAME);
366 if (error != 0) {
367 printk(KERN_ERR "tf_device_register():"
368 " register_chrdev_region failed (error %d)!\n",
369 error);
370 goto register_chrdev_region_failed;
371 }
372
373 error = cdev_add(&dev->cdev, dev->dev_number, 1);
374 if (error != 0) {
375 printk(KERN_ERR "tf_device_register(): "
376 "cdev_add failed (error %d)!\n",
377 error);
378 goto cdev_add_failed;
379 }
380
381 /*
382 * Initialize the communication with the Secure World.
383 */
384#ifdef CONFIG_TF_TRUSTZONE
385 dev->sm.soft_int_irq = soft_interrupt;
386#endif
387 error = tf_init(&g_tf_dev.sm);
388 if (error != S_SUCCESS) {
389 dprintk(KERN_ERR "tf_device_register(): "
390 "tf_init failed (error %d)!\n",
391 error);
392 goto init_failed;
393 }
394
395#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
396 error = tf_self_test_post_init(&(dev_stats->kobj));
397 /* N.B. error > 0 indicates a POST failure, which will not
398 prevent the module from loading. */
399 if (error < 0) {
400 dprintk(KERN_ERR "tf_device_register(): "
401 "tf_self_test_post_vectors failed (error %d)!\n",
402 error);
403 goto post_failed;
404 }
405#endif
406
407#ifdef CONFIG_ANDROID
408 tf_class = class_create(THIS_MODULE, TF_DEVICE_BASE_NAME);
409 device_create(tf_class, NULL,
410 dev->dev_number,
411 NULL, TF_DEVICE_BASE_NAME);
412#endif
413
414#ifdef CONFIG_TF_ZEBRA
415 /*
416 * Initializes the /dev/tf_ctrl device node.
417 */
418 error = tf_ctrl_device_register();
419 if (error)
420 goto ctrl_failed;
421#endif
422
423#ifdef CONFIG_TF_DRIVER_DEBUG_SUPPORT
424 address_cache_property((unsigned long) &tf_device_register);
425#endif
426 /*
427 * Successful completion.
428 */
429
430 dprintk(KERN_INFO "tf_device_register(): Success\n");
431 return 0;
432
433 /*
434 * Error: undo all operations in the reverse order
435 */
436#ifdef CONFIG_TF_ZEBRA
437ctrl_failed:
438#endif
439#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
440 tf_self_test_post_exit();
441post_failed:
442#endif
443init_failed:
444 cdev_del(&dev->cdev);
445cdev_add_failed:
446 unregister_chrdev_region(dev->dev_number, 1);
447register_chrdev_region_failed:
448 unregister_syscore_ops(&g_tf_device_syscore_ops);
449kobject_init_and_add_failed:
450 kobject_del(&g_tf_dev.kobj);
451
452#if defined(MODULE) && defined(CONFIG_TF_ZEBRA)
453#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
454 tf_self_test_unregister_device();
455self_test_register_device_failed:
456 tf_crypto_hmac_module_exit();
457hmac_init_failed:
458#endif
459 tf_device_mshield_exit();
460mshield_init_failed:
461module_early_init_failed:
462#endif
463 dprintk(KERN_INFO "tf_device_register(): Failure (error %d)\n",
464 error);
465 return error;
466}
467
468/*----------------------------------------------------------------------------*/
469
470static int tf_device_open(struct inode *inode, struct file *file)
471{
472 int error;
473 struct tf_device *dev = &g_tf_dev;
474 struct tf_connection *connection = NULL;
475
476 dprintk(KERN_INFO "tf_device_open(%u:%u, %p)\n",
477 imajor(inode), iminor(inode), file);
478
479 /* Dummy lseek for non-seekable driver */
480 error = nonseekable_open(inode, file);
481 if (error != 0) {
482 dprintk(KERN_ERR "tf_device_open(%p): "
483 "nonseekable_open failed (error %d)!\n",
484 file, error);
485 goto error;
486 }
487
488#ifndef CONFIG_ANDROID
489 /*
490 * Check file flags. We only autthorize the O_RDWR access
491 */
492 if (file->f_flags != O_RDWR) {
493 dprintk(KERN_ERR "tf_device_open(%p): "
494 "Invalid access mode %u\n",
495 file, file->f_flags);
496 error = -EACCES;
497 goto error;
498 }
499#endif
500
501 /*
502 * Open a new connection.
503 */
504
505 error = tf_open(dev, file, &connection);
506 if (error != 0) {
507 dprintk(KERN_ERR "tf_device_open(%p): "
508 "tf_open failed (error %d)!\n",
509 file, error);
510 goto error;
511 }
512
513 file->private_data = connection;
514
515 /*
516 * Send the CreateDeviceContext command to the secure
517 */
518 error = tf_create_device_context(connection);
519 if (error != 0) {
520 dprintk(KERN_ERR "tf_device_open(%p): "
521 "tf_create_device_context failed (error %d)!\n",
522 file, error);
523 goto error1;
524 }
525
526 /*
527 * Successful completion.
528 */
529
530 dprintk(KERN_INFO "tf_device_open(%p): Success (connection=%p)\n",
531 file, connection);
532 return 0;
533
534 /*
535 * Error handling.
536 */
537
538error1:
539 tf_close(connection);
540error:
541 dprintk(KERN_INFO "tf_device_open(%p): Failure (error %d)\n",
542 file, error);
543 return error;
544}
545
546/*----------------------------------------------------------------------------*/
547
548static int tf_device_release(struct inode *inode, struct file *file)
549{
550 struct tf_connection *connection;
551
552 dprintk(KERN_INFO "tf_device_release(%u:%u, %p)\n",
553 imajor(inode), iminor(inode), file);
554
555 connection = tf_conn_from_file(file);
556 tf_close(connection);
557
558 dprintk(KERN_INFO "tf_device_release(%p): Success\n", file);
559 return 0;
560}
561
562/*----------------------------------------------------------------------------*/
563
564static long tf_device_ioctl(struct file *file, unsigned int ioctl_num,
565 unsigned long ioctl_param)
566{
567 int result = S_SUCCESS;
568 struct tf_connection *connection;
569 union tf_command command;
570 struct tf_command_header header;
571 union tf_answer answer;
572 u32 command_size;
573 u32 answer_size;
574 void *user_answer;
575
576 dprintk(KERN_INFO "tf_device_ioctl(%p, %u, %p)\n",
577 file, ioctl_num, (void *) ioctl_param);
578
579 switch (ioctl_num) {
580 case IOCTL_TF_GET_VERSION:
581 /* ioctl is asking for the driver interface version */
582 result = TF_DRIVER_INTERFACE_VERSION;
583 goto exit;
584
585 case IOCTL_TF_EXCHANGE:
586 /*
587 * ioctl is asking to perform a message exchange with the Secure
588 * Module
589 */
590
591 /*
592 * Make a local copy of the data from the user application
593 * This routine checks the data is readable
594 *
595 * Get the header first.
596 */
597 if (copy_from_user(&header,
598 (struct tf_command_header *)ioctl_param,
599 sizeof(struct tf_command_header))) {
600 dprintk(KERN_ERR "tf_device_ioctl(%p): "
601 "Cannot access ioctl parameter %p\n",
602 file, (void *) ioctl_param);
603 result = -EFAULT;
604 goto exit;
605 }
606
607 /* size in words of u32 */
608 command_size = header.message_size +
609 sizeof(struct tf_command_header)/sizeof(u32);
610 if (command_size > sizeof(command)/sizeof(u32)) {
611 dprintk(KERN_ERR "tf_device_ioctl(%p): "
612 "Buffer overflow: too many bytes to copy %d\n",
613 file, command_size);
614 result = -EFAULT;
615 goto exit;
616 }
617
618 if (copy_from_user(&command,
619 (union tf_command *)ioctl_param,
620 command_size * sizeof(u32))) {
621 dprintk(KERN_ERR "tf_device_ioctl(%p): "
622 "Cannot access ioctl parameter %p\n",
623 file, (void *) ioctl_param);
624 result = -EFAULT;
625 goto exit;
626 }
627
628 connection = tf_conn_from_file(file);
629 BUG_ON(connection == NULL);
630
631 /*
632 * The answer memory space address is in the operation_id field
633 */
634 user_answer = (void *) command.header.operation_id;
635
636 atomic_inc(&(connection->pending_op_count));
637
638 dprintk(KERN_WARNING "tf_device_ioctl(%p): "
639 "Sending message type 0x%08x\n",
640 file, command.header.message_type);
641
642 switch (command.header.message_type) {
643 case TF_MESSAGE_TYPE_OPEN_CLIENT_SESSION:
644 result = tf_open_client_session(connection,
645 &command, &answer);
646 break;
647
648 case TF_MESSAGE_TYPE_CLOSE_CLIENT_SESSION:
649 result = tf_close_client_session(connection,
650 &command, &answer);
651 break;
652
653 case TF_MESSAGE_TYPE_REGISTER_SHARED_MEMORY:
654 result = tf_register_shared_memory(connection,
655 &command, &answer);
656 break;
657
658 case TF_MESSAGE_TYPE_RELEASE_SHARED_MEMORY:
659 result = tf_release_shared_memory(connection,
660 &command, &answer);
661 break;
662
663 case TF_MESSAGE_TYPE_INVOKE_CLIENT_COMMAND:
664 result = tf_invoke_client_command(connection,
665 &command, &answer);
666 break;
667
668 case TF_MESSAGE_TYPE_CANCEL_CLIENT_COMMAND:
669 result = tf_cancel_client_command(connection,
670 &command, &answer);
671 break;
672
673 default:
674 dprintk(KERN_ERR "tf_device_ioctl(%p): "
675 "Incorrect message type (0x%08x)!\n",
676 connection, command.header.message_type);
677 result = -EOPNOTSUPP;
678 break;
679 }
680
681 atomic_dec(&(connection->pending_op_count));
682
683 if (result != 0) {
684 dprintk(KERN_WARNING "tf_device_ioctl(%p): "
685 "Operation returning error code 0x%08x)!\n",
686 file, result);
687 goto exit;
688 }
689
690 /*
691 * Copy the answer back to the user space application.
692 * The driver does not check this field, only copy back to user
693 * space the data handed over by Secure World
694 */
695 answer_size = answer.header.message_size +
696 sizeof(struct tf_answer_header)/sizeof(u32);
697 if (copy_to_user(user_answer,
698 &answer, answer_size * sizeof(u32))) {
699 dprintk(KERN_WARNING "tf_device_ioctl(%p): "
700 "Failed to copy back the full command "
701 "answer to %p\n", file, user_answer);
702 result = -EFAULT;
703 goto exit;
704 }
705
706 /* successful completion */
707 dprintk(KERN_INFO "tf_device_ioctl(%p): Success\n", file);
708 break;
709
710 case IOCTL_TF_GET_DESCRIPTION: {
711 /* ioctl asking for the version information buffer */
712 struct tf_version_information_buffer *pInfoBuffer;
713
714 dprintk(KERN_INFO "IOCTL_TF_GET_DESCRIPTION:(%p, %u, %p)\n",
715 file, ioctl_num, (void *) ioctl_param);
716
717 pInfoBuffer =
718 ((struct tf_version_information_buffer *) ioctl_param);
719
720 dprintk(KERN_INFO "IOCTL_TF_GET_DESCRIPTION1: "
721 "driver_description=\"%64s\"\n", S_VERSION_STRING);
722
723 if (copy_to_user(pInfoBuffer->driver_description,
724 S_VERSION_STRING,
725 strlen(S_VERSION_STRING) + 1)) {
726 dprintk(KERN_ERR "tf_device_ioctl(%p): "
727 "Fail to copy back the driver description "
728 "to %p\n",
729 file, pInfoBuffer->driver_description);
730 result = -EFAULT;
731 goto exit;
732 }
733
734 dprintk(KERN_INFO "IOCTL_TF_GET_DESCRIPTION2: "
735 "secure_world_description=\"%64s\"\n",
736 tf_get_description(&g_tf_dev.sm));
737
738 if (copy_to_user(pInfoBuffer->secure_world_description,
739 tf_get_description(&g_tf_dev.sm),
740 TF_DESCRIPTION_BUFFER_LENGTH)) {
741 dprintk(KERN_WARNING "tf_device_ioctl(%p): "
742 "Failed to copy back the secure world "
743 "description to %p\n",
744 file, pInfoBuffer->secure_world_description);
745 result = -EFAULT;
746 goto exit;
747 }
748 break;
749 }
750
751 default:
752 dprintk(KERN_ERR "tf_device_ioctl(%p): "
753 "Unknown IOCTL code 0x%08x!\n",
754 file, ioctl_num);
755 result = -EOPNOTSUPP;
756 goto exit;
757 }
758
759exit:
760 return result;
761}
762
763/*----------------------------------------------------------------------------*/
764
765static int tf_device_shutdown(void)
766{
767
768 return tf_power_management(&g_tf_dev.sm,
769 TF_POWER_OPERATION_SHUTDOWN);
770}
771
772/*----------------------------------------------------------------------------*/
773
774static int tf_device_suspend(void)
775{
776 dprintk(KERN_INFO "tf_device_suspend: Enter\n");
777 return tf_power_management(&g_tf_dev.sm,
778 TF_POWER_OPERATION_HIBERNATE);
779}
780
781
782/*----------------------------------------------------------------------------*/
783
784static int tf_device_resume(void)
785{
786 return tf_power_management(&g_tf_dev.sm,
787 TF_POWER_OPERATION_RESUME);
788}
789
790
791/*----------------------------------------------------------------------------*/
792
793module_init(tf_device_register);
794
795MODULE_LICENSE("GPL");
796MODULE_AUTHOR("Trusted Logic S.A.");
diff --git a/security/tf_driver/tf_protocol.h b/security/tf_driver/tf_protocol.h
new file mode 100644
index 00000000000..403df8ec8ef
--- /dev/null
+++ b/security/tf_driver/tf_protocol.h
@@ -0,0 +1,690 @@
1/**
2 * Copyright (c) 2011 Trusted Logic S.A.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#ifndef __TF_PROTOCOL_H__
21#define __TF_PROTOCOL_H__
22
23/*----------------------------------------------------------------------------
24 *
25 * This header file defines the structure used in the SChannel Protocol.
26 * See your Product Reference Manual for a specification of the SChannel
27 * protocol.
28 *---------------------------------------------------------------------------*/
29
30/*
31 * The driver interface version returned by the version ioctl
32 */
33#define TF_DRIVER_INTERFACE_VERSION 0x04000000
34
35/*
36 * Protocol version handling
37 */
38#define TF_S_PROTOCOL_MAJOR_VERSION (0x06)
39#define GET_PROTOCOL_MAJOR_VERSION(a) (a >> 24)
40#define GET_PROTOCOL_MINOR_VERSION(a) ((a >> 16) & 0xFF)
41
42/*
43 * The S flag of the config_flag_s register.
44 */
45#define TF_CONFIG_FLAG_S (1 << 3)
46
47/*
48 * The TimeSlot field of the sync_serial_n register.
49 */
50#define TF_SYNC_SERIAL_TIMESLOT_N (1)
51
52/*
53 * status_s related defines.
54 */
55#define TF_STATUS_P_MASK (0X00000001)
56#define TF_STATUS_POWER_STATE_SHIFT (3)
57#define TF_STATUS_POWER_STATE_MASK (0x1F << TF_STATUS_POWER_STATE_SHIFT)
58
59/*
60 * Possible power states of the POWER_STATE field of the status_s register
61 */
62#define TF_POWER_MODE_COLD_BOOT (0)
63#define TF_POWER_MODE_WARM_BOOT (1)
64#define TF_POWER_MODE_ACTIVE (3)
65#define TF_POWER_MODE_READY_TO_SHUTDOWN (5)
66#define TF_POWER_MODE_READY_TO_HIBERNATE (7)
67#define TF_POWER_MODE_WAKEUP (8)
68#define TF_POWER_MODE_PANIC (15)
69
70/*
71 * Possible command values for MANAGEMENT commands
72 */
73#define TF_MANAGEMENT_HIBERNATE (1)
74#define TF_MANAGEMENT_SHUTDOWN (2)
75#define TF_MANAGEMENT_PREPARE_FOR_CORE_OFF (3)
76#define TF_MANAGEMENT_RESUME_FROM_CORE_OFF (4)
77
78/*
79 * The capacity of the Normal Word message queue, in number of slots.
80 */
81#define TF_N_MESSAGE_QUEUE_CAPACITY (512)
82
83/*
84 * The capacity of the Secure World message answer queue, in number of slots.
85 */
86#define TF_S_ANSWER_QUEUE_CAPACITY (256)
87
88/*
89 * The value of the S-timeout register indicating an infinite timeout.
90 */
91#define TF_S_TIMEOUT_0_INFINITE (0xFFFFFFFF)
92#define TF_S_TIMEOUT_1_INFINITE (0xFFFFFFFF)
93
94/*
95 * The value of the S-timeout register indicating an immediate timeout.
96 */
97#define TF_S_TIMEOUT_0_IMMEDIATE (0x0)
98#define TF_S_TIMEOUT_1_IMMEDIATE (0x0)
99
100/*
101 * Identifies the get protocol version SMC.
102 */
103#define TF_SMC_GET_PROTOCOL_VERSION (0XFFFFFFFB)
104
105/*
106 * Identifies the init SMC.
107 */
108#define TF_SMC_INIT (0XFFFFFFFF)
109
110/*
111 * Identifies the reset irq SMC.
112 */
113#define TF_SMC_RESET_IRQ (0xFFFFFFFE)
114
115/*
116 * Identifies the SET_W3B SMC.
117 */
118#define TF_SMC_WAKE_UP (0xFFFFFFFD)
119
120/*
121 * Identifies the STOP SMC.
122 */
123#define TF_SMC_STOP (0xFFFFFFFC)
124
125/*
126 * Identifies the n-yield SMC.
127 */
128#define TF_SMC_N_YIELD (0X00000003)
129
130
131/* Possible stop commands for SMC_STOP */
132#define SCSTOP_HIBERNATE (0xFFFFFFE1)
133#define SCSTOP_SHUTDOWN (0xFFFFFFE2)
134
135/*
136 * representation of an UUID.
137 */
138struct tf_uuid {
139 u32 time_low;
140 u16 time_mid;
141 u16 time_hi_and_version;
142 u8 clock_seq_and_node[8];
143};
144
145
146/**
147 * Command parameters.
148 */
149struct tf_command_param_value {
150 u32 a;
151 u32 b;
152};
153
154struct tf_command_param_temp_memref {
155 u32 descriptor; /* data pointer for exchange message.*/
156 u32 size;
157 u32 offset;
158};
159
160struct tf_command_param_memref {
161 u32 block;
162 u32 size;
163 u32 offset;
164};
165
166union tf_command_param {
167 struct tf_command_param_value value;
168 struct tf_command_param_temp_memref temp_memref;
169 struct tf_command_param_memref memref;
170};
171
172/**
173 * Answer parameters.
174 */
175struct tf_answer_param_value {
176 u32 a;
177 u32 b;
178};
179
180struct tf_answer_param_size {
181 u32 _ignored;
182 u32 size;
183};
184
185union tf_answer_param {
186 struct tf_answer_param_size size;
187 struct tf_answer_param_value value;
188};
189
190/*
191 * Descriptor tables capacity
192 */
193#define TF_MAX_W3B_COARSE_PAGES (2)
194/* TF_MAX_COARSE_PAGES is the number of level 1 descriptors (describing
195 * 1MB each) that can be shared with the secure world in a single registered
196 * shared memory block. It must be kept in synch with
197 * SCHANNEL6_MAX_DESCRIPTORS_PER_REGISTERED_SHARED_MEM in the SChannel
198 * protocol spec. */
199#define TF_MAX_COARSE_PAGES 128
200#define TF_DESCRIPTOR_TABLE_CAPACITY_BIT_SHIFT (8)
201#define TF_DESCRIPTOR_TABLE_CAPACITY \
202 (1 << TF_DESCRIPTOR_TABLE_CAPACITY_BIT_SHIFT)
203#define TF_DESCRIPTOR_TABLE_CAPACITY_MASK \
204 (TF_DESCRIPTOR_TABLE_CAPACITY - 1)
205/* Shared memories coarse pages can map up to 1MB */
206#define TF_MAX_COARSE_PAGE_MAPPED_SIZE \
207 (PAGE_SIZE * TF_DESCRIPTOR_TABLE_CAPACITY)
208/* Shared memories cannot exceed 8MB */
209#define TF_MAX_SHMEM_SIZE \
210 (TF_MAX_COARSE_PAGE_MAPPED_SIZE << 3)
211
212/*
213 * Buffer size for version description fields
214 */
215#define TF_DESCRIPTION_BUFFER_LENGTH 64
216
217/*
218 * Shared memory type flags.
219 */
220#define TF_SHMEM_TYPE_READ (0x00000001)
221#define TF_SHMEM_TYPE_WRITE (0x00000002)
222
223/*
224 * Shared mem flags
225 */
226#define TF_SHARED_MEM_FLAG_INPUT 1
227#define TF_SHARED_MEM_FLAG_OUTPUT 2
228#define TF_SHARED_MEM_FLAG_INOUT 3
229
230
231/*
232 * Parameter types
233 */
234#define TF_PARAM_TYPE_NONE 0x0
235#define TF_PARAM_TYPE_VALUE_INPUT 0x1
236#define TF_PARAM_TYPE_VALUE_OUTPUT 0x2
237#define TF_PARAM_TYPE_VALUE_INOUT 0x3
238#define TF_PARAM_TYPE_MEMREF_TEMP_INPUT 0x5
239#define TF_PARAM_TYPE_MEMREF_TEMP_OUTPUT 0x6
240#define TF_PARAM_TYPE_MEMREF_TEMP_INOUT 0x7
241#define TF_PARAM_TYPE_MEMREF_INPUT 0xD
242#define TF_PARAM_TYPE_MEMREF_OUTPUT 0xE
243#define TF_PARAM_TYPE_MEMREF_INOUT 0xF
244
245#define TF_PARAM_TYPE_MEMREF_FLAG 0x4
246#define TF_PARAM_TYPE_REGISTERED_MEMREF_FLAG 0x8
247
248
249#define TF_MAKE_PARAM_TYPES(t0, t1, t2, t3) \
250 ((t0) | ((t1) << 4) | ((t2) << 8) | ((t3) << 12))
251#define TF_GET_PARAM_TYPE(t, i) (((t) >> (4 * i)) & 0xF)
252
253/*
254 * Login types.
255 */
256#define TF_LOGIN_PUBLIC 0x00000000
257#define TF_LOGIN_USER 0x00000001
258#define TF_LOGIN_GROUP 0x00000002
259#define TF_LOGIN_APPLICATION 0x00000004
260#define TF_LOGIN_APPLICATION_USER 0x00000005
261#define TF_LOGIN_APPLICATION_GROUP 0x00000006
262#define TF_LOGIN_AUTHENTICATION 0x80000000
263#define TF_LOGIN_PRIVILEGED 0x80000002
264
265/* Login variants */
266
267#define TF_LOGIN_VARIANT(main_type, os, variant) \
268 ((main_type) | (1 << 27) | ((os) << 16) | ((variant) << 8))
269
270#define TF_LOGIN_GET_MAIN_TYPE(type) \
271 ((type) & ~TF_LOGIN_VARIANT(0, 0xFF, 0xFF))
272
273#define TF_LOGIN_OS_ANY 0x00
274#define TF_LOGIN_OS_LINUX 0x01
275#define TF_LOGIN_OS_ANDROID 0x04
276
277/* OS-independent variants */
278#define TF_LOGIN_USER_NONE \
279 TF_LOGIN_VARIANT(TF_LOGIN_USER, TF_LOGIN_OS_ANY, 0xFF)
280#define TF_LOGIN_GROUP_NONE \
281 TF_LOGIN_VARIANT(TF_LOGIN_GROUP, TF_LOGIN_OS_ANY, 0xFF)
282#define TF_LOGIN_APPLICATION_USER_NONE \
283 TF_LOGIN_VARIANT(TF_LOGIN_APPLICATION_USER, TF_LOGIN_OS_ANY, 0xFF)
284#define TF_LOGIN_AUTHENTICATION_BINARY_SHA1_HASH \
285 TF_LOGIN_VARIANT(TF_LOGIN_AUTHENTICATION, TF_LOGIN_OS_ANY, 0x01)
286#define TF_LOGIN_PRIVILEGED_KERNEL \
287 TF_LOGIN_VARIANT(TF_LOGIN_PRIVILEGED, TF_LOGIN_OS_ANY, 0x01)
288
289/* Linux variants */
290#define TF_LOGIN_USER_LINUX_EUID \
291 TF_LOGIN_VARIANT(TF_LOGIN_USER, TF_LOGIN_OS_LINUX, 0x01)
292#define TF_LOGIN_GROUP_LINUX_GID \
293 TF_LOGIN_VARIANT(TF_LOGIN_GROUP, TF_LOGIN_OS_LINUX, 0x01)
294#define TF_LOGIN_APPLICATION_LINUX_PATH_SHA1_HASH \
295 TF_LOGIN_VARIANT(TF_LOGIN_APPLICATION, TF_LOGIN_OS_LINUX, 0x01)
296#define TF_LOGIN_APPLICATION_USER_LINUX_PATH_EUID_SHA1_HASH \
297 TF_LOGIN_VARIANT(TF_LOGIN_APPLICATION_USER, TF_LOGIN_OS_LINUX, 0x01)
298#define TF_LOGIN_APPLICATION_GROUP_LINUX_PATH_GID_SHA1_HASH \
299 TF_LOGIN_VARIANT(TF_LOGIN_APPLICATION_GROUP, TF_LOGIN_OS_LINUX, 0x01)
300
301/* Android variants */
302#define TF_LOGIN_USER_ANDROID_EUID \
303 TF_LOGIN_VARIANT(TF_LOGIN_USER, TF_LOGIN_OS_ANDROID, 0x01)
304#define TF_LOGIN_GROUP_ANDROID_GID \
305 TF_LOGIN_VARIANT(TF_LOGIN_GROUP, TF_LOGIN_OS_ANDROID, 0x01)
306#define TF_LOGIN_APPLICATION_ANDROID_UID \
307 TF_LOGIN_VARIANT(TF_LOGIN_APPLICATION, TF_LOGIN_OS_ANDROID, 0x01)
308#define TF_LOGIN_APPLICATION_USER_ANDROID_UID_EUID \
309 TF_LOGIN_VARIANT(TF_LOGIN_APPLICATION_USER, TF_LOGIN_OS_ANDROID, \
310 0x01)
311#define TF_LOGIN_APPLICATION_GROUP_ANDROID_UID_GID \
312 TF_LOGIN_VARIANT(TF_LOGIN_APPLICATION_GROUP, TF_LOGIN_OS_ANDROID, \
313 0x01)
314
315/*
316 * return origins
317 */
318#define TF_ORIGIN_COMMS 2
319#define TF_ORIGIN_TEE 3
320#define TF_ORIGIN_TRUSTED_APP 4
321/*
322 * The message types.
323 */
324#define TF_MESSAGE_TYPE_CREATE_DEVICE_CONTEXT 0x02
325#define TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT 0xFD
326#define TF_MESSAGE_TYPE_REGISTER_SHARED_MEMORY 0xF7
327#define TF_MESSAGE_TYPE_RELEASE_SHARED_MEMORY 0xF9
328#define TF_MESSAGE_TYPE_OPEN_CLIENT_SESSION 0xF0
329#define TF_MESSAGE_TYPE_CLOSE_CLIENT_SESSION 0xF2
330#define TF_MESSAGE_TYPE_INVOKE_CLIENT_COMMAND 0xF5
331#define TF_MESSAGE_TYPE_CANCEL_CLIENT_COMMAND 0xF4
332#define TF_MESSAGE_TYPE_MANAGEMENT 0xFE
333
334
335/*
336 * The SChannel error codes.
337 */
338#define S_SUCCESS 0x00000000
339#define S_ERROR_OUT_OF_MEMORY 0xFFFF000C
340
341
342struct tf_command_header {
343 u8 message_size;
344 u8 message_type;
345 u16 message_info;
346 u32 operation_id;
347};
348
349struct tf_answer_header {
350 u8 message_size;
351 u8 message_type;
352 u16 message_info;
353 u32 operation_id;
354 u32 error_code;
355};
356
357/*
358 * CREATE_DEVICE_CONTEXT command message.
359 */
360struct tf_command_create_device_context {
361 u8 message_size;
362 u8 message_type;
363 u16 message_info_rfu;
364 u32 operation_id;
365 u32 device_context_id;
366};
367
368/*
369 * CREATE_DEVICE_CONTEXT answer message.
370 */
371struct tf_answer_create_device_context {
372 u8 message_size;
373 u8 message_type;
374 u16 message_info_rfu;
375 /* an opaque Normal World identifier for the operation */
376 u32 operation_id;
377 u32 error_code;
378 /* an opaque Normal World identifier for the device context */
379 u32 device_context;
380};
381
382/*
383 * DESTROY_DEVICE_CONTEXT command message.
384 */
385struct tf_command_destroy_device_context {
386 u8 message_size;
387 u8 message_type;
388 u16 message_info_rfu;
389 u32 operation_id;
390 u32 device_context;
391};
392
393/*
394 * DESTROY_DEVICE_CONTEXT answer message.
395 */
396struct tf_answer_destroy_device_context {
397 u8 message_size;
398 u8 message_type;
399 u16 message_info_rfu;
400 /* an opaque Normal World identifier for the operation */
401 u32 operation_id;
402 u32 error_code;
403 u32 device_context_id;
404};
405
406/*
407 * OPEN_CLIENT_SESSION command message.
408 */
409struct tf_command_open_client_session {
410 u8 message_size;
411 u8 message_type;
412 u16 param_types;
413 /* an opaque Normal World identifier for the operation */
414 u32 operation_id;
415 u32 device_context;
416 u32 cancellation_id;
417 u64 timeout;
418 struct tf_uuid destination_uuid;
419 union tf_command_param params[4];
420 u32 login_type;
421 /*
422 * Size = 0 for public, [16] for group identification, [20] for
423 * authentication
424 */
425 u8 login_data[20];
426};
427
428/*
429 * OPEN_CLIENT_SESSION answer message.
430 */
431struct tf_answer_open_client_session {
432 u8 message_size;
433 u8 message_type;
434 u8 error_origin;
435 u8 __reserved;
436 /* an opaque Normal World identifier for the operation */
437 u32 operation_id;
438 u32 error_code;
439 u32 client_session;
440 union tf_answer_param answers[4];
441};
442
443/*
444 * CLOSE_CLIENT_SESSION command message.
445 */
446struct tf_command_close_client_session {
447 u8 message_size;
448 u8 message_type;
449 u16 message_info_rfu;
450 /* an opaque Normal World identifier for the operation */
451 u32 operation_id;
452 u32 device_context;
453 u32 client_session;
454};
455
456/*
457 * CLOSE_CLIENT_SESSION answer message.
458 */
459struct tf_answer_close_client_session {
460 u8 message_size;
461 u8 message_type;
462 u16 message_info_rfu;
463 /* an opaque Normal World identifier for the operation */
464 u32 operation_id;
465 u32 error_code;
466};
467
468
469/*
470 * REGISTER_SHARED_MEMORY command message
471 */
472struct tf_command_register_shared_memory {
473 u8 message_size;
474 u8 message_type;
475 u16 memory_flags;
476 u32 operation_id;
477 u32 device_context;
478 u32 block_id;
479 u32 shared_mem_size;
480 u32 shared_mem_start_offset;
481 u32 shared_mem_descriptors[TF_MAX_COARSE_PAGES];
482};
483
484/*
485 * REGISTER_SHARED_MEMORY answer message.
486 */
487struct tf_answer_register_shared_memory {
488 u8 message_size;
489 u8 message_type;
490 u16 message_info_rfu;
491 /* an opaque Normal World identifier for the operation */
492 u32 operation_id;
493 u32 error_code;
494 u32 block;
495};
496
497/*
498 * RELEASE_SHARED_MEMORY command message.
499 */
500struct tf_command_release_shared_memory {
501 u8 message_size;
502 u8 message_type;
503 u16 message_info_rfu;
504 /* an opaque Normal World identifier for the operation */
505 u32 operation_id;
506 u32 device_context;
507 u32 block;
508};
509
510/*
511 * RELEASE_SHARED_MEMORY answer message.
512 */
513struct tf_answer_release_shared_memory {
514 u8 message_size;
515 u8 message_type;
516 u16 message_info_rfu;
517 u32 operation_id;
518 u32 error_code;
519 u32 block_id;
520};
521
522/*
523 * INVOKE_CLIENT_COMMAND command message.
524 */
525struct tf_command_invoke_client_command {
526 u8 message_size;
527 u8 message_type;
528 u16 param_types;
529 u32 operation_id;
530 u32 device_context;
531 u32 client_session;
532 u64 timeout;
533 u32 cancellation_id;
534 u32 client_command_identifier;
535 union tf_command_param params[4];
536};
537
538/*
539 * INVOKE_CLIENT_COMMAND command answer.
540 */
541struct tf_answer_invoke_client_command {
542 u8 message_size;
543 u8 message_type;
544 u8 error_origin;
545 u8 __reserved;
546 u32 operation_id;
547 u32 error_code;
548 union tf_answer_param answers[4];
549};
550
551/*
552 * CANCEL_CLIENT_OPERATION command message.
553 */
554struct tf_command_cancel_client_operation {
555 u8 message_size;
556 u8 message_type;
557 u16 message_info_rfu;
558 /* an opaque Normal World identifier for the operation */
559 u32 operation_id;
560 u32 device_context;
561 u32 client_session;
562 u32 cancellation_id;
563};
564
565struct tf_answer_cancel_client_operation {
566 u8 message_size;
567 u8 message_type;
568 u16 message_info_rfu;
569 u32 operation_id;
570 u32 error_code;
571};
572
573/*
574 * MANAGEMENT command message.
575 */
576struct tf_command_management {
577 u8 message_size;
578 u8 message_type;
579 u16 command;
580 u32 operation_id;
581 u32 w3b_size;
582 u32 w3b_start_offset;
583 u32 shared_mem_descriptors[1];
584};
585
586/*
587 * POWER_MANAGEMENT answer message.
588 * The message does not provide message specific parameters.
589 * Therefore no need to define a specific answer structure
590 */
591
592/*
593 * Structure for L2 messages
594 */
595union tf_command {
596 struct tf_command_header header;
597 struct tf_command_create_device_context create_device_context;
598 struct tf_command_destroy_device_context destroy_device_context;
599 struct tf_command_open_client_session open_client_session;
600 struct tf_command_close_client_session close_client_session;
601 struct tf_command_register_shared_memory register_shared_memory;
602 struct tf_command_release_shared_memory release_shared_memory;
603 struct tf_command_invoke_client_command invoke_client_command;
604 struct tf_command_cancel_client_operation cancel_client_operation;
605 struct tf_command_management management;
606};
607
608/*
609 * Structure for any L2 answer
610 */
611
612union tf_answer {
613 struct tf_answer_header header;
614 struct tf_answer_create_device_context create_device_context;
615 struct tf_answer_open_client_session open_client_session;
616 struct tf_answer_close_client_session close_client_session;
617 struct tf_answer_register_shared_memory register_shared_memory;
618 struct tf_answer_release_shared_memory release_shared_memory;
619 struct tf_answer_invoke_client_command invoke_client_command;
620 struct tf_answer_destroy_device_context destroy_device_context;
621 struct tf_answer_cancel_client_operation cancel_client_operation;
622};
623
624/* Structure of the Communication Buffer */
625struct tf_l1_shared_buffer {
626 #ifdef CONFIG_TF_ZEBRA
627 u32 exit_code;
628 u32 l1_shared_buffer_descr;
629 u32 backing_store_addr;
630 u32 backext_storage_addr;
631 u32 workspace_addr;
632 u32 workspace_size;
633 u32 conf_descriptor;
634 u32 conf_size;
635 u32 conf_offset;
636 u32 protocol_version;
637 u32 rpc_command;
638 u32 rpc_status;
639 u8 reserved1[16];
640 #else
641 u32 config_flag_s;
642 u32 w3b_size_max_s;
643 u32 reserved0;
644 u32 w3b_size_current_s;
645 u8 reserved1[48];
646 #endif
647 u8 version_description[TF_DESCRIPTION_BUFFER_LENGTH];
648 u32 status_s;
649 u32 reserved2;
650 u32 sync_serial_n;
651 u32 sync_serial_s;
652 u64 time_n[2];
653 u64 timeout_s[2];
654 u32 first_command;
655 u32 first_free_command;
656 u32 first_answer;
657 u32 first_free_answer;
658 u32 w3b_descriptors[128];
659 #ifdef CONFIG_TF_ZEBRA
660 u8 rpc_trace_buffer[140];
661 u8 rpc_cus_buffer[180];
662 #else
663 u8 reserved3[320];
664 #endif
665 u32 command_queue[TF_N_MESSAGE_QUEUE_CAPACITY];
666 u32 answer_queue[TF_S_ANSWER_QUEUE_CAPACITY];
667};
668
669
670/*
671 * tf_version_information_buffer structure description
672 * Description of the sVersionBuffer handed over from user space to kernel space
673 * This field is filled by the driver during a CREATE_DEVICE_CONTEXT ioctl
674 * and handed back to user space
675 */
676struct tf_version_information_buffer {
677 u8 driver_description[65];
678 u8 secure_world_description[65];
679};
680
681
682/* The IOCTLs the driver supports */
683#include <linux/ioctl.h>
684
685#define IOCTL_TF_GET_VERSION _IO('z', 0)
686#define IOCTL_TF_EXCHANGE _IOWR('z', 1, union tf_command)
687#define IOCTL_TF_GET_DESCRIPTION _IOR('z', 2, \
688 struct tf_version_information_buffer)
689
690#endif /* !defined(__TF_PROTOCOL_H__) */
diff --git a/security/tf_driver/tf_util.c b/security/tf_driver/tf_util.c
new file mode 100644
index 00000000000..78f90bf677e
--- /dev/null
+++ b/security/tf_driver/tf_util.c
@@ -0,0 +1,1143 @@
1/**
2 * Copyright (c) 2011 Trusted Logic S.A.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#include <linux/mman.h>
21#include "tf_util.h"
22
23/*----------------------------------------------------------------------------
24 * Debug printing routines
25 *----------------------------------------------------------------------------*/
26#ifdef CONFIG_TF_DRIVER_DEBUG_SUPPORT
27
28void tf_trace_array(const char *fun, const char *msg,
29 const void *ptr, size_t len)
30{
31 char hex[511];
32 bool ell = (len > sizeof(hex)/2);
33 unsigned lim = (len > sizeof(hex)/2 ? sizeof(hex)/2 : len);
34 unsigned i;
35 for (i = 0; i < lim; i++)
36 sprintf(hex + 2 * i, "%02x", ((unsigned char *)ptr)[i]);
37 pr_info("%s: %s[%u] = %s%s\n",
38 fun, msg, len, hex, ell ? "..." : "");
39}
40
41void address_cache_property(unsigned long va)
42{
43 unsigned long pa;
44 unsigned long inner;
45 unsigned long outer;
46
47 asm volatile ("mcr p15, 0, %0, c7, c8, 0" : : "r" (va));
48 asm volatile ("mrc p15, 0, %0, c7, c4, 0" : "=r" (pa));
49
50 dprintk(KERN_INFO "VA:%x, PA:%x\n",
51 (unsigned int) va,
52 (unsigned int) pa);
53
54 if (pa & 1) {
55 dprintk(KERN_INFO "Prop Error\n");
56 return;
57 }
58
59 outer = (pa >> 2) & 3;
60 dprintk(KERN_INFO "\touter : %x", (unsigned int) outer);
61
62 switch (outer) {
63 case 3:
64 dprintk(KERN_INFO "Write-Back, no Write-Allocate\n");
65 break;
66 case 2:
67 dprintk(KERN_INFO "Write-Through, no Write-Allocate.\n");
68 break;
69 case 1:
70 dprintk(KERN_INFO "Write-Back, Write-Allocate.\n");
71 break;
72 case 0:
73 dprintk(KERN_INFO "Non-cacheable.\n");
74 break;
75 }
76
77 inner = (pa >> 4) & 7;
78 dprintk(KERN_INFO "\tinner : %x", (unsigned int)inner);
79
80 switch (inner) {
81 case 7:
82 dprintk(KERN_INFO "Write-Back, no Write-Allocate\n");
83 break;
84 case 6:
85 dprintk(KERN_INFO "Write-Through.\n");
86 break;
87 case 5:
88 dprintk(KERN_INFO "Write-Back, Write-Allocate.\n");
89 break;
90 case 3:
91 dprintk(KERN_INFO "Device.\n");
92 break;
93 case 1:
94 dprintk(KERN_INFO "Strongly-ordered.\n");
95 break;
96 case 0:
97 dprintk(KERN_INFO "Non-cacheable.\n");
98 break;
99 }
100
101 if (pa & 0x00000002)
102 dprintk(KERN_INFO "SuperSection.\n");
103 if (pa & 0x00000080)
104 dprintk(KERN_INFO "Memory is shareable.\n");
105 else
106 dprintk(KERN_INFO "Memory is non-shareable.\n");
107
108 if (pa & 0x00000200)
109 dprintk(KERN_INFO "Non-secure.\n");
110}
111
112/*
113 * Dump the L1 shared buffer.
114 */
115void tf_dump_l1_shared_buffer(struct tf_l1_shared_buffer *buffer)
116{
117 dprintk(KERN_INFO
118 "buffer@%p:\n"
119 #ifndef CONFIG_TF_ZEBRA
120 " config_flag_s=%08X\n"
121 #endif
122 " version_description=%64s\n"
123 " status_s=%08X\n"
124 " sync_serial_n=%08X\n"
125 " sync_serial_s=%08X\n"
126 " time_n[0]=%016llX\n"
127 " time_n[1]=%016llX\n"
128 " timeout_s[0]=%016llX\n"
129 " timeout_s[1]=%016llX\n"
130 " first_command=%08X\n"
131 " first_free_command=%08X\n"
132 " first_answer=%08X\n"
133 " first_free_answer=%08X\n\n",
134 buffer,
135 #ifndef CONFIG_TF_ZEBRA
136 buffer->config_flag_s,
137 #endif
138 buffer->version_description,
139 buffer->status_s,
140 buffer->sync_serial_n,
141 buffer->sync_serial_s,
142 buffer->time_n[0],
143 buffer->time_n[1],
144 buffer->timeout_s[0],
145 buffer->timeout_s[1],
146 buffer->first_command,
147 buffer->first_free_command,
148 buffer->first_answer,
149 buffer->first_free_answer);
150}
151
152
153/*
154 * Dump the specified SChannel message using dprintk.
155 */
156void tf_dump_command(union tf_command *command)
157{
158 u32 i;
159
160 dprintk(KERN_INFO "message@%p:\n", command);
161
162 switch (command->header.message_type) {
163 case TF_MESSAGE_TYPE_CREATE_DEVICE_CONTEXT:
164 dprintk(KERN_INFO
165 " message_size = 0x%02X\n"
166 " message_type = 0x%02X "
167 "TF_MESSAGE_TYPE_CREATE_DEVICE_CONTEXT\n"
168 " operation_id = 0x%08X\n"
169 " device_context_id = 0x%08X\n",
170 command->header.message_size,
171 command->header.message_type,
172 command->header.operation_id,
173 command->create_device_context.device_context_id
174 );
175 break;
176
177 case TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT:
178 dprintk(KERN_INFO
179 " message_size = 0x%02X\n"
180 " message_type = 0x%02X "
181 "TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT\n"
182 " operation_id = 0x%08X\n"
183 " device_context = 0x%08X\n",
184 command->header.message_size,
185 command->header.message_type,
186 command->header.operation_id,
187 command->destroy_device_context.device_context);
188 break;
189
190 case TF_MESSAGE_TYPE_OPEN_CLIENT_SESSION:
191 dprintk(KERN_INFO
192 " message_size = 0x%02X\n"
193 " message_type = 0x%02X "
194 "TF_MESSAGE_TYPE_OPEN_CLIENT_SESSION\n"
195 " param_types = 0x%04X\n"
196 " operation_id = 0x%08X\n"
197 " device_context = 0x%08X\n"
198 " cancellation_id = 0x%08X\n"
199 " timeout = 0x%016llX\n"
200 " destination_uuid = "
201 "%08X-%04X-%04X-%02X%02X-"
202 "%02X%02X%02X%02X%02X%02X\n",
203 command->header.message_size,
204 command->header.message_type,
205 command->open_client_session.param_types,
206 command->header.operation_id,
207 command->open_client_session.device_context,
208 command->open_client_session.cancellation_id,
209 command->open_client_session.timeout,
210 command->open_client_session.destination_uuid.
211 time_low,
212 command->open_client_session.destination_uuid.
213 time_mid,
214 command->open_client_session.destination_uuid.
215 time_hi_and_version,
216 command->open_client_session.destination_uuid.
217 clock_seq_and_node[0],
218 command->open_client_session.destination_uuid.
219 clock_seq_and_node[1],
220 command->open_client_session.destination_uuid.
221 clock_seq_and_node[2],
222 command->open_client_session.destination_uuid.
223 clock_seq_and_node[3],
224 command->open_client_session.destination_uuid.
225 clock_seq_and_node[4],
226 command->open_client_session.destination_uuid.
227 clock_seq_and_node[5],
228 command->open_client_session.destination_uuid.
229 clock_seq_and_node[6],
230 command->open_client_session.destination_uuid.
231 clock_seq_and_node[7]
232 );
233
234 for (i = 0; i < 4; i++) {
235 uint32_t *param = (uint32_t *) &command->
236 open_client_session.params[i];
237 dprintk(KERN_INFO " params[%d] = "
238 "0x%08X:0x%08X:0x%08X\n",
239 i, param[0], param[1], param[2]);
240 }
241
242 switch (TF_LOGIN_GET_MAIN_TYPE(
243 command->open_client_session.login_type)) {
244 case TF_LOGIN_PUBLIC:
245 dprintk(
246 KERN_INFO " login_type = "
247 "TF_LOGIN_PUBLIC\n");
248 break;
249 case TF_LOGIN_USER:
250 dprintk(
251 KERN_INFO " login_type = "
252 "TF_LOGIN_USER\n");
253 break;
254 case TF_LOGIN_GROUP:
255 dprintk(
256 KERN_INFO " login_type = "
257 "TF_LOGIN_GROUP\n");
258 break;
259 case TF_LOGIN_APPLICATION:
260 dprintk(
261 KERN_INFO " login_type = "
262 "TF_LOGIN_APPLICATION\n");
263 break;
264 case TF_LOGIN_APPLICATION_USER:
265 dprintk(
266 KERN_INFO " login_type = "
267 "TF_LOGIN_APPLICATION_USER\n");
268 break;
269 case TF_LOGIN_APPLICATION_GROUP:
270 dprintk(
271 KERN_INFO " login_type = "
272 "TF_LOGIN_APPLICATION_GROUP\n");
273 break;
274 case TF_LOGIN_AUTHENTICATION:
275 dprintk(
276 KERN_INFO " login_type = "
277 "TF_LOGIN_AUTHENTICATION\n");
278 break;
279 case TF_LOGIN_PRIVILEGED:
280 dprintk(
281 KERN_INFO " login_type = "
282 "TF_LOGIN_PRIVILEGED\n");
283 break;
284 case TF_LOGIN_PRIVILEGED_KERNEL:
285 dprintk(
286 KERN_INFO " login_type = "
287 "TF_LOGIN_PRIVILEGED_KERNEL\n");
288 break;
289 default:
290 dprintk(
291 KERN_ERR " login_type = "
292 "0x%08X (Unknown login type)\n",
293 command->open_client_session.login_type);
294 break;
295 }
296
297 dprintk(
298 KERN_INFO " login_data = ");
299 for (i = 0; i < 20; i++)
300 dprintk(
301 KERN_INFO "%d",
302 command->open_client_session.
303 login_data[i]);
304 dprintk("\n");
305 break;
306
307 case TF_MESSAGE_TYPE_CLOSE_CLIENT_SESSION:
308 dprintk(KERN_INFO
309 " message_size = 0x%02X\n"
310 " message_type = 0x%02X "
311 "TF_MESSAGE_TYPE_CLOSE_CLIENT_SESSION\n"
312 " operation_id = 0x%08X\n"
313 " device_context = 0x%08X\n"
314 " client_session = 0x%08X\n",
315 command->header.message_size,
316 command->header.message_type,
317 command->header.operation_id,
318 command->close_client_session.device_context,
319 command->close_client_session.client_session
320 );
321 break;
322
323 case TF_MESSAGE_TYPE_REGISTER_SHARED_MEMORY:
324 dprintk(KERN_INFO
325 " message_size = 0x%02X\n"
326 " message_type = 0x%02X "
327 "TF_MESSAGE_TYPE_REGISTER_SHARED_MEMORY\n"
328 " memory_flags = 0x%04X\n"
329 " operation_id = 0x%08X\n"
330 " device_context = 0x%08X\n"
331 " block_id = 0x%08X\n"
332 " shared_mem_size = 0x%08X\n"
333 " shared_mem_start_offset = 0x%08X\n"
334 " shared_mem_descriptors[0] = 0x%08X\n"
335 " shared_mem_descriptors[1] = 0x%08X\n"
336 " shared_mem_descriptors[2] = 0x%08X\n"
337 " shared_mem_descriptors[3] = 0x%08X\n"
338 " shared_mem_descriptors[4] = 0x%08X\n"
339 " shared_mem_descriptors[5] = 0x%08X\n"
340 " shared_mem_descriptors[6] = 0x%08X\n"
341 " shared_mem_descriptors[7] = 0x%08X\n",
342 command->header.message_size,
343 command->header.message_type,
344 command->register_shared_memory.memory_flags,
345 command->header.operation_id,
346 command->register_shared_memory.device_context,
347 command->register_shared_memory.block_id,
348 command->register_shared_memory.shared_mem_size,
349 command->register_shared_memory.
350 shared_mem_start_offset,
351 command->register_shared_memory.
352 shared_mem_descriptors[0],
353 command->register_shared_memory.
354 shared_mem_descriptors[1],
355 command->register_shared_memory.
356 shared_mem_descriptors[2],
357 command->register_shared_memory.
358 shared_mem_descriptors[3],
359 command->register_shared_memory.
360 shared_mem_descriptors[4],
361 command->register_shared_memory.
362 shared_mem_descriptors[5],
363 command->register_shared_memory.
364 shared_mem_descriptors[6],
365 command->register_shared_memory.
366 shared_mem_descriptors[7]);
367 break;
368
369 case TF_MESSAGE_TYPE_RELEASE_SHARED_MEMORY:
370 dprintk(KERN_INFO
371 " message_size = 0x%02X\n"
372 " message_type = 0x%02X "
373 "TF_MESSAGE_TYPE_RELEASE_SHARED_MEMORY\n"
374 " operation_id = 0x%08X\n"
375 " device_context = 0x%08X\n"
376 " block = 0x%08X\n",
377 command->header.message_size,
378 command->header.message_type,
379 command->header.operation_id,
380 command->release_shared_memory.device_context,
381 command->release_shared_memory.block);
382 break;
383
384 case TF_MESSAGE_TYPE_INVOKE_CLIENT_COMMAND:
385 dprintk(KERN_INFO
386 " message_size = 0x%02X\n"
387 " message_type = 0x%02X "
388 "TF_MESSAGE_TYPE_INVOKE_CLIENT_COMMAND\n"
389 " param_types = 0x%04X\n"
390 " operation_id = 0x%08X\n"
391 " device_context = 0x%08X\n"
392 " client_session = 0x%08X\n"
393 " timeout = 0x%016llX\n"
394 " cancellation_id = 0x%08X\n"
395 " client_command_identifier = 0x%08X\n",
396 command->header.message_size,
397 command->header.message_type,
398 command->invoke_client_command.param_types,
399 command->header.operation_id,
400 command->invoke_client_command.device_context,
401 command->invoke_client_command.client_session,
402 command->invoke_client_command.timeout,
403 command->invoke_client_command.cancellation_id,
404 command->invoke_client_command.
405 client_command_identifier
406 );
407
408 for (i = 0; i < 4; i++) {
409 uint32_t *param = (uint32_t *) &command->
410 open_client_session.params[i];
411 dprintk(KERN_INFO " params[%d] = "
412 "0x%08X:0x%08X:0x%08X\n", i,
413 param[0], param[1], param[2]);
414 }
415 break;
416
417 case TF_MESSAGE_TYPE_CANCEL_CLIENT_COMMAND:
418 dprintk(KERN_INFO
419 " message_size = 0x%02X\n"
420 " message_type = 0x%02X "
421 "TF_MESSAGE_TYPE_CANCEL_CLIENT_COMMAND\n"
422 " operation_id = 0x%08X\n"
423 " device_context = 0x%08X\n"
424 " client_session = 0x%08X\n",
425 command->header.message_size,
426 command->header.message_type,
427 command->header.operation_id,
428 command->cancel_client_operation.device_context,
429 command->cancel_client_operation.client_session);
430 break;
431
432 case TF_MESSAGE_TYPE_MANAGEMENT:
433 dprintk(KERN_INFO
434 " message_size = 0x%02X\n"
435 " message_type = 0x%02X "
436 "TF_MESSAGE_TYPE_MANAGEMENT\n"
437 " operation_id = 0x%08X\n"
438 " command = 0x%08X\n"
439 " w3b_size = 0x%08X\n"
440 " w3b_start_offset = 0x%08X\n",
441 command->header.message_size,
442 command->header.message_type,
443 command->header.operation_id,
444 command->management.command,
445 command->management.w3b_size,
446 command->management.w3b_start_offset);
447 break;
448
449 default:
450 dprintk(
451 KERN_ERR " message_type = 0x%08X "
452 "(Unknown message type)\n",
453 command->header.message_type);
454 break;
455 }
456}
457
458
459/*
460 * Dump the specified SChannel answer using dprintk.
461 */
462void tf_dump_answer(union tf_answer *answer)
463{
464 u32 i;
465 dprintk(
466 KERN_INFO "answer@%p:\n",
467 answer);
468
469 switch (answer->header.message_type) {
470 case TF_MESSAGE_TYPE_CREATE_DEVICE_CONTEXT:
471 dprintk(KERN_INFO
472 " message_size = 0x%02X\n"
473 " message_type = 0x%02X "
474 "tf_answer_create_device_context\n"
475 " operation_id = 0x%08X\n"
476 " error_code = 0x%08X\n"
477 " device_context = 0x%08X\n",
478 answer->header.message_size,
479 answer->header.message_type,
480 answer->header.operation_id,
481 answer->create_device_context.error_code,
482 answer->create_device_context.device_context);
483 break;
484
485 case TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT:
486 dprintk(KERN_INFO
487 " message_size = 0x%02X\n"
488 " message_type = 0x%02X "
489 "ANSWER_DESTROY_DEVICE_CONTEXT\n"
490 " operation_id = 0x%08X\n"
491 " error_code = 0x%08X\n"
492 " device_context_id = 0x%08X\n",
493 answer->header.message_size,
494 answer->header.message_type,
495 answer->header.operation_id,
496 answer->destroy_device_context.error_code,
497 answer->destroy_device_context.device_context_id);
498 break;
499
500
501 case TF_MESSAGE_TYPE_OPEN_CLIENT_SESSION:
502 dprintk(KERN_INFO
503 " message_size = 0x%02X\n"
504 " message_type = 0x%02X "
505 "tf_answer_open_client_session\n"
506 " error_origin = 0x%02X\n"
507 " operation_id = 0x%08X\n"
508 " error_code = 0x%08X\n"
509 " client_session = 0x%08X\n",
510 answer->header.message_size,
511 answer->header.message_type,
512 answer->open_client_session.error_origin,
513 answer->header.operation_id,
514 answer->open_client_session.error_code,
515 answer->open_client_session.client_session);
516 for (i = 0; i < 4; i++) {
517 dprintk(KERN_INFO " answers[%d]=0x%08X:0x%08X\n",
518 i,
519 answer->open_client_session.answers[i].
520 value.a,
521 answer->open_client_session.answers[i].
522 value.b);
523 }
524 break;
525
526 case TF_MESSAGE_TYPE_CLOSE_CLIENT_SESSION:
527 dprintk(KERN_INFO
528 " message_size = 0x%02X\n"
529 " message_type = 0x%02X "
530 "ANSWER_CLOSE_CLIENT_SESSION\n"
531 " operation_id = 0x%08X\n"
532 " error_code = 0x%08X\n",
533 answer->header.message_size,
534 answer->header.message_type,
535 answer->header.operation_id,
536 answer->close_client_session.error_code);
537 break;
538
539 case TF_MESSAGE_TYPE_REGISTER_SHARED_MEMORY:
540 dprintk(KERN_INFO
541 " message_size = 0x%02X\n"
542 " message_type = 0x%02X "
543 "tf_answer_register_shared_memory\n"
544 " operation_id = 0x%08X\n"
545 " error_code = 0x%08X\n"
546 " block = 0x%08X\n",
547 answer->header.message_size,
548 answer->header.message_type,
549 answer->header.operation_id,
550 answer->register_shared_memory.error_code,
551 answer->register_shared_memory.block);
552 break;
553
554 case TF_MESSAGE_TYPE_RELEASE_SHARED_MEMORY:
555 dprintk(KERN_INFO
556 " message_size = 0x%02X\n"
557 " message_type = 0x%02X "
558 "ANSWER_RELEASE_SHARED_MEMORY\n"
559 " operation_id = 0x%08X\n"
560 " error_code = 0x%08X\n"
561 " block_id = 0x%08X\n",
562 answer->header.message_size,
563 answer->header.message_type,
564 answer->header.operation_id,
565 answer->release_shared_memory.error_code,
566 answer->release_shared_memory.block_id);
567 break;
568
569 case TF_MESSAGE_TYPE_INVOKE_CLIENT_COMMAND:
570 dprintk(KERN_INFO
571 " message_size = 0x%02X\n"
572 " message_type = 0x%02X "
573 "tf_answer_invoke_client_command\n"
574 " error_origin = 0x%02X\n"
575 " operation_id = 0x%08X\n"
576 " error_code = 0x%08X\n",
577 answer->header.message_size,
578 answer->header.message_type,
579 answer->invoke_client_command.error_origin,
580 answer->header.operation_id,
581 answer->invoke_client_command.error_code
582 );
583 for (i = 0; i < 4; i++) {
584 dprintk(KERN_INFO " answers[%d]=0x%08X:0x%08X\n",
585 i,
586 answer->invoke_client_command.answers[i].
587 value.a,
588 answer->invoke_client_command.answers[i].
589 value.b);
590 }
591 break;
592
593 case TF_MESSAGE_TYPE_CANCEL_CLIENT_COMMAND:
594 dprintk(KERN_INFO
595 " message_size = 0x%02X\n"
596 " message_type = 0x%02X "
597 "TF_ANSWER_CANCEL_CLIENT_COMMAND\n"
598 " operation_id = 0x%08X\n"
599 " error_code = 0x%08X\n",
600 answer->header.message_size,
601 answer->header.message_type,
602 answer->header.operation_id,
603 answer->cancel_client_operation.error_code);
604 break;
605
606 case TF_MESSAGE_TYPE_MANAGEMENT:
607 dprintk(KERN_INFO
608 " message_size = 0x%02X\n"
609 " message_type = 0x%02X "
610 "TF_MESSAGE_TYPE_MANAGEMENT\n"
611 " operation_id = 0x%08X\n"
612 " error_code = 0x%08X\n",
613 answer->header.message_size,
614 answer->header.message_type,
615 answer->header.operation_id,
616 answer->header.error_code);
617 break;
618
619 default:
620 dprintk(
621 KERN_ERR " message_type = 0x%02X "
622 "(Unknown message type)\n",
623 answer->header.message_type);
624 break;
625
626 }
627}
628
629#endif /* defined(TF_DRIVER_DEBUG_SUPPORT) */
630
631/*----------------------------------------------------------------------------
632 * SHA-1 implementation
633 * This is taken from the Linux kernel source crypto/sha1.c
634 *----------------------------------------------------------------------------*/
635
636struct sha1_ctx {
637 u64 count;
638 u32 state[5];
639 u8 buffer[64];
640};
641
642static inline u32 rol(u32 value, u32 bits)
643{
644 return ((value) << (bits)) | ((value) >> (32 - (bits)));
645}
646
647/* blk0() and blk() perform the initial expand. */
648/* I got the idea of expanding during the round function from SSLeay */
649#define blk0(i) block32[i]
650
651#define blk(i) (block32[i & 15] = rol( \
652 block32[(i + 13) & 15] ^ block32[(i + 8) & 15] ^ \
653 block32[(i + 2) & 15] ^ block32[i & 15], 1))
654
655/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
656#define R0(v, w, x, y, z, i) do { \
657 z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
658 w = rol(w, 30); } while (0)
659
660#define R1(v, w, x, y, z, i) do { \
661 z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
662 w = rol(w, 30); } while (0)
663
664#define R2(v, w, x, y, z, i) do { \
665 z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
666 w = rol(w, 30); } while (0)
667
668#define R3(v, w, x, y, z, i) do { \
669 z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
670 w = rol(w, 30); } while (0)
671
672#define R4(v, w, x, y, z, i) do { \
673 z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
674 w = rol(w, 30); } while (0)
675
676
677/* Hash a single 512-bit block. This is the core of the algorithm. */
678static void sha1_transform(u32 *state, const u8 *in)
679{
680 u32 a, b, c, d, e;
681 u32 block32[16];
682
683 /* convert/copy data to workspace */
684 for (a = 0; a < sizeof(block32)/sizeof(u32); a++)
685 block32[a] = ((u32) in[4 * a]) << 24 |
686 ((u32) in[4 * a + 1]) << 16 |
687 ((u32) in[4 * a + 2]) << 8 |
688 ((u32) in[4 * a + 3]);
689
690 /* Copy context->state[] to working vars */
691 a = state[0];
692 b = state[1];
693 c = state[2];
694 d = state[3];
695 e = state[4];
696
697 /* 4 rounds of 20 operations each. Loop unrolled. */
698 R0(a, b, c, d, e, 0); R0(e, a, b, c, d, 1);
699 R0(d, e, a, b, c, 2); R0(c, d, e, a, b, 3);
700 R0(b, c, d, e, a, 4); R0(a, b, c, d, e, 5);
701 R0(e, a, b, c, d, 6); R0(d, e, a, b, c, 7);
702 R0(c, d, e, a, b, 8); R0(b, c, d, e, a, 9);
703 R0(a, b, c, d, e, 10); R0(e, a, b, c, d, 11);
704 R0(d, e, a, b, c, 12); R0(c, d, e, a, b, 13);
705 R0(b, c, d, e, a, 14); R0(a, b, c, d, e, 15);
706
707 R1(e, a, b, c, d, 16); R1(d, e, a, b, c, 17);
708 R1(c, d, e, a, b, 18); R1(b, c, d, e, a, 19);
709
710 R2(a, b, c, d, e, 20); R2(e, a, b, c, d, 21);
711 R2(d, e, a, b, c, 22); R2(c, d, e, a, b, 23);
712 R2(b, c, d, e, a, 24); R2(a, b, c, d, e, 25);
713 R2(e, a, b, c, d, 26); R2(d, e, a, b, c, 27);
714 R2(c, d, e, a, b, 28); R2(b, c, d, e, a, 29);
715 R2(a, b, c, d, e, 30); R2(e, a, b, c, d, 31);
716 R2(d, e, a, b, c, 32); R2(c, d, e, a, b, 33);
717 R2(b, c, d, e, a, 34); R2(a, b, c, d, e, 35);
718 R2(e, a, b, c, d, 36); R2(d, e, a, b, c, 37);
719 R2(c, d, e, a, b, 38); R2(b, c, d, e, a, 39);
720
721 R3(a, b, c, d, e, 40); R3(e, a, b, c, d, 41);
722 R3(d, e, a, b, c, 42); R3(c, d, e, a, b, 43);
723 R3(b, c, d, e, a, 44); R3(a, b, c, d, e, 45);
724 R3(e, a, b, c, d, 46); R3(d, e, a, b, c, 47);
725 R3(c, d, e, a, b, 48); R3(b, c, d, e, a, 49);
726 R3(a, b, c, d, e, 50); R3(e, a, b, c, d, 51);
727 R3(d, e, a, b, c, 52); R3(c, d, e, a, b, 53);
728 R3(b, c, d, e, a, 54); R3(a, b, c, d, e, 55);
729 R3(e, a, b, c, d, 56); R3(d, e, a, b, c, 57);
730 R3(c, d, e, a, b, 58); R3(b, c, d, e, a, 59);
731
732 R4(a, b, c, d, e, 60); R4(e, a, b, c, d, 61);
733 R4(d, e, a, b, c, 62); R4(c, d, e, a, b, 63);
734 R4(b, c, d, e, a, 64); R4(a, b, c, d, e, 65);
735 R4(e, a, b, c, d, 66); R4(d, e, a, b, c, 67);
736 R4(c, d, e, a, b, 68); R4(b, c, d, e, a, 69);
737 R4(a, b, c, d, e, 70); R4(e, a, b, c, d, 71);
738 R4(d, e, a, b, c, 72); R4(c, d, e, a, b, 73);
739 R4(b, c, d, e, a, 74); R4(a, b, c, d, e, 75);
740 R4(e, a, b, c, d, 76); R4(d, e, a, b, c, 77);
741 R4(c, d, e, a, b, 78); R4(b, c, d, e, a, 79);
742
743 /* Add the working vars back into context.state[] */
744 state[0] += a;
745 state[1] += b;
746 state[2] += c;
747 state[3] += d;
748 state[4] += e;
749 /* Wipe variables */
750 a = b = c = d = e = 0;
751 memset(block32, 0x00, sizeof(block32));
752}
753
754
755static void sha1_init(void *ctx)
756{
757 struct sha1_ctx *sctx = ctx;
758 static const struct sha1_ctx initstate = {
759 0,
760 { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 },
761 { 0, }
762 };
763
764 *sctx = initstate;
765}
766
767
768static void sha1_update(void *ctx, const u8 *data, unsigned int len)
769{
770 struct sha1_ctx *sctx = ctx;
771 unsigned int i, j;
772
773 j = (sctx->count >> 3) & 0x3f;
774 sctx->count += len << 3;
775
776 if ((j + len) > 63) {
777 memcpy(&sctx->buffer[j], data, (i = 64 - j));
778 sha1_transform(sctx->state, sctx->buffer);
779 for ( ; i + 63 < len; i += 64)
780 sha1_transform(sctx->state, &data[i]);
781 j = 0;
782 } else
783 i = 0;
784 memcpy(&sctx->buffer[j], &data[i], len - i);
785}
786
787
788/* Add padding and return the message digest. */
789static void sha1_final(void *ctx, u8 *out)
790{
791 struct sha1_ctx *sctx = ctx;
792 u32 i, j, index, padlen;
793 u64 t;
794 u8 bits[8] = { 0, };
795 static const u8 padding[64] = { 0x80, };
796
797 t = sctx->count;
798 bits[7] = 0xff & t; t >>= 8;
799 bits[6] = 0xff & t; t >>= 8;
800 bits[5] = 0xff & t; t >>= 8;
801 bits[4] = 0xff & t; t >>= 8;
802 bits[3] = 0xff & t; t >>= 8;
803 bits[2] = 0xff & t; t >>= 8;
804 bits[1] = 0xff & t; t >>= 8;
805 bits[0] = 0xff & t;
806
807 /* Pad out to 56 mod 64 */
808 index = (sctx->count >> 3) & 0x3f;
809 padlen = (index < 56) ? (56 - index) : ((64+56) - index);
810 sha1_update(sctx, padding, padlen);
811
812 /* Append length */
813 sha1_update(sctx, bits, sizeof(bits));
814
815 /* Store state in digest */
816 for (i = j = 0; i < 5; i++, j += 4) {
817 u32 t2 = sctx->state[i];
818 out[j+3] = t2 & 0xff; t2 >>= 8;
819 out[j+2] = t2 & 0xff; t2 >>= 8;
820 out[j+1] = t2 & 0xff; t2 >>= 8;
821 out[j] = t2 & 0xff;
822 }
823
824 /* Wipe context */
825 memset(sctx, 0, sizeof(*sctx));
826}
827
828
829
830
831/*----------------------------------------------------------------------------
832 * Process identification
833 *----------------------------------------------------------------------------*/
834
835/* This function generates a processes hash table for authentication */
836int tf_get_current_process_hash(void *hash)
837{
838 int result = 0;
839 void *buffer;
840 struct mm_struct *mm;
841 struct vm_area_struct *vma;
842
843 buffer = internal_kmalloc(PAGE_SIZE, GFP_KERNEL);
844 if (buffer == NULL) {
845 dprintk(
846 KERN_ERR "tf_get_current_process_hash:"
847 " Out of memory for buffer!\n");
848 return -ENOMEM;
849 }
850
851 mm = current->mm;
852
853 down_read(&(mm->mmap_sem));
854 for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) {
855 if ((vma->vm_flags & VM_EXECUTABLE) != 0 && vma->vm_file
856 != NULL) {
857 struct dentry *dentry;
858 unsigned long start;
859 unsigned long cur;
860 unsigned long end;
861 struct sha1_ctx sha1;
862
863 dentry = dget(vma->vm_file->f_dentry);
864
865 dprintk(
866 KERN_DEBUG "tf_get_current_process_hash: "
867 "Found executable VMA for inode %lu "
868 "(%lu bytes).\n",
869 dentry->d_inode->i_ino,
870 (unsigned long) (dentry->d_inode->
871 i_size));
872
873 start = do_mmap(vma->vm_file, 0,
874 dentry->d_inode->i_size,
875 PROT_READ | PROT_WRITE | PROT_EXEC,
876 MAP_PRIVATE, 0);
877 if (start < 0) {
878 dprintk(
879 KERN_ERR "tf_get_current_process_hash"
880 "Hash: do_mmap failed (error %d)!\n",
881 (int) start);
882 dput(dentry);
883 result = -EFAULT;
884 goto vma_out;
885 }
886
887 end = start + dentry->d_inode->i_size;
888
889 sha1_init(&sha1);
890 cur = start;
891 while (cur < end) {
892 unsigned long chunk;
893
894 chunk = end - cur;
895 if (chunk > PAGE_SIZE)
896 chunk = PAGE_SIZE;
897 if (copy_from_user(buffer, (const void *) cur,
898 chunk) != 0) {
899 dprintk(
900 KERN_ERR "tf_get_current_"
901 "process_hash: copy_from_user "
902 "failed!\n");
903 result = -EINVAL;
904 (void) do_munmap(mm, start,
905 dentry->d_inode->i_size);
906 dput(dentry);
907 goto vma_out;
908 }
909 sha1_update(&sha1, buffer, chunk);
910 cur += chunk;
911 }
912 sha1_final(&sha1, hash);
913 result = 0;
914
915 (void) do_munmap(mm, start, dentry->d_inode->i_size);
916 dput(dentry);
917 break;
918 }
919 }
920vma_out:
921 up_read(&(mm->mmap_sem));
922
923 internal_kfree(buffer);
924
925 if (result == -ENOENT)
926 dprintk(
927 KERN_ERR "tf_get_current_process_hash: "
928 "No executable VMA found for process!\n");
929 return result;
930}
931
932#ifndef CONFIG_ANDROID
933/* This function hashes the path of the current application.
934 * If data = NULL ,nothing else is added to the hash
935 else add data to the hash
936 */
937int tf_hash_application_path_and_data(char *buffer, void *data,
938 u32 data_len)
939{
940 int result = -ENOENT;
941 char *tmp = NULL;
942 struct mm_struct *mm;
943 struct vm_area_struct *vma;
944
945 tmp = internal_kmalloc(PAGE_SIZE, GFP_KERNEL);
946 if (tmp == NULL) {
947 result = -ENOMEM;
948 goto end;
949 }
950
951 mm = current->mm;
952
953 down_read(&(mm->mmap_sem));
954 for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) {
955 if ((vma->vm_flags & VM_EXECUTABLE) != 0
956 && vma->vm_file != NULL) {
957 struct path *path;
958 char *endpath;
959 size_t pathlen;
960 struct sha1_ctx sha1;
961 u8 hash[SHA1_DIGEST_SIZE];
962
963 path = &vma->vm_file->f_path;
964
965 endpath = d_path(path, tmp, PAGE_SIZE);
966 if (IS_ERR(path)) {
967 result = PTR_ERR(endpath);
968 up_read(&(mm->mmap_sem));
969 goto end;
970 }
971 pathlen = (tmp + PAGE_SIZE) - endpath;
972
973#ifdef CONFIG_TF_DRIVER_DEBUG_SUPPORT
974 {
975 char *c;
976 dprintk(KERN_DEBUG "current process path = ");
977 for (c = endpath;
978 c < tmp + PAGE_SIZE;
979 c++)
980 dprintk("%c", *c);
981
982 dprintk(", uid=%d, euid=%d\n", current_uid(),
983 current_euid());
984 }
985#endif /* defined(CONFIG_TF_DRIVER_DEBUG_SUPPORT) */
986
987 sha1_init(&sha1);
988 sha1_update(&sha1, endpath, pathlen);
989 if (data != NULL) {
990 dprintk(KERN_INFO "current process path: "
991 "Hashing additional data\n");
992 sha1_update(&sha1, data, data_len);
993 }
994 sha1_final(&sha1, hash);
995 memcpy(buffer, hash, sizeof(hash));
996
997 result = 0;
998
999 break;
1000 }
1001 }
1002 up_read(&(mm->mmap_sem));
1003
1004end:
1005 if (tmp != NULL)
1006 internal_kfree(tmp);
1007
1008 return result;
1009}
1010#endif /* !CONFIG_ANDROID */
1011
1012void *internal_kmalloc(size_t size, int priority)
1013{
1014 void *ptr;
1015 struct tf_device *dev = tf_get_device();
1016
1017 ptr = kmalloc(size, priority);
1018
1019 if (ptr != NULL)
1020 atomic_inc(
1021 &dev->stats.stat_memories_allocated);
1022
1023 return ptr;
1024}
1025
1026void internal_kfree(void *ptr)
1027{
1028 struct tf_device *dev = tf_get_device();
1029
1030 if (ptr != NULL)
1031 atomic_dec(
1032 &dev->stats.stat_memories_allocated);
1033 return kfree(ptr);
1034}
1035
1036void internal_vunmap(void *ptr)
1037{
1038 struct tf_device *dev = tf_get_device();
1039
1040 if (ptr != NULL)
1041 atomic_dec(
1042 &dev->stats.stat_memories_allocated);
1043
1044 vunmap((void *) (((unsigned int)ptr) & 0xFFFFF000));
1045}
1046
1047void *internal_vmalloc(size_t size)
1048{
1049 void *ptr;
1050 struct tf_device *dev = tf_get_device();
1051
1052 ptr = vmalloc(size);
1053
1054 if (ptr != NULL)
1055 atomic_inc(
1056 &dev->stats.stat_memories_allocated);
1057
1058 return ptr;
1059}
1060
1061void internal_vfree(void *ptr)
1062{
1063 struct tf_device *dev = tf_get_device();
1064
1065 if (ptr != NULL)
1066 atomic_dec(
1067 &dev->stats.stat_memories_allocated);
1068 return vfree(ptr);
1069}
1070
1071unsigned long internal_get_zeroed_page(int priority)
1072{
1073 unsigned long result;
1074 struct tf_device *dev = tf_get_device();
1075
1076 result = get_zeroed_page(priority);
1077
1078 if (result != 0)
1079 atomic_inc(&dev->stats.
1080 stat_pages_allocated);
1081
1082 return result;
1083}
1084
1085void internal_free_page(unsigned long addr)
1086{
1087 struct tf_device *dev = tf_get_device();
1088
1089 if (addr != 0)
1090 atomic_dec(
1091 &dev->stats.stat_pages_allocated);
1092 return free_page(addr);
1093}
1094
1095int internal_get_user_pages(
1096 struct task_struct *tsk,
1097 struct mm_struct *mm,
1098 unsigned long start,
1099 int len,
1100 int write,
1101 int force,
1102 struct page **pages,
1103 struct vm_area_struct **vmas)
1104{
1105 int result;
1106 struct tf_device *dev = tf_get_device();
1107
1108 result = get_user_pages(
1109 tsk,
1110 mm,
1111 start,
1112 len,
1113 write,
1114 force,
1115 pages,
1116 vmas);
1117
1118 if (result > 0)
1119 atomic_add(result,
1120 &dev->stats.stat_pages_locked);
1121
1122 return result;
1123}
1124
1125void internal_get_page(struct page *page)
1126{
1127 struct tf_device *dev = tf_get_device();
1128
1129 atomic_inc(&dev->stats.stat_pages_locked);
1130
1131 get_page(page);
1132}
1133
1134void internal_page_cache_release(struct page *page)
1135{
1136 struct tf_device *dev = tf_get_device();
1137
1138 atomic_dec(&dev->stats.stat_pages_locked);
1139
1140 page_cache_release(page);
1141}
1142
1143
diff --git a/security/tf_driver/tf_util.h b/security/tf_driver/tf_util.h
new file mode 100644
index 00000000000..14bc78952d8
--- /dev/null
+++ b/security/tf_driver/tf_util.h
@@ -0,0 +1,122 @@
1/**
2 * Copyright (c) 2011 Trusted Logic S.A.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#ifndef __TF_UTIL_H__
21#define __TF_UTIL_H__
22
23#include <linux/spinlock.h>
24#include <linux/errno.h>
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/mm.h>
28#include <linux/crypto.h>
29#include <linux/mount.h>
30#include <linux/pagemap.h>
31#include <linux/vmalloc.h>
32#include <asm/byteorder.h>
33
34#include "tf_protocol.h"
35#include "tf_defs.h"
36
37/*----------------------------------------------------------------------------
38 * Debug printing routines
39 *----------------------------------------------------------------------------*/
40
41#ifdef CONFIG_TF_DRIVER_DEBUG_SUPPORT
42extern unsigned tf_debug_level;
43
44void address_cache_property(unsigned long va);
45
46#define dprintk(args...) ((void)(tf_debug_level >= 6 ? printk(args) : 0))
47#define dpr_info(args...) ((void)(tf_debug_level >= 3 ? pr_info(args) : 0))
48#define dpr_err(args...) ((void)(tf_debug_level >= 1 ? pr_err(args) : 0))
49#define INFO(fmt, args...) \
50 (void)dprintk(KERN_INFO "%s: " fmt "\n", __func__, ## args)
51#define WARNING(fmt, args...) \
52 (tf_debug_level >= 3 ? \
53 printk(KERN_WARNING "%s: " fmt "\n", __func__, ## args) : \
54 (void)0)
55#define ERROR(fmt, args...) \
56 (tf_debug_level >= 1 ? \
57 printk(KERN_ERR "%s: " fmt "\n", __func__, ## args) : \
58 (void)0)
59void tf_trace_array(const char *fun, const char *msg,
60 const void *ptr, size_t len);
61#define TF_TRACE_ARRAY(ptr, len) \
62 (tf_debug_level >= 7 ? \
63 tf_trace_array(__func__, #ptr "/" #len, ptr, len) : \
64 0)
65
66void tf_dump_l1_shared_buffer(struct tf_l1_shared_buffer *buffer);
67
68void tf_dump_command(union tf_command *command);
69
70void tf_dump_answer(union tf_answer *answer);
71
72#else /* defined(CONFIG_TF_DRIVER_DEBUG_SUPPORT) */
73
74#define dprintk(args...) do { ; } while (0)
75#define dpr_info(args...) do { ; } while (0)
76#define dpr_err(args...) do { ; } while (0)
77#define INFO(fmt, args...) ((void)0)
78#define WARNING(fmt, args...) ((void)0)
79#define ERROR(fmt, args...) ((void)0)
80#define TF_TRACE_ARRAY(ptr, len) ((void)(ptr), (void)(len))
81#define tf_dump_l1_shared_buffer(buffer) ((void) 0)
82#define tf_dump_command(command) ((void) 0)
83#define tf_dump_answer(answer) ((void) 0)
84
85#endif /* defined(CONFIG_TF_DRIVER_DEBUG_SUPPORT) */
86
87#define SHA1_DIGEST_SIZE 20
88
89/*----------------------------------------------------------------------------
90 * Process identification
91 *----------------------------------------------------------------------------*/
92
93int tf_get_current_process_hash(void *hash);
94
95#ifndef CONFIG_ANDROID
96int tf_hash_application_path_and_data(char *buffer, void *data, u32 data_len);
97#endif /* !CONFIG_ANDROID */
98
99/*----------------------------------------------------------------------------
100 * Statistic computation
101 *----------------------------------------------------------------------------*/
102
103void *internal_kmalloc(size_t size, int priority);
104void internal_kfree(void *ptr);
105void internal_vunmap(void *ptr);
106void *internal_vmalloc(size_t size);
107void internal_vfree(void *ptr);
108unsigned long internal_get_zeroed_page(int priority);
109void internal_free_page(unsigned long addr);
110int internal_get_user_pages(
111 struct task_struct *tsk,
112 struct mm_struct *mm,
113 unsigned long start,
114 int len,
115 int write,
116 int force,
117 struct page **pages,
118 struct vm_area_struct **vmas);
119void internal_get_page(struct page *page);
120void internal_page_cache_release(struct page *page);
121#endif /* __TF_UTIL_H__ */
122
diff --git a/security/tomoyo/.gitignore b/security/tomoyo/.gitignore
new file mode 100644
index 00000000000..5caf1a6f590
--- /dev/null
+++ b/security/tomoyo/.gitignore
@@ -0,0 +1,2 @@
1builtin-policy.h
2policy/
diff --git a/security/tomoyo/Kconfig b/security/tomoyo/Kconfig
index c8f38579323..7c7f8c16c10 100644
--- a/security/tomoyo/Kconfig
+++ b/security/tomoyo/Kconfig
@@ -9,3 +9,64 @@ config SECURITY_TOMOYO
9 Required userspace tools and further information may be 9 Required userspace tools and further information may be
10 found at <http://tomoyo.sourceforge.jp/>. 10 found at <http://tomoyo.sourceforge.jp/>.
11 If you are unsure how to answer this question, answer N. 11 If you are unsure how to answer this question, answer N.
12
13config SECURITY_TOMOYO_MAX_ACCEPT_ENTRY
14 int "Default maximal count for learning mode"
15 default 2048
16 range 0 2147483647
17 depends on SECURITY_TOMOYO
18 help
19 This is the default value for maximal ACL entries
20 that are automatically appended into policy at "learning mode".
21 Some programs access thousands of objects, so running
22 such programs in "learning mode" dulls the system response
23 and consumes much memory.
24 This is the safeguard for such programs.
25
26config SECURITY_TOMOYO_MAX_AUDIT_LOG
27 int "Default maximal count for audit log"
28 default 1024
29 range 0 2147483647
30 depends on SECURITY_TOMOYO
31 help
32 This is the default value for maximal entries for
33 audit logs that the kernel can hold on memory.
34 You can read the log via /sys/kernel/security/tomoyo/audit.
35 If you don't need audit logs, you may set this value to 0.
36
37config SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
38 bool "Activate without calling userspace policy loader."
39 default n
40 depends on SECURITY_TOMOYO
41 ---help---
42 Say Y here if you want to activate access control as soon as built-in
43 policy was loaded. This option will be useful for systems where
44 operations which can lead to the hijacking of the boot sequence are
45 needed before loading the policy. For example, you can activate
46 immediately after loading the fixed part of policy which will allow
47 only operations needed for mounting a partition which contains the
48 variant part of policy and verifying (e.g. running GPG check) and
49 loading the variant part of policy. Since you can start using
50 enforcing mode from the beginning, you can reduce the possibility of
51 hijacking the boot sequence.
52
53config SECURITY_TOMOYO_POLICY_LOADER
54 string "Location of userspace policy loader"
55 default "/sbin/tomoyo-init"
56 depends on SECURITY_TOMOYO
57 depends on !SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
58 ---help---
59 This is the default pathname of policy loader which is called before
60 activation. You can override this setting via TOMOYO_loader= kernel
61 command line option.
62
63config SECURITY_TOMOYO_ACTIVATION_TRIGGER
64 string "Trigger for calling userspace policy loader"
65 default "/sbin/init"
66 depends on SECURITY_TOMOYO
67 depends on !SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
68 ---help---
69 This is the default pathname of activation trigger.
70 You can override this setting via TOMOYO_trigger= kernel command line
71 option. For example, if you pass init=/bin/systemd option, you may
72 want to also pass TOMOYO_trigger=/bin/systemd option.
diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile
index 91640e96bd0..95278b71fc2 100644
--- a/security/tomoyo/Makefile
+++ b/security/tomoyo/Makefile
@@ -1 +1,48 @@
1obj-y = common.o domain.o file.o gc.o group.o load_policy.o memory.o mount.o realpath.o securityfs_if.o tomoyo.o util.o 1obj-y = audit.o common.o condition.o domain.o file.o gc.o group.o load_policy.o memory.o mount.o realpath.o securityfs_if.o tomoyo.o util.o
2
3$(obj)/policy/profile.conf:
4 @mkdir -p $(obj)/policy/
5 @echo Creating an empty policy/profile.conf
6 @touch $@
7
8$(obj)/policy/exception_policy.conf:
9 @mkdir -p $(obj)/policy/
10 @echo Creating a default policy/exception_policy.conf
11 @echo initialize_domain /sbin/modprobe from any >> $@
12 @echo initialize_domain /sbin/hotplug from any >> $@
13
14$(obj)/policy/domain_policy.conf:
15 @mkdir -p $(obj)/policy/
16 @echo Creating an empty policy/domain_policy.conf
17 @touch $@
18
19$(obj)/policy/manager.conf:
20 @mkdir -p $(obj)/policy/
21 @echo Creating an empty policy/manager.conf
22 @touch $@
23
24$(obj)/policy/stat.conf:
25 @mkdir -p $(obj)/policy/
26 @echo Creating an empty policy/stat.conf
27 @touch $@
28
29$(obj)/builtin-policy.h: $(obj)/policy/profile.conf $(obj)/policy/exception_policy.conf $(obj)/policy/domain_policy.conf $(obj)/policy/manager.conf $(obj)/policy/stat.conf
30 @echo Generating built-in policy for TOMOYO 2.4.x.
31 @echo "static char tomoyo_builtin_profile[] __initdata =" > $@.tmp
32 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/profile.conf >> $@.tmp
33 @echo "\"\";" >> $@.tmp
34 @echo "static char tomoyo_builtin_exception_policy[] __initdata =" >> $@.tmp
35 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/exception_policy.conf >> $@.tmp
36 @echo "\"\";" >> $@.tmp
37 @echo "static char tomoyo_builtin_domain_policy[] __initdata =" >> $@.tmp
38 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/domain_policy.conf >> $@.tmp
39 @echo "\"\";" >> $@.tmp
40 @echo "static char tomoyo_builtin_manager[] __initdata =" >> $@.tmp
41 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/manager.conf >> $@.tmp
42 @echo "\"\";" >> $@.tmp
43 @echo "static char tomoyo_builtin_stat[] __initdata =" >> $@.tmp
44 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/stat.conf >> $@.tmp
45 @echo "\"\";" >> $@.tmp
46 @mv $@.tmp $@
47
48$(obj)/common.o: $(obj)/builtin-policy.h
diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c
new file mode 100644
index 00000000000..5dbb1f7617c
--- /dev/null
+++ b/security/tomoyo/audit.c
@@ -0,0 +1,456 @@
1/*
2 * security/tomoyo/audit.c
3 *
4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */
6
7#include "common.h"
8#include <linux/slab.h>
9
10/**
11 * tomoyo_print_bprm - Print "struct linux_binprm" for auditing.
12 *
13 * @bprm: Pointer to "struct linux_binprm".
14 * @dump: Pointer to "struct tomoyo_page_dump".
15 *
16 * Returns the contents of @bprm on success, NULL otherwise.
17 *
18 * This function uses kzalloc(), so caller must kfree() if this function
19 * didn't return NULL.
20 */
21static char *tomoyo_print_bprm(struct linux_binprm *bprm,
22 struct tomoyo_page_dump *dump)
23{
24 static const int tomoyo_buffer_len = 4096 * 2;
25 char *buffer = kzalloc(tomoyo_buffer_len, GFP_NOFS);
26 char *cp;
27 char *last_start;
28 int len;
29 unsigned long pos = bprm->p;
30 int offset = pos % PAGE_SIZE;
31 int argv_count = bprm->argc;
32 int envp_count = bprm->envc;
33 bool truncated = false;
34 if (!buffer)
35 return NULL;
36 len = snprintf(buffer, tomoyo_buffer_len - 1, "argv[]={ ");
37 cp = buffer + len;
38 if (!argv_count) {
39 memmove(cp, "} envp[]={ ", 11);
40 cp += 11;
41 }
42 last_start = cp;
43 while (argv_count || envp_count) {
44 if (!tomoyo_dump_page(bprm, pos, dump))
45 goto out;
46 pos += PAGE_SIZE - offset;
47 /* Read. */
48 while (offset < PAGE_SIZE) {
49 const char *kaddr = dump->data;
50 const unsigned char c = kaddr[offset++];
51 if (cp == last_start)
52 *cp++ = '"';
53 if (cp >= buffer + tomoyo_buffer_len - 32) {
54 /* Reserve some room for "..." string. */
55 truncated = true;
56 } else if (c == '\\') {
57 *cp++ = '\\';
58 *cp++ = '\\';
59 } else if (c > ' ' && c < 127) {
60 *cp++ = c;
61 } else if (!c) {
62 *cp++ = '"';
63 *cp++ = ' ';
64 last_start = cp;
65 } else {
66 *cp++ = '\\';
67 *cp++ = (c >> 6) + '0';
68 *cp++ = ((c >> 3) & 7) + '0';
69 *cp++ = (c & 7) + '0';
70 }
71 if (c)
72 continue;
73 if (argv_count) {
74 if (--argv_count == 0) {
75 if (truncated) {
76 cp = last_start;
77 memmove(cp, "... ", 4);
78 cp += 4;
79 }
80 memmove(cp, "} envp[]={ ", 11);
81 cp += 11;
82 last_start = cp;
83 truncated = false;
84 }
85 } else if (envp_count) {
86 if (--envp_count == 0) {
87 if (truncated) {
88 cp = last_start;
89 memmove(cp, "... ", 4);
90 cp += 4;
91 }
92 }
93 }
94 if (!argv_count && !envp_count)
95 break;
96 }
97 offset = 0;
98 }
99 *cp++ = '}';
100 *cp = '\0';
101 return buffer;
102out:
103 snprintf(buffer, tomoyo_buffer_len - 1,
104 "argv[]={ ... } envp[]= { ... }");
105 return buffer;
106}
107
108/**
109 * tomoyo_filetype - Get string representation of file type.
110 *
111 * @mode: Mode value for stat().
112 *
113 * Returns file type string.
114 */
115static inline const char *tomoyo_filetype(const mode_t mode)
116{
117 switch (mode & S_IFMT) {
118 case S_IFREG:
119 case 0:
120 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FILE];
121 case S_IFDIR:
122 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_DIRECTORY];
123 case S_IFLNK:
124 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SYMLINK];
125 case S_IFIFO:
126 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FIFO];
127 case S_IFSOCK:
128 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SOCKET];
129 case S_IFBLK:
130 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_BLOCK_DEV];
131 case S_IFCHR:
132 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_CHAR_DEV];
133 }
134 return "unknown"; /* This should not happen. */
135}
136
137/**
138 * tomoyo_print_header - Get header line of audit log.
139 *
140 * @r: Pointer to "struct tomoyo_request_info".
141 *
142 * Returns string representation.
143 *
144 * This function uses kmalloc(), so caller must kfree() if this function
145 * didn't return NULL.
146 */
147static char *tomoyo_print_header(struct tomoyo_request_info *r)
148{
149 struct tomoyo_time stamp;
150 const pid_t gpid = task_pid_nr(current);
151 struct tomoyo_obj_info *obj = r->obj;
152 static const int tomoyo_buffer_len = 4096;
153 char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
154 int pos;
155 u8 i;
156 if (!buffer)
157 return NULL;
158 {
159 struct timeval tv;
160 do_gettimeofday(&tv);
161 tomoyo_convert_time(tv.tv_sec, &stamp);
162 }
163 pos = snprintf(buffer, tomoyo_buffer_len - 1,
164 "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s "
165 "granted=%s (global-pid=%u) task={ pid=%u ppid=%u "
166 "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u "
167 "fsuid=%u fsgid=%u }", stamp.year, stamp.month,
168 stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile,
169 tomoyo_mode[r->mode], tomoyo_yesno(r->granted), gpid,
170 tomoyo_sys_getpid(), tomoyo_sys_getppid(),
171 current_uid(), current_gid(), current_euid(),
172 current_egid(), current_suid(), current_sgid(),
173 current_fsuid(), current_fsgid());
174 if (!obj)
175 goto no_obj_info;
176 if (!obj->validate_done) {
177 tomoyo_get_attributes(obj);
178 obj->validate_done = true;
179 }
180 for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) {
181 struct tomoyo_mini_stat *stat;
182 unsigned int dev;
183 mode_t mode;
184 if (!obj->stat_valid[i])
185 continue;
186 stat = &obj->stat[i];
187 dev = stat->dev;
188 mode = stat->mode;
189 if (i & 1) {
190 pos += snprintf(buffer + pos,
191 tomoyo_buffer_len - 1 - pos,
192 " path%u.parent={ uid=%u gid=%u "
193 "ino=%lu perm=0%o }", (i >> 1) + 1,
194 stat->uid, stat->gid, (unsigned long)
195 stat->ino, stat->mode & S_IALLUGO);
196 continue;
197 }
198 pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
199 " path%u={ uid=%u gid=%u ino=%lu major=%u"
200 " minor=%u perm=0%o type=%s", (i >> 1) + 1,
201 stat->uid, stat->gid, (unsigned long)
202 stat->ino, MAJOR(dev), MINOR(dev),
203 mode & S_IALLUGO, tomoyo_filetype(mode));
204 if (S_ISCHR(mode) || S_ISBLK(mode)) {
205 dev = stat->rdev;
206 pos += snprintf(buffer + pos,
207 tomoyo_buffer_len - 1 - pos,
208 " dev_major=%u dev_minor=%u",
209 MAJOR(dev), MINOR(dev));
210 }
211 pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
212 " }");
213 }
214no_obj_info:
215 if (pos < tomoyo_buffer_len - 1)
216 return buffer;
217 kfree(buffer);
218 return NULL;
219}
220
221/**
222 * tomoyo_init_log - Allocate buffer for audit logs.
223 *
224 * @r: Pointer to "struct tomoyo_request_info".
225 * @len: Buffer size needed for @fmt and @args.
226 * @fmt: The printf()'s format string.
227 * @args: va_list structure for @fmt.
228 *
229 * Returns pointer to allocated memory.
230 *
231 * This function uses kzalloc(), so caller must kfree() if this function
232 * didn't return NULL.
233 */
234char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
235 va_list args)
236{
237 char *buf = NULL;
238 char *bprm_info = NULL;
239 const char *header = NULL;
240 char *realpath = NULL;
241 const char *symlink = NULL;
242 int pos;
243 const char *domainname = r->domain->domainname->name;
244 header = tomoyo_print_header(r);
245 if (!header)
246 return NULL;
247 /* +10 is for '\n' etc. and '\0'. */
248 len += strlen(domainname) + strlen(header) + 10;
249 if (r->ee) {
250 struct file *file = r->ee->bprm->file;
251 realpath = tomoyo_realpath_from_path(&file->f_path);
252 bprm_info = tomoyo_print_bprm(r->ee->bprm, &r->ee->dump);
253 if (!realpath || !bprm_info)
254 goto out;
255 /* +80 is for " exec={ realpath=\"%s\" argc=%d envc=%d %s }" */
256 len += strlen(realpath) + 80 + strlen(bprm_info);
257 } else if (r->obj && r->obj->symlink_target) {
258 symlink = r->obj->symlink_target->name;
259 /* +18 is for " symlink.target=\"%s\"" */
260 len += 18 + strlen(symlink);
261 }
262 len = tomoyo_round2(len);
263 buf = kzalloc(len, GFP_NOFS);
264 if (!buf)
265 goto out;
266 len--;
267 pos = snprintf(buf, len, "%s", header);
268 if (realpath) {
269 struct linux_binprm *bprm = r->ee->bprm;
270 pos += snprintf(buf + pos, len - pos,
271 " exec={ realpath=\"%s\" argc=%d envc=%d %s }",
272 realpath, bprm->argc, bprm->envc, bprm_info);
273 } else if (symlink)
274 pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"",
275 symlink);
276 pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname);
277 vsnprintf(buf + pos, len - pos, fmt, args);
278out:
279 kfree(realpath);
280 kfree(bprm_info);
281 kfree(header);
282 return buf;
283}
284
285/* Wait queue for /sys/kernel/security/tomoyo/audit. */
286static DECLARE_WAIT_QUEUE_HEAD(tomoyo_log_wait);
287
288/* Structure for audit log. */
289struct tomoyo_log {
290 struct list_head list;
291 char *log;
292 int size;
293};
294
295/* The list for "struct tomoyo_log". */
296static LIST_HEAD(tomoyo_log);
297
298/* Lock for "struct list_head tomoyo_log". */
299static DEFINE_SPINLOCK(tomoyo_log_lock);
300
301/* Length of "stuct list_head tomoyo_log". */
302static unsigned int tomoyo_log_count;
303
304/**
305 * tomoyo_get_audit - Get audit mode.
306 *
307 * @ns: Pointer to "struct tomoyo_policy_namespace".
308 * @profile: Profile number.
309 * @index: Index number of functionality.
310 * @is_granted: True if granted log, false otherwise.
311 *
312 * Returns true if this request should be audited, false otherwise.
313 */
314static bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns,
315 const u8 profile, const u8 index,
316 const bool is_granted)
317{
318 u8 mode;
319 const u8 category = tomoyo_index2category[index] +
320 TOMOYO_MAX_MAC_INDEX;
321 struct tomoyo_profile *p;
322 if (!tomoyo_policy_loaded)
323 return false;
324 p = tomoyo_profile(ns, profile);
325 if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG])
326 return false;
327 mode = p->config[index];
328 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
329 mode = p->config[category];
330 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
331 mode = p->default_config;
332 if (is_granted)
333 return mode & TOMOYO_CONFIG_WANT_GRANT_LOG;
334 return mode & TOMOYO_CONFIG_WANT_REJECT_LOG;
335}
336
337/**
338 * tomoyo_write_log2 - Write an audit log.
339 *
340 * @r: Pointer to "struct tomoyo_request_info".
341 * @len: Buffer size needed for @fmt and @args.
342 * @fmt: The printf()'s format string.
343 * @args: va_list structure for @fmt.
344 *
345 * Returns nothing.
346 */
347void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
348 va_list args)
349{
350 char *buf;
351 struct tomoyo_log *entry;
352 bool quota_exceeded = false;
353 if (!tomoyo_get_audit(r->domain->ns, r->profile, r->type, r->granted))
354 goto out;
355 buf = tomoyo_init_log(r, len, fmt, args);
356 if (!buf)
357 goto out;
358 entry = kzalloc(sizeof(*entry), GFP_NOFS);
359 if (!entry) {
360 kfree(buf);
361 goto out;
362 }
363 entry->log = buf;
364 len = tomoyo_round2(strlen(buf) + 1);
365 /*
366 * The entry->size is used for memory quota checks.
367 * Don't go beyond strlen(entry->log).
368 */
369 entry->size = len + tomoyo_round2(sizeof(*entry));
370 spin_lock(&tomoyo_log_lock);
371 if (tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT] &&
372 tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] + entry->size >=
373 tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT]) {
374 quota_exceeded = true;
375 } else {
376 tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] += entry->size;
377 list_add_tail(&entry->list, &tomoyo_log);
378 tomoyo_log_count++;
379 }
380 spin_unlock(&tomoyo_log_lock);
381 if (quota_exceeded) {
382 kfree(buf);
383 kfree(entry);
384 goto out;
385 }
386 wake_up(&tomoyo_log_wait);
387out:
388 return;
389}
390
391/**
392 * tomoyo_write_log - Write an audit log.
393 *
394 * @r: Pointer to "struct tomoyo_request_info".
395 * @fmt: The printf()'s format string, followed by parameters.
396 *
397 * Returns nothing.
398 */
399void tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...)
400{
401 va_list args;
402 int len;
403 va_start(args, fmt);
404 len = vsnprintf((char *) &len, 1, fmt, args) + 1;
405 va_end(args);
406 va_start(args, fmt);
407 tomoyo_write_log2(r, len, fmt, args);
408 va_end(args);
409}
410
411/**
412 * tomoyo_read_log - Read an audit log.
413 *
414 * @head: Pointer to "struct tomoyo_io_buffer".
415 *
416 * Returns nothing.
417 */
418void tomoyo_read_log(struct tomoyo_io_buffer *head)
419{
420 struct tomoyo_log *ptr = NULL;
421 if (head->r.w_pos)
422 return;
423 kfree(head->read_buf);
424 head->read_buf = NULL;
425 spin_lock(&tomoyo_log_lock);
426 if (!list_empty(&tomoyo_log)) {
427 ptr = list_entry(tomoyo_log.next, typeof(*ptr), list);
428 list_del(&ptr->list);
429 tomoyo_log_count--;
430 tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] -= ptr->size;
431 }
432 spin_unlock(&tomoyo_log_lock);
433 if (ptr) {
434 head->read_buf = ptr->log;
435 head->r.w[head->r.w_pos++] = head->read_buf;
436 kfree(ptr);
437 }
438}
439
440/**
441 * tomoyo_poll_log - Wait for an audit log.
442 *
443 * @file: Pointer to "struct file".
444 * @wait: Pointer to "poll_table".
445 *
446 * Returns POLLIN | POLLRDNORM when ready to read an audit log.
447 */
448int tomoyo_poll_log(struct file *file, poll_table *wait)
449{
450 if (tomoyo_log_count)
451 return POLLIN | POLLRDNORM;
452 poll_wait(file, &tomoyo_log_wait, wait);
453 if (tomoyo_log_count)
454 return POLLIN | POLLRDNORM;
455 return 0;
456}
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index a0d09e56874..2e43aec1c36 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * security/tomoyo/common.c 2 * security/tomoyo/common.c
3 * 3 *
4 * Common functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include <linux/uaccess.h> 7#include <linux/uaccess.h>
@@ -11,54 +9,131 @@
11#include <linux/security.h> 9#include <linux/security.h>
12#include "common.h" 10#include "common.h"
13 11
14static struct tomoyo_profile tomoyo_default_profile = { 12/* String table for operation mode. */
15 .learning = &tomoyo_default_profile.preference, 13const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE] = {
16 .permissive = &tomoyo_default_profile.preference, 14 [TOMOYO_CONFIG_DISABLED] = "disabled",
17 .enforcing = &tomoyo_default_profile.preference, 15 [TOMOYO_CONFIG_LEARNING] = "learning",
18 .preference.enforcing_verbose = true, 16 [TOMOYO_CONFIG_PERMISSIVE] = "permissive",
19 .preference.learning_max_entry = 2048, 17 [TOMOYO_CONFIG_ENFORCING] = "enforcing"
20 .preference.learning_verbose = false,
21 .preference.permissive_verbose = true
22}; 18};
23 19
24/* Profile version. Currently only 20090903 is defined. */ 20/* String table for /sys/kernel/security/tomoyo/profile */
25static unsigned int tomoyo_profile_version; 21const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
22 + TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
23 [TOMOYO_MAC_FILE_EXECUTE] = "execute",
24 [TOMOYO_MAC_FILE_OPEN] = "open",
25 [TOMOYO_MAC_FILE_CREATE] = "create",
26 [TOMOYO_MAC_FILE_UNLINK] = "unlink",
27 [TOMOYO_MAC_FILE_GETATTR] = "getattr",
28 [TOMOYO_MAC_FILE_MKDIR] = "mkdir",
29 [TOMOYO_MAC_FILE_RMDIR] = "rmdir",
30 [TOMOYO_MAC_FILE_MKFIFO] = "mkfifo",
31 [TOMOYO_MAC_FILE_MKSOCK] = "mksock",
32 [TOMOYO_MAC_FILE_TRUNCATE] = "truncate",
33 [TOMOYO_MAC_FILE_SYMLINK] = "symlink",
34 [TOMOYO_MAC_FILE_MKBLOCK] = "mkblock",
35 [TOMOYO_MAC_FILE_MKCHAR] = "mkchar",
36 [TOMOYO_MAC_FILE_LINK] = "link",
37 [TOMOYO_MAC_FILE_RENAME] = "rename",
38 [TOMOYO_MAC_FILE_CHMOD] = "chmod",
39 [TOMOYO_MAC_FILE_CHOWN] = "chown",
40 [TOMOYO_MAC_FILE_CHGRP] = "chgrp",
41 [TOMOYO_MAC_FILE_IOCTL] = "ioctl",
42 [TOMOYO_MAC_FILE_CHROOT] = "chroot",
43 [TOMOYO_MAC_FILE_MOUNT] = "mount",
44 [TOMOYO_MAC_FILE_UMOUNT] = "unmount",
45 [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root",
46 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file",
47};
26 48
27/* Profile table. Memory is allocated as needed. */ 49/* String table for conditions. */
28static struct tomoyo_profile *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES]; 50const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = {
51 [TOMOYO_TASK_UID] = "task.uid",
52 [TOMOYO_TASK_EUID] = "task.euid",
53 [TOMOYO_TASK_SUID] = "task.suid",
54 [TOMOYO_TASK_FSUID] = "task.fsuid",
55 [TOMOYO_TASK_GID] = "task.gid",
56 [TOMOYO_TASK_EGID] = "task.egid",
57 [TOMOYO_TASK_SGID] = "task.sgid",
58 [TOMOYO_TASK_FSGID] = "task.fsgid",
59 [TOMOYO_TASK_PID] = "task.pid",
60 [TOMOYO_TASK_PPID] = "task.ppid",
61 [TOMOYO_EXEC_ARGC] = "exec.argc",
62 [TOMOYO_EXEC_ENVC] = "exec.envc",
63 [TOMOYO_TYPE_IS_SOCKET] = "socket",
64 [TOMOYO_TYPE_IS_SYMLINK] = "symlink",
65 [TOMOYO_TYPE_IS_FILE] = "file",
66 [TOMOYO_TYPE_IS_BLOCK_DEV] = "block",
67 [TOMOYO_TYPE_IS_DIRECTORY] = "directory",
68 [TOMOYO_TYPE_IS_CHAR_DEV] = "char",
69 [TOMOYO_TYPE_IS_FIFO] = "fifo",
70 [TOMOYO_MODE_SETUID] = "setuid",
71 [TOMOYO_MODE_SETGID] = "setgid",
72 [TOMOYO_MODE_STICKY] = "sticky",
73 [TOMOYO_MODE_OWNER_READ] = "owner_read",
74 [TOMOYO_MODE_OWNER_WRITE] = "owner_write",
75 [TOMOYO_MODE_OWNER_EXECUTE] = "owner_execute",
76 [TOMOYO_MODE_GROUP_READ] = "group_read",
77 [TOMOYO_MODE_GROUP_WRITE] = "group_write",
78 [TOMOYO_MODE_GROUP_EXECUTE] = "group_execute",
79 [TOMOYO_MODE_OTHERS_READ] = "others_read",
80 [TOMOYO_MODE_OTHERS_WRITE] = "others_write",
81 [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute",
82 [TOMOYO_EXEC_REALPATH] = "exec.realpath",
83 [TOMOYO_SYMLINK_TARGET] = "symlink.target",
84 [TOMOYO_PATH1_UID] = "path1.uid",
85 [TOMOYO_PATH1_GID] = "path1.gid",
86 [TOMOYO_PATH1_INO] = "path1.ino",
87 [TOMOYO_PATH1_MAJOR] = "path1.major",
88 [TOMOYO_PATH1_MINOR] = "path1.minor",
89 [TOMOYO_PATH1_PERM] = "path1.perm",
90 [TOMOYO_PATH1_TYPE] = "path1.type",
91 [TOMOYO_PATH1_DEV_MAJOR] = "path1.dev_major",
92 [TOMOYO_PATH1_DEV_MINOR] = "path1.dev_minor",
93 [TOMOYO_PATH2_UID] = "path2.uid",
94 [TOMOYO_PATH2_GID] = "path2.gid",
95 [TOMOYO_PATH2_INO] = "path2.ino",
96 [TOMOYO_PATH2_MAJOR] = "path2.major",
97 [TOMOYO_PATH2_MINOR] = "path2.minor",
98 [TOMOYO_PATH2_PERM] = "path2.perm",
99 [TOMOYO_PATH2_TYPE] = "path2.type",
100 [TOMOYO_PATH2_DEV_MAJOR] = "path2.dev_major",
101 [TOMOYO_PATH2_DEV_MINOR] = "path2.dev_minor",
102 [TOMOYO_PATH1_PARENT_UID] = "path1.parent.uid",
103 [TOMOYO_PATH1_PARENT_GID] = "path1.parent.gid",
104 [TOMOYO_PATH1_PARENT_INO] = "path1.parent.ino",
105 [TOMOYO_PATH1_PARENT_PERM] = "path1.parent.perm",
106 [TOMOYO_PATH2_PARENT_UID] = "path2.parent.uid",
107 [TOMOYO_PATH2_PARENT_GID] = "path2.parent.gid",
108 [TOMOYO_PATH2_PARENT_INO] = "path2.parent.ino",
109 [TOMOYO_PATH2_PARENT_PERM] = "path2.parent.perm",
110};
29 111
30/* String table for functionality that takes 4 modes. */ 112/* String table for PREFERENCE keyword. */
31static const char *tomoyo_mode[4] = { 113static const char * const tomoyo_pref_keywords[TOMOYO_MAX_PREF] = {
32 "disabled", "learning", "permissive", "enforcing" 114 [TOMOYO_PREF_MAX_AUDIT_LOG] = "max_audit_log",
115 [TOMOYO_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry",
33}; 116};
34 117
35/* String table for /sys/kernel/security/tomoyo/profile */ 118/* String table for path operation. */
36static const char *tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX 119const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
37 + TOMOYO_MAX_MAC_CATEGORY_INDEX] = { 120 [TOMOYO_TYPE_EXECUTE] = "execute",
38 [TOMOYO_MAC_FILE_EXECUTE] = "file::execute", 121 [TOMOYO_TYPE_READ] = "read",
39 [TOMOYO_MAC_FILE_OPEN] = "file::open", 122 [TOMOYO_TYPE_WRITE] = "write",
40 [TOMOYO_MAC_FILE_CREATE] = "file::create", 123 [TOMOYO_TYPE_APPEND] = "append",
41 [TOMOYO_MAC_FILE_UNLINK] = "file::unlink", 124 [TOMOYO_TYPE_UNLINK] = "unlink",
42 [TOMOYO_MAC_FILE_MKDIR] = "file::mkdir", 125 [TOMOYO_TYPE_GETATTR] = "getattr",
43 [TOMOYO_MAC_FILE_RMDIR] = "file::rmdir", 126 [TOMOYO_TYPE_RMDIR] = "rmdir",
44 [TOMOYO_MAC_FILE_MKFIFO] = "file::mkfifo", 127 [TOMOYO_TYPE_TRUNCATE] = "truncate",
45 [TOMOYO_MAC_FILE_MKSOCK] = "file::mksock", 128 [TOMOYO_TYPE_SYMLINK] = "symlink",
46 [TOMOYO_MAC_FILE_TRUNCATE] = "file::truncate", 129 [TOMOYO_TYPE_CHROOT] = "chroot",
47 [TOMOYO_MAC_FILE_SYMLINK] = "file::symlink", 130 [TOMOYO_TYPE_UMOUNT] = "unmount",
48 [TOMOYO_MAC_FILE_REWRITE] = "file::rewrite", 131};
49 [TOMOYO_MAC_FILE_MKBLOCK] = "file::mkblock", 132
50 [TOMOYO_MAC_FILE_MKCHAR] = "file::mkchar", 133/* String table for categories. */
51 [TOMOYO_MAC_FILE_LINK] = "file::link", 134static const char * const tomoyo_category_keywords
52 [TOMOYO_MAC_FILE_RENAME] = "file::rename", 135[TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
53 [TOMOYO_MAC_FILE_CHMOD] = "file::chmod", 136 [TOMOYO_MAC_CATEGORY_FILE] = "file",
54 [TOMOYO_MAC_FILE_CHOWN] = "file::chown",
55 [TOMOYO_MAC_FILE_CHGRP] = "file::chgrp",
56 [TOMOYO_MAC_FILE_IOCTL] = "file::ioctl",
57 [TOMOYO_MAC_FILE_CHROOT] = "file::chroot",
58 [TOMOYO_MAC_FILE_MOUNT] = "file::mount",
59 [TOMOYO_MAC_FILE_UMOUNT] = "file::umount",
60 [TOMOYO_MAC_FILE_PIVOT_ROOT] = "file::pivot_root",
61 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file",
62}; 137};
63 138
64/* Permit policy management by non-root user? */ 139/* Permit policy management by non-root user? */
@@ -71,11 +146,20 @@ static bool tomoyo_manage_by_non_root;
71 * 146 *
72 * @value: Bool value. 147 * @value: Bool value.
73 */ 148 */
74static const char *tomoyo_yesno(const unsigned int value) 149const char *tomoyo_yesno(const unsigned int value)
75{ 150{
76 return value ? "yes" : "no"; 151 return value ? "yes" : "no";
77} 152}
78 153
154/**
155 * tomoyo_addprintf - strncat()-like-snprintf().
156 *
157 * @buffer: Buffer to write to. Must be '\0'-terminated.
158 * @len: Size of @buffer.
159 * @fmt: The printf()'s format string, followed by parameters.
160 *
161 * Returns nothing.
162 */
79static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...) 163static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...)
80{ 164{
81 va_list args; 165 va_list args;
@@ -96,7 +180,7 @@ static bool tomoyo_flush(struct tomoyo_io_buffer *head)
96{ 180{
97 while (head->r.w_pos) { 181 while (head->r.w_pos) {
98 const char *w = head->r.w[0]; 182 const char *w = head->r.w[0];
99 int len = strlen(w); 183 size_t len = strlen(w);
100 if (len) { 184 if (len) {
101 if (len > head->read_user_buf_avail) 185 if (len > head->read_user_buf_avail)
102 len = head->read_user_buf_avail; 186 len = head->read_user_buf_avail;
@@ -111,7 +195,7 @@ static bool tomoyo_flush(struct tomoyo_io_buffer *head)
111 head->r.w[0] = w; 195 head->r.w[0] = w;
112 if (*w) 196 if (*w)
113 return false; 197 return false;
114 /* Add '\0' for query. */ 198 /* Add '\0' for audit logs and query. */
115 if (head->poll) { 199 if (head->poll) {
116 if (!head->read_user_buf_avail || 200 if (!head->read_user_buf_avail ||
117 copy_to_user(head->read_user_buf, "", 1)) 201 copy_to_user(head->read_user_buf, "", 1))
@@ -155,8 +239,8 @@ static void tomoyo_set_string(struct tomoyo_io_buffer *head, const char *string)
155void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 239void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
156{ 240{
157 va_list args; 241 va_list args;
158 int len; 242 size_t len;
159 int pos = head->r.avail; 243 size_t pos = head->r.avail;
160 int size = head->readbuf_size - pos; 244 int size = head->readbuf_size - pos;
161 if (size <= 0) 245 if (size <= 0)
162 return; 246 return;
@@ -171,11 +255,25 @@ void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
171 tomoyo_set_string(head, head->read_buf + pos); 255 tomoyo_set_string(head, head->read_buf + pos);
172} 256}
173 257
258/**
259 * tomoyo_set_space - Put a space to "struct tomoyo_io_buffer" structure.
260 *
261 * @head: Pointer to "struct tomoyo_io_buffer".
262 *
263 * Returns nothing.
264 */
174static void tomoyo_set_space(struct tomoyo_io_buffer *head) 265static void tomoyo_set_space(struct tomoyo_io_buffer *head)
175{ 266{
176 tomoyo_set_string(head, " "); 267 tomoyo_set_string(head, " ");
177} 268}
178 269
270/**
271 * tomoyo_set_lf - Put a line feed to "struct tomoyo_io_buffer" structure.
272 *
273 * @head: Pointer to "struct tomoyo_io_buffer".
274 *
275 * Returns nothing.
276 */
179static bool tomoyo_set_lf(struct tomoyo_io_buffer *head) 277static bool tomoyo_set_lf(struct tomoyo_io_buffer *head)
180{ 278{
181 tomoyo_set_string(head, "\n"); 279 tomoyo_set_string(head, "\n");
@@ -183,6 +281,62 @@ static bool tomoyo_set_lf(struct tomoyo_io_buffer *head)
183} 281}
184 282
185/** 283/**
284 * tomoyo_set_slash - Put a shash to "struct tomoyo_io_buffer" structure.
285 *
286 * @head: Pointer to "struct tomoyo_io_buffer".
287 *
288 * Returns nothing.
289 */
290static void tomoyo_set_slash(struct tomoyo_io_buffer *head)
291{
292 tomoyo_set_string(head, "/");
293}
294
295/* List of namespaces. */
296LIST_HEAD(tomoyo_namespace_list);
297/* True if namespace other than tomoyo_kernel_namespace is defined. */
298static bool tomoyo_namespace_enabled;
299
300/**
301 * tomoyo_init_policy_namespace - Initialize namespace.
302 *
303 * @ns: Pointer to "struct tomoyo_policy_namespace".
304 *
305 * Returns nothing.
306 */
307void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns)
308{
309 unsigned int idx;
310 for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++)
311 INIT_LIST_HEAD(&ns->acl_group[idx]);
312 for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++)
313 INIT_LIST_HEAD(&ns->group_list[idx]);
314 for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++)
315 INIT_LIST_HEAD(&ns->policy_list[idx]);
316 ns->profile_version = 20100903;
317 tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list);
318 list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list);
319}
320
321/**
322 * tomoyo_print_namespace - Print namespace header.
323 *
324 * @head: Pointer to "struct tomoyo_io_buffer".
325 *
326 * Returns nothing.
327 */
328static void tomoyo_print_namespace(struct tomoyo_io_buffer *head)
329{
330 if (!tomoyo_namespace_enabled)
331 return;
332 tomoyo_set_string(head,
333 container_of(head->r.ns,
334 struct tomoyo_policy_namespace,
335 namespace_list)->name);
336 tomoyo_set_space(head);
337}
338
339/**
186 * tomoyo_print_name_union - Print a tomoyo_name_union. 340 * tomoyo_print_name_union - Print a tomoyo_name_union.
187 * 341 *
188 * @head: Pointer to "struct tomoyo_io_buffer". 342 * @head: Pointer to "struct tomoyo_io_buffer".
@@ -192,7 +346,7 @@ static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
192 const struct tomoyo_name_union *ptr) 346 const struct tomoyo_name_union *ptr)
193{ 347{
194 tomoyo_set_space(head); 348 tomoyo_set_space(head);
195 if (ptr->is_group) { 349 if (ptr->group) {
196 tomoyo_set_string(head, "@"); 350 tomoyo_set_string(head, "@");
197 tomoyo_set_string(head, ptr->group->group_name->name); 351 tomoyo_set_string(head, ptr->group->group_name->name);
198 } else { 352 } else {
@@ -201,24 +355,46 @@ static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
201} 355}
202 356
203/** 357/**
204 * tomoyo_print_number_union - Print a tomoyo_number_union. 358 * tomoyo_print_name_union_quoted - Print a tomoyo_name_union with a quote.
205 * 359 *
206 * @head: Pointer to "struct tomoyo_io_buffer". 360 * @head: Pointer to "struct tomoyo_io_buffer".
207 * @ptr: Pointer to "struct tomoyo_number_union". 361 * @ptr: Pointer to "struct tomoyo_name_union".
362 *
363 * Returns nothing.
208 */ 364 */
209static void tomoyo_print_number_union(struct tomoyo_io_buffer *head, 365static void tomoyo_print_name_union_quoted(struct tomoyo_io_buffer *head,
210 const struct tomoyo_number_union *ptr) 366 const struct tomoyo_name_union *ptr)
211{ 367{
212 tomoyo_set_space(head); 368 if (ptr->group) {
213 if (ptr->is_group) { 369 tomoyo_set_string(head, "@");
370 tomoyo_set_string(head, ptr->group->group_name->name);
371 } else {
372 tomoyo_set_string(head, "\"");
373 tomoyo_set_string(head, ptr->filename->name);
374 tomoyo_set_string(head, "\"");
375 }
376}
377
378/**
379 * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space.
380 *
381 * @head: Pointer to "struct tomoyo_io_buffer".
382 * @ptr: Pointer to "struct tomoyo_number_union".
383 *
384 * Returns nothing.
385 */
386static void tomoyo_print_number_union_nospace
387(struct tomoyo_io_buffer *head, const struct tomoyo_number_union *ptr)
388{
389 if (ptr->group) {
214 tomoyo_set_string(head, "@"); 390 tomoyo_set_string(head, "@");
215 tomoyo_set_string(head, ptr->group->group_name->name); 391 tomoyo_set_string(head, ptr->group->group_name->name);
216 } else { 392 } else {
217 int i; 393 int i;
218 unsigned long min = ptr->values[0]; 394 unsigned long min = ptr->values[0];
219 const unsigned long max = ptr->values[1]; 395 const unsigned long max = ptr->values[1];
220 u8 min_type = ptr->min_type; 396 u8 min_type = ptr->value_type[0];
221 const u8 max_type = ptr->max_type; 397 const u8 max_type = ptr->value_type[1];
222 char buffer[128]; 398 char buffer[128];
223 buffer[0] = '\0'; 399 buffer[0] = '\0';
224 for (i = 0; i < 2; i++) { 400 for (i = 0; i < 2; i++) {
@@ -232,8 +408,8 @@ static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
232 "0%lo", min); 408 "0%lo", min);
233 break; 409 break;
234 default: 410 default:
235 tomoyo_addprintf(buffer, sizeof(buffer), 411 tomoyo_addprintf(buffer, sizeof(buffer), "%lu",
236 "%lu", min); 412 min);
237 break; 413 break;
238 } 414 }
239 if (min == max && min_type == max_type) 415 if (min == max && min_type == max_type)
@@ -247,35 +423,53 @@ static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
247} 423}
248 424
249/** 425/**
426 * tomoyo_print_number_union - Print a tomoyo_number_union.
427 *
428 * @head: Pointer to "struct tomoyo_io_buffer".
429 * @ptr: Pointer to "struct tomoyo_number_union".
430 *
431 * Returns nothing.
432 */
433static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
434 const struct tomoyo_number_union *ptr)
435{
436 tomoyo_set_space(head);
437 tomoyo_print_number_union_nospace(head, ptr);
438}
439
440/**
250 * tomoyo_assign_profile - Create a new profile. 441 * tomoyo_assign_profile - Create a new profile.
251 * 442 *
443 * @ns: Pointer to "struct tomoyo_policy_namespace".
252 * @profile: Profile number to create. 444 * @profile: Profile number to create.
253 * 445 *
254 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise. 446 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise.
255 */ 447 */
256static struct tomoyo_profile *tomoyo_assign_profile(const unsigned int profile) 448static struct tomoyo_profile *tomoyo_assign_profile
449(struct tomoyo_policy_namespace *ns, const unsigned int profile)
257{ 450{
258 struct tomoyo_profile *ptr; 451 struct tomoyo_profile *ptr;
259 struct tomoyo_profile *entry; 452 struct tomoyo_profile *entry;
260 if (profile >= TOMOYO_MAX_PROFILES) 453 if (profile >= TOMOYO_MAX_PROFILES)
261 return NULL; 454 return NULL;
262 ptr = tomoyo_profile_ptr[profile]; 455 ptr = ns->profile_ptr[profile];
263 if (ptr) 456 if (ptr)
264 return ptr; 457 return ptr;
265 entry = kzalloc(sizeof(*entry), GFP_NOFS); 458 entry = kzalloc(sizeof(*entry), GFP_NOFS);
266 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 459 if (mutex_lock_interruptible(&tomoyo_policy_lock))
267 goto out; 460 goto out;
268 ptr = tomoyo_profile_ptr[profile]; 461 ptr = ns->profile_ptr[profile];
269 if (!ptr && tomoyo_memory_ok(entry)) { 462 if (!ptr && tomoyo_memory_ok(entry)) {
270 ptr = entry; 463 ptr = entry;
271 ptr->learning = &tomoyo_default_profile.preference; 464 ptr->default_config = TOMOYO_CONFIG_DISABLED |
272 ptr->permissive = &tomoyo_default_profile.preference; 465 TOMOYO_CONFIG_WANT_GRANT_LOG |
273 ptr->enforcing = &tomoyo_default_profile.preference; 466 TOMOYO_CONFIG_WANT_REJECT_LOG;
274 ptr->default_config = TOMOYO_CONFIG_DISABLED;
275 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT, 467 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT,
276 sizeof(ptr->config)); 468 sizeof(ptr->config));
469 ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] = 1024;
470 ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = 2048;
277 mb(); /* Avoid out-of-order execution. */ 471 mb(); /* Avoid out-of-order execution. */
278 tomoyo_profile_ptr[profile] = ptr; 472 ns->profile_ptr[profile] = ptr;
279 entry = NULL; 473 entry = NULL;
280 } 474 }
281 mutex_unlock(&tomoyo_policy_lock); 475 mutex_unlock(&tomoyo_policy_lock);
@@ -287,19 +481,29 @@ static struct tomoyo_profile *tomoyo_assign_profile(const unsigned int profile)
287/** 481/**
288 * tomoyo_profile - Find a profile. 482 * tomoyo_profile - Find a profile.
289 * 483 *
484 * @ns: Pointer to "struct tomoyo_policy_namespace".
290 * @profile: Profile number to find. 485 * @profile: Profile number to find.
291 * 486 *
292 * Returns pointer to "struct tomoyo_profile". 487 * Returns pointer to "struct tomoyo_profile".
293 */ 488 */
294struct tomoyo_profile *tomoyo_profile(const u8 profile) 489struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns,
490 const u8 profile)
295{ 491{
296 struct tomoyo_profile *ptr = tomoyo_profile_ptr[profile]; 492 static struct tomoyo_profile tomoyo_null_profile;
297 if (!tomoyo_policy_loaded) 493 struct tomoyo_profile *ptr = ns->profile_ptr[profile];
298 return &tomoyo_default_profile; 494 if (!ptr)
299 BUG_ON(!ptr); 495 ptr = &tomoyo_null_profile;
300 return ptr; 496 return ptr;
301} 497}
302 498
499/**
500 * tomoyo_find_yesno - Find values for specified keyword.
501 *
502 * @string: String to check.
503 * @find: Name of keyword.
504 *
505 * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise.
506 */
303static s8 tomoyo_find_yesno(const char *string, const char *find) 507static s8 tomoyo_find_yesno(const char *string, const char *find)
304{ 508{
305 const char *cp = strstr(string, find); 509 const char *cp = strstr(string, find);
@@ -313,18 +517,15 @@ static s8 tomoyo_find_yesno(const char *string, const char *find)
313 return -1; 517 return -1;
314} 518}
315 519
316static void tomoyo_set_bool(bool *b, const char *string, const char *find) 520/**
317{ 521 * tomoyo_set_uint - Set value for specified preference.
318 switch (tomoyo_find_yesno(string, find)) { 522 *
319 case 1: 523 * @i: Pointer to "unsigned int".
320 *b = true; 524 * @string: String to check.
321 break; 525 * @find: Name of keyword.
322 case 0: 526 *
323 *b = false; 527 * Returns nothing.
324 break; 528 */
325 }
326}
327
328static void tomoyo_set_uint(unsigned int *i, const char *string, 529static void tomoyo_set_uint(unsigned int *i, const char *string,
329 const char *find) 530 const char *find)
330{ 531{
@@ -333,51 +534,16 @@ static void tomoyo_set_uint(unsigned int *i, const char *string,
333 sscanf(cp + strlen(find), "=%u", i); 534 sscanf(cp + strlen(find), "=%u", i);
334} 535}
335 536
336static void tomoyo_set_pref(const char *name, const char *value, 537/**
337 const bool use_default, 538 * tomoyo_set_mode - Set mode for specified profile.
338 struct tomoyo_profile *profile) 539 *
339{ 540 * @name: Name of functionality.
340 struct tomoyo_preference **pref; 541 * @value: Mode for @name.
341 bool *verbose; 542 * @profile: Pointer to "struct tomoyo_profile".
342 if (!strcmp(name, "enforcing")) { 543 *
343 if (use_default) { 544 * Returns 0 on success, negative value otherwise.
344 pref = &profile->enforcing; 545 */
345 goto set_default;
346 }
347 profile->enforcing = &profile->preference;
348 verbose = &profile->preference.enforcing_verbose;
349 goto set_verbose;
350 }
351 if (!strcmp(name, "permissive")) {
352 if (use_default) {
353 pref = &profile->permissive;
354 goto set_default;
355 }
356 profile->permissive = &profile->preference;
357 verbose = &profile->preference.permissive_verbose;
358 goto set_verbose;
359 }
360 if (!strcmp(name, "learning")) {
361 if (use_default) {
362 pref = &profile->learning;
363 goto set_default;
364 }
365 profile->learning = &profile->preference;
366 tomoyo_set_uint(&profile->preference.learning_max_entry, value,
367 "max_entry");
368 verbose = &profile->preference.learning_verbose;
369 goto set_verbose;
370 }
371 return;
372 set_default:
373 *pref = &tomoyo_default_profile.preference;
374 return;
375 set_verbose:
376 tomoyo_set_bool(verbose, value, "verbose");
377}
378
379static int tomoyo_set_mode(char *name, const char *value, 546static int tomoyo_set_mode(char *name, const char *value,
380 const bool use_default,
381 struct tomoyo_profile *profile) 547 struct tomoyo_profile *profile)
382{ 548{
383 u8 i; 549 u8 i;
@@ -389,7 +555,17 @@ static int tomoyo_set_mode(char *name, const char *value,
389 config = 0; 555 config = 0;
390 for (i = 0; i < TOMOYO_MAX_MAC_INDEX 556 for (i = 0; i < TOMOYO_MAX_MAC_INDEX
391 + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) { 557 + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) {
392 if (strcmp(name, tomoyo_mac_keywords[i])) 558 int len = 0;
559 if (i < TOMOYO_MAX_MAC_INDEX) {
560 const u8 c = tomoyo_index2category[i];
561 const char *category =
562 tomoyo_category_keywords[c];
563 len = strlen(category);
564 if (strncmp(name, category, len) ||
565 name[len++] != ':' || name[len++] != ':')
566 continue;
567 }
568 if (strcmp(name + len, tomoyo_mac_keywords[i]))
393 continue; 569 continue;
394 config = profile->config[i]; 570 config = profile->config[i];
395 break; 571 break;
@@ -399,7 +575,7 @@ static int tomoyo_set_mode(char *name, const char *value,
399 } else { 575 } else {
400 return -EINVAL; 576 return -EINVAL;
401 } 577 }
402 if (use_default) { 578 if (strstr(value, "use_default")) {
403 config = TOMOYO_CONFIG_USE_DEFAULT; 579 config = TOMOYO_CONFIG_USE_DEFAULT;
404 } else { 580 } else {
405 u8 mode; 581 u8 mode;
@@ -410,6 +586,24 @@ static int tomoyo_set_mode(char *name, const char *value,
410 * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'. 586 * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'.
411 */ 587 */
412 config = (config & ~7) | mode; 588 config = (config & ~7) | mode;
589 if (config != TOMOYO_CONFIG_USE_DEFAULT) {
590 switch (tomoyo_find_yesno(value, "grant_log")) {
591 case 1:
592 config |= TOMOYO_CONFIG_WANT_GRANT_LOG;
593 break;
594 case 0:
595 config &= ~TOMOYO_CONFIG_WANT_GRANT_LOG;
596 break;
597 }
598 switch (tomoyo_find_yesno(value, "reject_log")) {
599 case 1:
600 config |= TOMOYO_CONFIG_WANT_REJECT_LOG;
601 break;
602 case 0:
603 config &= ~TOMOYO_CONFIG_WANT_REJECT_LOG;
604 break;
605 }
606 }
413 } 607 }
414 if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX) 608 if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
415 profile->config[i] = config; 609 profile->config[i] = config;
@@ -429,34 +623,22 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
429{ 623{
430 char *data = head->write_buf; 624 char *data = head->write_buf;
431 unsigned int i; 625 unsigned int i;
432 bool use_default = false;
433 char *cp; 626 char *cp;
434 struct tomoyo_profile *profile; 627 struct tomoyo_profile *profile;
435 if (sscanf(data, "PROFILE_VERSION=%u", &tomoyo_profile_version) == 1) 628 if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version)
629 == 1)
436 return 0; 630 return 0;
437 i = simple_strtoul(data, &cp, 10); 631 i = simple_strtoul(data, &cp, 10);
438 if (data == cp) { 632 if (*cp != '-')
439 profile = &tomoyo_default_profile; 633 return -EINVAL;
440 } else { 634 data = cp + 1;
441 if (*cp != '-') 635 profile = tomoyo_assign_profile(head->w.ns, i);
442 return -EINVAL; 636 if (!profile)
443 data = cp + 1; 637 return -EINVAL;
444 profile = tomoyo_assign_profile(i);
445 if (!profile)
446 return -EINVAL;
447 }
448 cp = strchr(data, '='); 638 cp = strchr(data, '=');
449 if (!cp) 639 if (!cp)
450 return -EINVAL; 640 return -EINVAL;
451 *cp++ = '\0'; 641 *cp++ = '\0';
452 if (profile != &tomoyo_default_profile)
453 use_default = strstr(cp, "use_default") != NULL;
454 if (tomoyo_str_starts(&data, "PREFERENCE::")) {
455 tomoyo_set_pref(data, cp, use_default, profile);
456 return 0;
457 }
458 if (profile == &tomoyo_default_profile)
459 return -EINVAL;
460 if (!strcmp(data, "COMMENT")) { 642 if (!strcmp(data, "COMMENT")) {
461 static DEFINE_SPINLOCK(lock); 643 static DEFINE_SPINLOCK(lock);
462 const struct tomoyo_path_info *new_comment 644 const struct tomoyo_path_info *new_comment
@@ -471,94 +653,91 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
471 tomoyo_put_name(old_comment); 653 tomoyo_put_name(old_comment);
472 return 0; 654 return 0;
473 } 655 }
474 return tomoyo_set_mode(data, cp, use_default, profile); 656 if (!strcmp(data, "PREFERENCE")) {
475} 657 for (i = 0; i < TOMOYO_MAX_PREF; i++)
476 658 tomoyo_set_uint(&profile->pref[i], cp,
477static void tomoyo_print_preference(struct tomoyo_io_buffer *head, 659 tomoyo_pref_keywords[i]);
478 const int idx) 660 return 0;
479{
480 struct tomoyo_preference *pref = &tomoyo_default_profile.preference;
481 const struct tomoyo_profile *profile = idx >= 0 ?
482 tomoyo_profile_ptr[idx] : NULL;
483 char buffer[16] = "";
484 if (profile) {
485 buffer[sizeof(buffer) - 1] = '\0';
486 snprintf(buffer, sizeof(buffer) - 1, "%u-", idx);
487 }
488 if (profile) {
489 pref = profile->learning;
490 if (pref == &tomoyo_default_profile.preference)
491 goto skip1;
492 }
493 tomoyo_io_printf(head, "%sPREFERENCE::%s={ "
494 "verbose=%s max_entry=%u }\n",
495 buffer, "learning",
496 tomoyo_yesno(pref->learning_verbose),
497 pref->learning_max_entry);
498 skip1:
499 if (profile) {
500 pref = profile->permissive;
501 if (pref == &tomoyo_default_profile.preference)
502 goto skip2;
503 }
504 tomoyo_io_printf(head, "%sPREFERENCE::%s={ verbose=%s }\n",
505 buffer, "permissive",
506 tomoyo_yesno(pref->permissive_verbose));
507 skip2:
508 if (profile) {
509 pref = profile->enforcing;
510 if (pref == &tomoyo_default_profile.preference)
511 return;
512 } 661 }
513 tomoyo_io_printf(head, "%sPREFERENCE::%s={ verbose=%s }\n", 662 return tomoyo_set_mode(data, cp, profile);
514 buffer, "enforcing",
515 tomoyo_yesno(pref->enforcing_verbose));
516} 663}
517 664
665/**
666 * tomoyo_print_config - Print mode for specified functionality.
667 *
668 * @head: Pointer to "struct tomoyo_io_buffer".
669 * @config: Mode for that functionality.
670 *
671 * Returns nothing.
672 *
673 * Caller prints functionality's name.
674 */
518static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config) 675static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config)
519{ 676{
520 tomoyo_io_printf(head, "={ mode=%s }\n", tomoyo_mode[config & 3]); 677 tomoyo_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n",
678 tomoyo_mode[config & 3],
679 tomoyo_yesno(config & TOMOYO_CONFIG_WANT_GRANT_LOG),
680 tomoyo_yesno(config & TOMOYO_CONFIG_WANT_REJECT_LOG));
521} 681}
522 682
523/** 683/**
524 * tomoyo_read_profile - Read profile table. 684 * tomoyo_read_profile - Read profile table.
525 * 685 *
526 * @head: Pointer to "struct tomoyo_io_buffer". 686 * @head: Pointer to "struct tomoyo_io_buffer".
687 *
688 * Returns nothing.
527 */ 689 */
528static void tomoyo_read_profile(struct tomoyo_io_buffer *head) 690static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
529{ 691{
530 u8 index; 692 u8 index;
693 struct tomoyo_policy_namespace *ns =
694 container_of(head->r.ns, typeof(*ns), namespace_list);
531 const struct tomoyo_profile *profile; 695 const struct tomoyo_profile *profile;
696 if (head->r.eof)
697 return;
532 next: 698 next:
533 index = head->r.index; 699 index = head->r.index;
534 profile = tomoyo_profile_ptr[index]; 700 profile = ns->profile_ptr[index];
535 switch (head->r.step) { 701 switch (head->r.step) {
536 case 0: 702 case 0:
537 tomoyo_io_printf(head, "PROFILE_VERSION=%s\n", "20090903"); 703 tomoyo_print_namespace(head);
538 tomoyo_print_preference(head, -1); 704 tomoyo_io_printf(head, "PROFILE_VERSION=%u\n",
705 ns->profile_version);
539 head->r.step++; 706 head->r.step++;
540 break; 707 break;
541 case 1: 708 case 1:
542 for ( ; head->r.index < TOMOYO_MAX_PROFILES; 709 for ( ; head->r.index < TOMOYO_MAX_PROFILES;
543 head->r.index++) 710 head->r.index++)
544 if (tomoyo_profile_ptr[head->r.index]) 711 if (ns->profile_ptr[head->r.index])
545 break; 712 break;
546 if (head->r.index == TOMOYO_MAX_PROFILES) 713 if (head->r.index == TOMOYO_MAX_PROFILES) {
714 head->r.eof = true;
547 return; 715 return;
716 }
548 head->r.step++; 717 head->r.step++;
549 break; 718 break;
550 case 2: 719 case 2:
551 { 720 {
721 u8 i;
552 const struct tomoyo_path_info *comment = 722 const struct tomoyo_path_info *comment =
553 profile->comment; 723 profile->comment;
724 tomoyo_print_namespace(head);
554 tomoyo_io_printf(head, "%u-COMMENT=", index); 725 tomoyo_io_printf(head, "%u-COMMENT=", index);
555 tomoyo_set_string(head, comment ? comment->name : ""); 726 tomoyo_set_string(head, comment ? comment->name : "");
556 tomoyo_set_lf(head); 727 tomoyo_set_lf(head);
728 tomoyo_print_namespace(head);
729 tomoyo_io_printf(head, "%u-PREFERENCE={ ", index);
730 for (i = 0; i < TOMOYO_MAX_PREF; i++)
731 tomoyo_io_printf(head, "%s=%u ",
732 tomoyo_pref_keywords[i],
733 profile->pref[i]);
734 tomoyo_set_string(head, "}\n");
557 head->r.step++; 735 head->r.step++;
558 } 736 }
559 break; 737 break;
560 case 3: 738 case 3:
561 { 739 {
740 tomoyo_print_namespace(head);
562 tomoyo_io_printf(head, "%u-%s", index, "CONFIG"); 741 tomoyo_io_printf(head, "%u-%s", index, "CONFIG");
563 tomoyo_print_config(head, profile->default_config); 742 tomoyo_print_config(head, profile->default_config);
564 head->r.bit = 0; 743 head->r.bit = 0;
@@ -572,15 +751,22 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
572 const u8 config = profile->config[i]; 751 const u8 config = profile->config[i];
573 if (config == TOMOYO_CONFIG_USE_DEFAULT) 752 if (config == TOMOYO_CONFIG_USE_DEFAULT)
574 continue; 753 continue;
575 tomoyo_io_printf(head, "%u-%s%s", index, "CONFIG::", 754 tomoyo_print_namespace(head);
576 tomoyo_mac_keywords[i]); 755 if (i < TOMOYO_MAX_MAC_INDEX)
756 tomoyo_io_printf(head, "%u-CONFIG::%s::%s",
757 index,
758 tomoyo_category_keywords
759 [tomoyo_index2category[i]],
760 tomoyo_mac_keywords[i]);
761 else
762 tomoyo_io_printf(head, "%u-CONFIG::%s", index,
763 tomoyo_mac_keywords[i]);
577 tomoyo_print_config(head, config); 764 tomoyo_print_config(head, config);
578 head->r.bit++; 765 head->r.bit++;
579 break; 766 break;
580 } 767 }
581 if (head->r.bit == TOMOYO_MAX_MAC_INDEX 768 if (head->r.bit == TOMOYO_MAX_MAC_INDEX
582 + TOMOYO_MAX_MAC_CATEGORY_INDEX) { 769 + TOMOYO_MAX_MAC_CATEGORY_INDEX) {
583 tomoyo_print_preference(head, index);
584 head->r.index++; 770 head->r.index++;
585 head->r.step = 1; 771 head->r.step = 1;
586 } 772 }
@@ -590,6 +776,14 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
590 goto next; 776 goto next;
591} 777}
592 778
779/**
780 * tomoyo_same_manager - Check for duplicated "struct tomoyo_manager" entry.
781 *
782 * @a: Pointer to "struct tomoyo_acl_head".
783 * @b: Pointer to "struct tomoyo_acl_head".
784 *
785 * Returns true if @a == @b, false otherwise.
786 */
593static bool tomoyo_same_manager(const struct tomoyo_acl_head *a, 787static bool tomoyo_same_manager(const struct tomoyo_acl_head *a,
594 const struct tomoyo_acl_head *b) 788 const struct tomoyo_acl_head *b)
595{ 789{
@@ -611,8 +805,13 @@ static int tomoyo_update_manager_entry(const char *manager,
611 const bool is_delete) 805 const bool is_delete)
612{ 806{
613 struct tomoyo_manager e = { }; 807 struct tomoyo_manager e = { };
614 int error; 808 struct tomoyo_acl_param param = {
615 809 /* .ns = &tomoyo_kernel_namespace, */
810 .is_delete = is_delete,
811 .list = &tomoyo_kernel_namespace.
812 policy_list[TOMOYO_ID_MANAGER],
813 };
814 int error = is_delete ? -ENOENT : -ENOMEM;
616 if (tomoyo_domain_def(manager)) { 815 if (tomoyo_domain_def(manager)) {
617 if (!tomoyo_correct_domain(manager)) 816 if (!tomoyo_correct_domain(manager))
618 return -EINVAL; 817 return -EINVAL;
@@ -622,12 +821,11 @@ static int tomoyo_update_manager_entry(const char *manager,
622 return -EINVAL; 821 return -EINVAL;
623 } 822 }
624 e.manager = tomoyo_get_name(manager); 823 e.manager = tomoyo_get_name(manager);
625 if (!e.manager) 824 if (e.manager) {
626 return -ENOMEM; 825 error = tomoyo_update_policy(&e.head, sizeof(e), &param,
627 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 826 tomoyo_same_manager);
628 &tomoyo_policy_list[TOMOYO_ID_MANAGER], 827 tomoyo_put_name(e.manager);
629 tomoyo_same_manager); 828 }
630 tomoyo_put_name(e.manager);
631 return error; 829 return error;
632} 830}
633 831
@@ -643,13 +841,12 @@ static int tomoyo_update_manager_entry(const char *manager,
643static int tomoyo_write_manager(struct tomoyo_io_buffer *head) 841static int tomoyo_write_manager(struct tomoyo_io_buffer *head)
644{ 842{
645 char *data = head->write_buf; 843 char *data = head->write_buf;
646 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE);
647 844
648 if (!strcmp(data, "manage_by_non_root")) { 845 if (!strcmp(data, "manage_by_non_root")) {
649 tomoyo_manage_by_non_root = !is_delete; 846 tomoyo_manage_by_non_root = !head->w.is_delete;
650 return 0; 847 return 0;
651 } 848 }
652 return tomoyo_update_manager_entry(data, is_delete); 849 return tomoyo_update_manager_entry(data, head->w.is_delete);
653} 850}
654 851
655/** 852/**
@@ -663,8 +860,8 @@ static void tomoyo_read_manager(struct tomoyo_io_buffer *head)
663{ 860{
664 if (head->r.eof) 861 if (head->r.eof)
665 return; 862 return;
666 list_for_each_cookie(head->r.acl, 863 list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace.
667 &tomoyo_policy_list[TOMOYO_ID_MANAGER]) { 864 policy_list[TOMOYO_ID_MANAGER]) {
668 struct tomoyo_manager *ptr = 865 struct tomoyo_manager *ptr =
669 list_entry(head->r.acl, typeof(*ptr), head.list); 866 list_entry(head->r.acl, typeof(*ptr), head.list);
670 if (ptr->head.is_deleted) 867 if (ptr->head.is_deleted)
@@ -697,8 +894,8 @@ static bool tomoyo_manager(void)
697 return true; 894 return true;
698 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) 895 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid))
699 return false; 896 return false;
700 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_MANAGER], 897 list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.
701 head.list) { 898 policy_list[TOMOYO_ID_MANAGER], head.list) {
702 if (!ptr->head.is_deleted && ptr->is_domain 899 if (!ptr->head.is_deleted && ptr->is_domain
703 && !tomoyo_pathcmp(domainname, ptr->manager)) { 900 && !tomoyo_pathcmp(domainname, ptr->manager)) {
704 found = true; 901 found = true;
@@ -710,8 +907,8 @@ static bool tomoyo_manager(void)
710 exe = tomoyo_get_exe(); 907 exe = tomoyo_get_exe();
711 if (!exe) 908 if (!exe)
712 return false; 909 return false;
713 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_MANAGER], 910 list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.
714 head.list) { 911 policy_list[TOMOYO_ID_MANAGER], head.list) {
715 if (!ptr->head.is_deleted && !ptr->is_domain 912 if (!ptr->head.is_deleted && !ptr->is_domain
716 && !strcmp(exe, ptr->manager->name)) { 913 && !strcmp(exe, ptr->manager->name)) {
717 found = true; 914 found = true;
@@ -732,7 +929,7 @@ static bool tomoyo_manager(void)
732} 929}
733 930
734/** 931/**
735 * tomoyo_select_one - Parse select command. 932 * tomoyo_select_domain - Parse select command.
736 * 933 *
737 * @head: Pointer to "struct tomoyo_io_buffer". 934 * @head: Pointer to "struct tomoyo_io_buffer".
738 * @data: String to parse. 935 * @data: String to parse.
@@ -741,16 +938,15 @@ static bool tomoyo_manager(void)
741 * 938 *
742 * Caller holds tomoyo_read_lock(). 939 * Caller holds tomoyo_read_lock().
743 */ 940 */
744static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data) 941static bool tomoyo_select_domain(struct tomoyo_io_buffer *head,
942 const char *data)
745{ 943{
746 unsigned int pid; 944 unsigned int pid;
747 struct tomoyo_domain_info *domain = NULL; 945 struct tomoyo_domain_info *domain = NULL;
748 bool global_pid = false; 946 bool global_pid = false;
749 947 if (strncmp(data, "select ", 7))
750 if (!strcmp(data, "allow_execute")) { 948 return false;
751 head->r.print_execute_only = true; 949 data += 7;
752 return true;
753 }
754 if (sscanf(data, "pid=%u", &pid) == 1 || 950 if (sscanf(data, "pid=%u", &pid) == 1 ||
755 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { 951 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
756 struct task_struct *p; 952 struct task_struct *p;
@@ -769,7 +965,7 @@ static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data)
769 domain = tomoyo_find_domain(data + 7); 965 domain = tomoyo_find_domain(data + 7);
770 } else 966 } else
771 return false; 967 return false;
772 head->write_var1 = domain; 968 head->w.domain = domain;
773 /* Accessing read_buf is safe because head->io_sem is held. */ 969 /* Accessing read_buf is safe because head->io_sem is held. */
774 if (!head->read_buf) 970 if (!head->read_buf)
775 return true; /* Do nothing if open(O_WRONLY). */ 971 return true; /* Do nothing if open(O_WRONLY). */
@@ -821,20 +1017,47 @@ static int tomoyo_delete_domain(char *domainname)
821/** 1017/**
822 * tomoyo_write_domain2 - Write domain policy. 1018 * tomoyo_write_domain2 - Write domain policy.
823 * 1019 *
824 * @head: Pointer to "struct tomoyo_io_buffer". 1020 * @ns: Pointer to "struct tomoyo_policy_namespace".
1021 * @list: Pointer to "struct list_head".
1022 * @data: Policy to be interpreted.
1023 * @is_delete: True if it is a delete request.
825 * 1024 *
826 * Returns 0 on success, negative value otherwise. 1025 * Returns 0 on success, negative value otherwise.
827 * 1026 *
828 * Caller holds tomoyo_read_lock(). 1027 * Caller holds tomoyo_read_lock().
829 */ 1028 */
830static int tomoyo_write_domain2(char *data, struct tomoyo_domain_info *domain, 1029static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns,
1030 struct list_head *list, char *data,
831 const bool is_delete) 1031 const bool is_delete)
832{ 1032{
833 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_MOUNT)) 1033 struct tomoyo_acl_param param = {
834 return tomoyo_write_mount(data, domain, is_delete); 1034 .ns = ns,
835 return tomoyo_write_file(data, domain, is_delete); 1035 .list = list,
1036 .data = data,
1037 .is_delete = is_delete,
1038 };
1039 static const struct {
1040 const char *keyword;
1041 int (*write) (struct tomoyo_acl_param *);
1042 } tomoyo_callback[1] = {
1043 { "file ", tomoyo_write_file },
1044 };
1045 u8 i;
1046 for (i = 0; i < 1; i++) {
1047 if (!tomoyo_str_starts(&param.data,
1048 tomoyo_callback[i].keyword))
1049 continue;
1050 return tomoyo_callback[i].write(&param);
1051 }
1052 return -EINVAL;
836} 1053}
837 1054
1055/* String table for domain flags. */
1056const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS] = {
1057 [TOMOYO_DIF_QUOTA_WARNED] = "quota_exceeded\n",
1058 [TOMOYO_DIF_TRANSITION_FAILED] = "transition_failed\n",
1059};
1060
838/** 1061/**
839 * tomoyo_write_domain - Write domain policy. 1062 * tomoyo_write_domain - Write domain policy.
840 * 1063 *
@@ -847,69 +1070,198 @@ static int tomoyo_write_domain2(char *data, struct tomoyo_domain_info *domain,
847static int tomoyo_write_domain(struct tomoyo_io_buffer *head) 1070static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
848{ 1071{
849 char *data = head->write_buf; 1072 char *data = head->write_buf;
850 struct tomoyo_domain_info *domain = head->write_var1; 1073 struct tomoyo_policy_namespace *ns;
851 bool is_delete = false; 1074 struct tomoyo_domain_info *domain = head->w.domain;
852 bool is_select = false; 1075 const bool is_delete = head->w.is_delete;
1076 bool is_select = !is_delete && tomoyo_str_starts(&data, "select ");
853 unsigned int profile; 1077 unsigned int profile;
854 1078 if (*data == '<') {
855 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE))
856 is_delete = true;
857 else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT))
858 is_select = true;
859 if (is_select && tomoyo_select_one(head, data))
860 return 0;
861 /* Don't allow updating policies by non manager programs. */
862 if (!tomoyo_manager())
863 return -EPERM;
864 if (tomoyo_domain_def(data)) {
865 domain = NULL; 1079 domain = NULL;
866 if (is_delete) 1080 if (is_delete)
867 tomoyo_delete_domain(data); 1081 tomoyo_delete_domain(data);
868 else if (is_select) 1082 else if (is_select)
869 domain = tomoyo_find_domain(data); 1083 domain = tomoyo_find_domain(data);
870 else 1084 else
871 domain = tomoyo_assign_domain(data, 0); 1085 domain = tomoyo_assign_domain(data, false);
872 head->write_var1 = domain; 1086 head->w.domain = domain;
873 return 0; 1087 return 0;
874 } 1088 }
875 if (!domain) 1089 if (!domain)
876 return -EINVAL; 1090 return -EINVAL;
877 1091 ns = domain->ns;
878 if (sscanf(data, TOMOYO_KEYWORD_USE_PROFILE "%u", &profile) == 1 1092 if (sscanf(data, "use_profile %u", &profile) == 1
879 && profile < TOMOYO_MAX_PROFILES) { 1093 && profile < TOMOYO_MAX_PROFILES) {
880 if (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded) 1094 if (!tomoyo_policy_loaded || ns->profile_ptr[profile])
881 domain->profile = (u8) profile; 1095 domain->profile = (u8) profile;
882 return 0; 1096 return 0;
883 } 1097 }
884 if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) { 1098 if (sscanf(data, "use_group %u\n", &profile) == 1
885 domain->ignore_global_allow_read = !is_delete; 1099 && profile < TOMOYO_MAX_ACL_GROUPS) {
1100 if (!is_delete)
1101 domain->group = (u8) profile;
886 return 0; 1102 return 0;
887 } 1103 }
888 if (!strcmp(data, TOMOYO_KEYWORD_QUOTA_EXCEEDED)) { 1104 for (profile = 0; profile < TOMOYO_MAX_DOMAIN_INFO_FLAGS; profile++) {
889 domain->quota_warned = !is_delete; 1105 const char *cp = tomoyo_dif[profile];
890 return 0; 1106 if (strncmp(data, cp, strlen(cp) - 1))
891 } 1107 continue;
892 if (!strcmp(data, TOMOYO_KEYWORD_TRANSITION_FAILED)) { 1108 domain->flags[profile] = !is_delete;
893 domain->transition_failed = !is_delete;
894 return 0; 1109 return 0;
895 } 1110 }
896 return tomoyo_write_domain2(data, domain, is_delete); 1111 return tomoyo_write_domain2(ns, &domain->acl_info_list, data,
1112 is_delete);
897} 1113}
898 1114
899/** 1115/**
900 * tomoyo_fns - Find next set bit. 1116 * tomoyo_print_condition - Print condition part.
901 * 1117 *
902 * @perm: 8 bits value. 1118 * @head: Pointer to "struct tomoyo_io_buffer".
903 * @bit: First bit to find. 1119 * @cond: Pointer to "struct tomoyo_condition".
904 * 1120 *
905 * Returns next on-bit on success, 8 otherwise. 1121 * Returns true on success, false otherwise.
906 */ 1122 */
907static u8 tomoyo_fns(const u8 perm, u8 bit) 1123static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
1124 const struct tomoyo_condition *cond)
908{ 1125{
909 for ( ; bit < 8; bit++) 1126 switch (head->r.cond_step) {
910 if (perm & (1 << bit)) 1127 case 0:
1128 head->r.cond_index = 0;
1129 head->r.cond_step++;
1130 /* fall through */
1131 case 1:
1132 {
1133 const u16 condc = cond->condc;
1134 const struct tomoyo_condition_element *condp =
1135 (typeof(condp)) (cond + 1);
1136 const struct tomoyo_number_union *numbers_p =
1137 (typeof(numbers_p)) (condp + condc);
1138 const struct tomoyo_name_union *names_p =
1139 (typeof(names_p))
1140 (numbers_p + cond->numbers_count);
1141 const struct tomoyo_argv *argv =
1142 (typeof(argv)) (names_p + cond->names_count);
1143 const struct tomoyo_envp *envp =
1144 (typeof(envp)) (argv + cond->argc);
1145 u16 skip;
1146 for (skip = 0; skip < head->r.cond_index; skip++) {
1147 const u8 left = condp->left;
1148 const u8 right = condp->right;
1149 condp++;
1150 switch (left) {
1151 case TOMOYO_ARGV_ENTRY:
1152 argv++;
1153 continue;
1154 case TOMOYO_ENVP_ENTRY:
1155 envp++;
1156 continue;
1157 case TOMOYO_NUMBER_UNION:
1158 numbers_p++;
1159 break;
1160 }
1161 switch (right) {
1162 case TOMOYO_NAME_UNION:
1163 names_p++;
1164 break;
1165 case TOMOYO_NUMBER_UNION:
1166 numbers_p++;
1167 break;
1168 }
1169 }
1170 while (head->r.cond_index < condc) {
1171 const u8 match = condp->equals;
1172 const u8 left = condp->left;
1173 const u8 right = condp->right;
1174 if (!tomoyo_flush(head))
1175 return false;
1176 condp++;
1177 head->r.cond_index++;
1178 tomoyo_set_space(head);
1179 switch (left) {
1180 case TOMOYO_ARGV_ENTRY:
1181 tomoyo_io_printf(head,
1182 "exec.argv[%lu]%s=\"",
1183 argv->index, argv->
1184 is_not ? "!" : "");
1185 tomoyo_set_string(head,
1186 argv->value->name);
1187 tomoyo_set_string(head, "\"");
1188 argv++;
1189 continue;
1190 case TOMOYO_ENVP_ENTRY:
1191 tomoyo_set_string(head,
1192 "exec.envp[\"");
1193 tomoyo_set_string(head,
1194 envp->name->name);
1195 tomoyo_io_printf(head, "\"]%s=", envp->
1196 is_not ? "!" : "");
1197 if (envp->value) {
1198 tomoyo_set_string(head, "\"");
1199 tomoyo_set_string(head, envp->
1200 value->name);
1201 tomoyo_set_string(head, "\"");
1202 } else {
1203 tomoyo_set_string(head,
1204 "NULL");
1205 }
1206 envp++;
1207 continue;
1208 case TOMOYO_NUMBER_UNION:
1209 tomoyo_print_number_union_nospace
1210 (head, numbers_p++);
1211 break;
1212 default:
1213 tomoyo_set_string(head,
1214 tomoyo_condition_keyword[left]);
1215 break;
1216 }
1217 tomoyo_set_string(head, match ? "=" : "!=");
1218 switch (right) {
1219 case TOMOYO_NAME_UNION:
1220 tomoyo_print_name_union_quoted
1221 (head, names_p++);
1222 break;
1223 case TOMOYO_NUMBER_UNION:
1224 tomoyo_print_number_union_nospace
1225 (head, numbers_p++);
1226 break;
1227 default:
1228 tomoyo_set_string(head,
1229 tomoyo_condition_keyword[right]);
1230 break;
1231 }
1232 }
1233 }
1234 head->r.cond_step++;
1235 /* fall through */
1236 case 2:
1237 if (!tomoyo_flush(head))
911 break; 1238 break;
912 return bit; 1239 head->r.cond_step++;
1240 /* fall through */
1241 case 3:
1242 tomoyo_set_lf(head);
1243 return true;
1244 }
1245 return false;
1246}
1247
1248/**
1249 * tomoyo_set_group - Print "acl_group " header keyword and category name.
1250 *
1251 * @head: Pointer to "struct tomoyo_io_buffer".
1252 * @category: Category name.
1253 *
1254 * Returns nothing.
1255 */
1256static void tomoyo_set_group(struct tomoyo_io_buffer *head,
1257 const char *category)
1258{
1259 if (head->type == TOMOYO_EXCEPTIONPOLICY) {
1260 tomoyo_print_namespace(head);
1261 tomoyo_io_printf(head, "acl_group %u ",
1262 head->r.acl_group_index);
1263 }
1264 tomoyo_set_string(head, category);
913} 1265}
914 1266
915/** 1267/**
@@ -924,63 +1276,96 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
924 struct tomoyo_acl_info *acl) 1276 struct tomoyo_acl_info *acl)
925{ 1277{
926 const u8 acl_type = acl->type; 1278 const u8 acl_type = acl->type;
1279 bool first = true;
927 u8 bit; 1280 u8 bit;
928 1281
1282 if (head->r.print_cond_part)
1283 goto print_cond_part;
929 if (acl->is_deleted) 1284 if (acl->is_deleted)
930 return true; 1285 return true;
931 next:
932 bit = head->r.bit;
933 if (!tomoyo_flush(head)) 1286 if (!tomoyo_flush(head))
934 return false; 1287 return false;
935 else if (acl_type == TOMOYO_TYPE_PATH_ACL) { 1288 else if (acl_type == TOMOYO_TYPE_PATH_ACL) {
936 struct tomoyo_path_acl *ptr = 1289 struct tomoyo_path_acl *ptr =
937 container_of(acl, typeof(*ptr), head); 1290 container_of(acl, typeof(*ptr), head);
938 const u16 perm = ptr->perm; 1291 const u16 perm = ptr->perm;
939 for ( ; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { 1292 for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
940 if (!(perm & (1 << bit))) 1293 if (!(perm & (1 << bit)))
941 continue; 1294 continue;
942 if (head->r.print_execute_only && 1295 if (head->r.print_transition_related_only &&
943 bit != TOMOYO_TYPE_EXECUTE) 1296 bit != TOMOYO_TYPE_EXECUTE)
944 continue; 1297 continue;
945 /* Print "read/write" instead of "read" and "write". */ 1298 if (first) {
946 if ((bit == TOMOYO_TYPE_READ || 1299 tomoyo_set_group(head, "file ");
947 bit == TOMOYO_TYPE_WRITE) 1300 first = false;
948 && (perm & (1 << TOMOYO_TYPE_READ_WRITE))) 1301 } else {
949 continue; 1302 tomoyo_set_slash(head);
950 break; 1303 }
1304 tomoyo_set_string(head, tomoyo_path_keyword[bit]);
951 } 1305 }
952 if (bit >= TOMOYO_MAX_PATH_OPERATION) 1306 if (first)
953 goto done; 1307 return true;
954 tomoyo_io_printf(head, "allow_%s", tomoyo_path_keyword[bit]);
955 tomoyo_print_name_union(head, &ptr->name); 1308 tomoyo_print_name_union(head, &ptr->name);
956 } else if (head->r.print_execute_only) { 1309 } else if (head->r.print_transition_related_only) {
957 return true; 1310 return true;
958 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) { 1311 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
959 struct tomoyo_path2_acl *ptr = 1312 struct tomoyo_path2_acl *ptr =
960 container_of(acl, typeof(*ptr), head); 1313 container_of(acl, typeof(*ptr), head);
961 bit = tomoyo_fns(ptr->perm, bit); 1314 const u8 perm = ptr->perm;
962 if (bit >= TOMOYO_MAX_PATH2_OPERATION) 1315 for (bit = 0; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) {
963 goto done; 1316 if (!(perm & (1 << bit)))
964 tomoyo_io_printf(head, "allow_%s", tomoyo_path2_keyword[bit]); 1317 continue;
1318 if (first) {
1319 tomoyo_set_group(head, "file ");
1320 first = false;
1321 } else {
1322 tomoyo_set_slash(head);
1323 }
1324 tomoyo_set_string(head, tomoyo_mac_keywords
1325 [tomoyo_pp2mac[bit]]);
1326 }
1327 if (first)
1328 return true;
965 tomoyo_print_name_union(head, &ptr->name1); 1329 tomoyo_print_name_union(head, &ptr->name1);
966 tomoyo_print_name_union(head, &ptr->name2); 1330 tomoyo_print_name_union(head, &ptr->name2);
967 } else if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) { 1331 } else if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) {
968 struct tomoyo_path_number_acl *ptr = 1332 struct tomoyo_path_number_acl *ptr =
969 container_of(acl, typeof(*ptr), head); 1333 container_of(acl, typeof(*ptr), head);
970 bit = tomoyo_fns(ptr->perm, bit); 1334 const u8 perm = ptr->perm;
971 if (bit >= TOMOYO_MAX_PATH_NUMBER_OPERATION) 1335 for (bit = 0; bit < TOMOYO_MAX_PATH_NUMBER_OPERATION; bit++) {
972 goto done; 1336 if (!(perm & (1 << bit)))
973 tomoyo_io_printf(head, "allow_%s", 1337 continue;
974 tomoyo_path_number_keyword[bit]); 1338 if (first) {
1339 tomoyo_set_group(head, "file ");
1340 first = false;
1341 } else {
1342 tomoyo_set_slash(head);
1343 }
1344 tomoyo_set_string(head, tomoyo_mac_keywords
1345 [tomoyo_pn2mac[bit]]);
1346 }
1347 if (first)
1348 return true;
975 tomoyo_print_name_union(head, &ptr->name); 1349 tomoyo_print_name_union(head, &ptr->name);
976 tomoyo_print_number_union(head, &ptr->number); 1350 tomoyo_print_number_union(head, &ptr->number);
977 } else if (acl_type == TOMOYO_TYPE_MKDEV_ACL) { 1351 } else if (acl_type == TOMOYO_TYPE_MKDEV_ACL) {
978 struct tomoyo_mkdev_acl *ptr = 1352 struct tomoyo_mkdev_acl *ptr =
979 container_of(acl, typeof(*ptr), head); 1353 container_of(acl, typeof(*ptr), head);
980 bit = tomoyo_fns(ptr->perm, bit); 1354 const u8 perm = ptr->perm;
981 if (bit >= TOMOYO_MAX_MKDEV_OPERATION) 1355 for (bit = 0; bit < TOMOYO_MAX_MKDEV_OPERATION; bit++) {
982 goto done; 1356 if (!(perm & (1 << bit)))
983 tomoyo_io_printf(head, "allow_%s", tomoyo_mkdev_keyword[bit]); 1357 continue;
1358 if (first) {
1359 tomoyo_set_group(head, "file ");
1360 first = false;
1361 } else {
1362 tomoyo_set_slash(head);
1363 }
1364 tomoyo_set_string(head, tomoyo_mac_keywords
1365 [tomoyo_pnnn2mac[bit]]);
1366 }
1367 if (first)
1368 return true;
984 tomoyo_print_name_union(head, &ptr->name); 1369 tomoyo_print_name_union(head, &ptr->name);
985 tomoyo_print_number_union(head, &ptr->mode); 1370 tomoyo_print_number_union(head, &ptr->mode);
986 tomoyo_print_number_union(head, &ptr->major); 1371 tomoyo_print_number_union(head, &ptr->major);
@@ -988,35 +1373,41 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
988 } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { 1373 } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) {
989 struct tomoyo_mount_acl *ptr = 1374 struct tomoyo_mount_acl *ptr =
990 container_of(acl, typeof(*ptr), head); 1375 container_of(acl, typeof(*ptr), head);
991 tomoyo_io_printf(head, "allow_mount"); 1376 tomoyo_set_group(head, "file mount");
992 tomoyo_print_name_union(head, &ptr->dev_name); 1377 tomoyo_print_name_union(head, &ptr->dev_name);
993 tomoyo_print_name_union(head, &ptr->dir_name); 1378 tomoyo_print_name_union(head, &ptr->dir_name);
994 tomoyo_print_name_union(head, &ptr->fs_type); 1379 tomoyo_print_name_union(head, &ptr->fs_type);
995 tomoyo_print_number_union(head, &ptr->flags); 1380 tomoyo_print_number_union(head, &ptr->flags);
996 } 1381 }
997 head->r.bit = bit + 1; 1382 if (acl->cond) {
998 tomoyo_io_printf(head, "\n"); 1383 head->r.print_cond_part = true;
999 if (acl_type != TOMOYO_TYPE_MOUNT_ACL) 1384 head->r.cond_step = 0;
1000 goto next; 1385 if (!tomoyo_flush(head))
1001 done: 1386 return false;
1002 head->r.bit = 0; 1387print_cond_part:
1388 if (!tomoyo_print_condition(head, acl->cond))
1389 return false;
1390 head->r.print_cond_part = false;
1391 } else {
1392 tomoyo_set_lf(head);
1393 }
1003 return true; 1394 return true;
1004} 1395}
1005 1396
1006/** 1397/**
1007 * tomoyo_read_domain2 - Read domain policy. 1398 * tomoyo_read_domain2 - Read domain policy.
1008 * 1399 *
1009 * @head: Pointer to "struct tomoyo_io_buffer". 1400 * @head: Pointer to "struct tomoyo_io_buffer".
1010 * @domain: Pointer to "struct tomoyo_domain_info". 1401 * @list: Pointer to "struct list_head".
1011 * 1402 *
1012 * Caller holds tomoyo_read_lock(). 1403 * Caller holds tomoyo_read_lock().
1013 * 1404 *
1014 * Returns true on success, false otherwise. 1405 * Returns true on success, false otherwise.
1015 */ 1406 */
1016static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head, 1407static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head,
1017 struct tomoyo_domain_info *domain) 1408 struct list_head *list)
1018{ 1409{
1019 list_for_each_cookie(head->r.acl, &domain->acl_info_list) { 1410 list_for_each_cookie(head->r.acl, list) {
1020 struct tomoyo_acl_info *ptr = 1411 struct tomoyo_acl_info *ptr =
1021 list_entry(head->r.acl, typeof(*ptr), list); 1412 list_entry(head->r.acl, typeof(*ptr), list);
1022 if (!tomoyo_print_entry(head, ptr)) 1413 if (!tomoyo_print_entry(head, ptr))
@@ -1041,6 +1432,7 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
1041 struct tomoyo_domain_info *domain = 1432 struct tomoyo_domain_info *domain =
1042 list_entry(head->r.domain, typeof(*domain), list); 1433 list_entry(head->r.domain, typeof(*domain), list);
1043 switch (head->r.step) { 1434 switch (head->r.step) {
1435 u8 i;
1044 case 0: 1436 case 0:
1045 if (domain->is_deleted && 1437 if (domain->is_deleted &&
1046 !head->r.print_this_domain_only) 1438 !head->r.print_this_domain_only)
@@ -1048,22 +1440,18 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
1048 /* Print domainname and flags. */ 1440 /* Print domainname and flags. */
1049 tomoyo_set_string(head, domain->domainname->name); 1441 tomoyo_set_string(head, domain->domainname->name);
1050 tomoyo_set_lf(head); 1442 tomoyo_set_lf(head);
1051 tomoyo_io_printf(head, 1443 tomoyo_io_printf(head, "use_profile %u\n",
1052 TOMOYO_KEYWORD_USE_PROFILE "%u\n",
1053 domain->profile); 1444 domain->profile);
1054 if (domain->quota_warned) 1445 tomoyo_io_printf(head, "use_group %u\n",
1055 tomoyo_set_string(head, "quota_exceeded\n"); 1446 domain->group);
1056 if (domain->transition_failed) 1447 for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++)
1057 tomoyo_set_string(head, "transition_failed\n"); 1448 if (domain->flags[i])
1058 if (domain->ignore_global_allow_read) 1449 tomoyo_set_string(head, tomoyo_dif[i]);
1059 tomoyo_set_string(head,
1060 TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ
1061 "\n");
1062 head->r.step++; 1450 head->r.step++;
1063 tomoyo_set_lf(head); 1451 tomoyo_set_lf(head);
1064 /* fall through */ 1452 /* fall through */
1065 case 1: 1453 case 1:
1066 if (!tomoyo_read_domain2(head, domain)) 1454 if (!tomoyo_read_domain2(head, &domain->acl_info_list))
1067 return; 1455 return;
1068 head->r.step++; 1456 head->r.step++;
1069 if (!tomoyo_set_lf(head)) 1457 if (!tomoyo_set_lf(head))
@@ -1080,73 +1468,6 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
1080} 1468}
1081 1469
1082/** 1470/**
1083 * tomoyo_write_domain_profile - Assign profile for specified domain.
1084 *
1085 * @head: Pointer to "struct tomoyo_io_buffer".
1086 *
1087 * Returns 0 on success, -EINVAL otherwise.
1088 *
1089 * This is equivalent to doing
1090 *
1091 * ( echo "select " $domainname; echo "use_profile " $profile ) |
1092 * /usr/sbin/tomoyo-loadpolicy -d
1093 *
1094 * Caller holds tomoyo_read_lock().
1095 */
1096static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
1097{
1098 char *data = head->write_buf;
1099 char *cp = strchr(data, ' ');
1100 struct tomoyo_domain_info *domain;
1101 unsigned long profile;
1102
1103 if (!cp)
1104 return -EINVAL;
1105 *cp = '\0';
1106 domain = tomoyo_find_domain(cp + 1);
1107 if (strict_strtoul(data, 10, &profile))
1108 return -EINVAL;
1109 if (domain && profile < TOMOYO_MAX_PROFILES
1110 && (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded))
1111 domain->profile = (u8) profile;
1112 return 0;
1113}
1114
1115/**
1116 * tomoyo_read_domain_profile - Read only domainname and profile.
1117 *
1118 * @head: Pointer to "struct tomoyo_io_buffer".
1119 *
1120 * Returns list of profile number and domainname pairs.
1121 *
1122 * This is equivalent to doing
1123 *
1124 * grep -A 1 '^<kernel>' /sys/kernel/security/tomoyo/domain_policy |
1125 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
1126 * domainname = $0; } else if ( $1 == "use_profile" ) {
1127 * print $2 " " domainname; domainname = ""; } } ; '
1128 *
1129 * Caller holds tomoyo_read_lock().
1130 */
1131static void tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1132{
1133 if (head->r.eof)
1134 return;
1135 list_for_each_cookie(head->r.domain, &tomoyo_domain_list) {
1136 struct tomoyo_domain_info *domain =
1137 list_entry(head->r.domain, typeof(*domain), list);
1138 if (domain->is_deleted)
1139 continue;
1140 if (!tomoyo_flush(head))
1141 return;
1142 tomoyo_io_printf(head, "%u ", domain->profile);
1143 tomoyo_set_string(head, domain->domainname->name);
1144 tomoyo_set_lf(head);
1145 }
1146 head->r.eof = true;
1147}
1148
1149/**
1150 * tomoyo_write_pid: Specify PID to obtain domainname. 1471 * tomoyo_write_pid: Specify PID to obtain domainname.
1151 * 1472 *
1152 * @head: Pointer to "struct tomoyo_io_buffer". 1473 * @head: Pointer to "struct tomoyo_io_buffer".
@@ -1204,18 +1525,20 @@ static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
1204 tomoyo_set_string(head, domain->domainname->name); 1525 tomoyo_set_string(head, domain->domainname->name);
1205} 1526}
1206 1527
1528/* String table for domain transition control keywords. */
1207static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = { 1529static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = {
1208 [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] 1530 [TOMOYO_TRANSITION_CONTROL_NO_RESET] = "no_reset_domain ",
1209 = TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN, 1531 [TOMOYO_TRANSITION_CONTROL_RESET] = "reset_domain ",
1210 [TOMOYO_TRANSITION_CONTROL_INITIALIZE] 1532 [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ",
1211 = TOMOYO_KEYWORD_INITIALIZE_DOMAIN, 1533 [TOMOYO_TRANSITION_CONTROL_INITIALIZE] = "initialize_domain ",
1212 [TOMOYO_TRANSITION_CONTROL_NO_KEEP] = TOMOYO_KEYWORD_NO_KEEP_DOMAIN, 1534 [TOMOYO_TRANSITION_CONTROL_NO_KEEP] = "no_keep_domain ",
1213 [TOMOYO_TRANSITION_CONTROL_KEEP] = TOMOYO_KEYWORD_KEEP_DOMAIN 1535 [TOMOYO_TRANSITION_CONTROL_KEEP] = "keep_domain ",
1214}; 1536};
1215 1537
1538/* String table for grouping keywords. */
1216static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { 1539static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
1217 [TOMOYO_PATH_GROUP] = TOMOYO_KEYWORD_PATH_GROUP, 1540 [TOMOYO_PATH_GROUP] = "path_group ",
1218 [TOMOYO_NUMBER_GROUP] = TOMOYO_KEYWORD_NUMBER_GROUP 1541 [TOMOYO_NUMBER_GROUP] = "number_group ",
1219}; 1542};
1220 1543
1221/** 1544/**
@@ -1229,29 +1552,30 @@ static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
1229 */ 1552 */
1230static int tomoyo_write_exception(struct tomoyo_io_buffer *head) 1553static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
1231{ 1554{
1232 char *data = head->write_buf; 1555 const bool is_delete = head->w.is_delete;
1233 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE); 1556 struct tomoyo_acl_param param = {
1234 u8 i; 1557 .ns = head->w.ns,
1235 static const struct { 1558 .is_delete = is_delete,
1236 const char *keyword; 1559 .data = head->write_buf,
1237 int (*write) (char *, const bool);
1238 } tomoyo_callback[4] = {
1239 { TOMOYO_KEYWORD_AGGREGATOR, tomoyo_write_aggregator },
1240 { TOMOYO_KEYWORD_FILE_PATTERN, tomoyo_write_pattern },
1241 { TOMOYO_KEYWORD_DENY_REWRITE, tomoyo_write_no_rewrite },
1242 { TOMOYO_KEYWORD_ALLOW_READ, tomoyo_write_globally_readable },
1243 }; 1560 };
1244 1561 u8 i;
1562 if (tomoyo_str_starts(&param.data, "aggregator "))
1563 return tomoyo_write_aggregator(&param);
1245 for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) 1564 for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++)
1246 if (tomoyo_str_starts(&data, tomoyo_transition_type[i])) 1565 if (tomoyo_str_starts(&param.data, tomoyo_transition_type[i]))
1247 return tomoyo_write_transition_control(data, is_delete, 1566 return tomoyo_write_transition_control(&param, i);
1248 i);
1249 for (i = 0; i < 4; i++)
1250 if (tomoyo_str_starts(&data, tomoyo_callback[i].keyword))
1251 return tomoyo_callback[i].write(data, is_delete);
1252 for (i = 0; i < TOMOYO_MAX_GROUP; i++) 1567 for (i = 0; i < TOMOYO_MAX_GROUP; i++)
1253 if (tomoyo_str_starts(&data, tomoyo_group_name[i])) 1568 if (tomoyo_str_starts(&param.data, tomoyo_group_name[i]))
1254 return tomoyo_write_group(data, is_delete, i); 1569 return tomoyo_write_group(&param, i);
1570 if (tomoyo_str_starts(&param.data, "acl_group ")) {
1571 unsigned int group;
1572 char *data;
1573 group = simple_strtoul(param.data, &data, 10);
1574 if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ')
1575 return tomoyo_write_domain2
1576 (head->w.ns, &head->w.ns->acl_group[group],
1577 data, is_delete);
1578 }
1255 return -EINVAL; 1579 return -EINVAL;
1256} 1580}
1257 1581
@@ -1267,9 +1591,12 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
1267 */ 1591 */
1268static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) 1592static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1269{ 1593{
1270 list_for_each_cookie(head->r.group, &tomoyo_group_list[idx]) { 1594 struct tomoyo_policy_namespace *ns =
1595 container_of(head->r.ns, typeof(*ns), namespace_list);
1596 struct list_head *list = &ns->group_list[idx];
1597 list_for_each_cookie(head->r.group, list) {
1271 struct tomoyo_group *group = 1598 struct tomoyo_group *group =
1272 list_entry(head->r.group, typeof(*group), list); 1599 list_entry(head->r.group, typeof(*group), head.list);
1273 list_for_each_cookie(head->r.acl, &group->member_list) { 1600 list_for_each_cookie(head->r.acl, &group->member_list) {
1274 struct tomoyo_acl_head *ptr = 1601 struct tomoyo_acl_head *ptr =
1275 list_entry(head->r.acl, typeof(*ptr), list); 1602 list_entry(head->r.acl, typeof(*ptr), list);
@@ -1277,6 +1604,7 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1277 continue; 1604 continue;
1278 if (!tomoyo_flush(head)) 1605 if (!tomoyo_flush(head))
1279 return false; 1606 return false;
1607 tomoyo_print_namespace(head);
1280 tomoyo_set_string(head, tomoyo_group_name[idx]); 1608 tomoyo_set_string(head, tomoyo_group_name[idx]);
1281 tomoyo_set_string(head, group->group_name->name); 1609 tomoyo_set_string(head, group->group_name->name);
1282 if (idx == TOMOYO_PATH_GROUP) { 1610 if (idx == TOMOYO_PATH_GROUP) {
@@ -1310,7 +1638,10 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1310 */ 1638 */
1311static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) 1639static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1312{ 1640{
1313 list_for_each_cookie(head->r.acl, &tomoyo_policy_list[idx]) { 1641 struct tomoyo_policy_namespace *ns =
1642 container_of(head->r.ns, typeof(*ns), namespace_list);
1643 struct list_head *list = &ns->policy_list[idx];
1644 list_for_each_cookie(head->r.acl, list) {
1314 struct tomoyo_acl_head *acl = 1645 struct tomoyo_acl_head *acl =
1315 container_of(head->r.acl, typeof(*acl), list); 1646 container_of(head->r.acl, typeof(*acl), list);
1316 if (acl->is_deleted) 1647 if (acl->is_deleted)
@@ -1322,35 +1653,23 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1322 { 1653 {
1323 struct tomoyo_transition_control *ptr = 1654 struct tomoyo_transition_control *ptr =
1324 container_of(acl, typeof(*ptr), head); 1655 container_of(acl, typeof(*ptr), head);
1325 tomoyo_set_string(head, 1656 tomoyo_print_namespace(head);
1326 tomoyo_transition_type 1657 tomoyo_set_string(head, tomoyo_transition_type
1327 [ptr->type]); 1658 [ptr->type]);
1328 if (ptr->program) 1659 tomoyo_set_string(head, ptr->program ?
1329 tomoyo_set_string(head, 1660 ptr->program->name : "any");
1330 ptr->program->name); 1661 tomoyo_set_string(head, " from ");
1331 if (ptr->program && ptr->domainname) 1662 tomoyo_set_string(head, ptr->domainname ?
1332 tomoyo_set_string(head, " from "); 1663 ptr->domainname->name :
1333 if (ptr->domainname) 1664 "any");
1334 tomoyo_set_string(head,
1335 ptr->domainname->
1336 name);
1337 }
1338 break;
1339 case TOMOYO_ID_GLOBALLY_READABLE:
1340 {
1341 struct tomoyo_readable_file *ptr =
1342 container_of(acl, typeof(*ptr), head);
1343 tomoyo_set_string(head,
1344 TOMOYO_KEYWORD_ALLOW_READ);
1345 tomoyo_set_string(head, ptr->filename->name);
1346 } 1665 }
1347 break; 1666 break;
1348 case TOMOYO_ID_AGGREGATOR: 1667 case TOMOYO_ID_AGGREGATOR:
1349 { 1668 {
1350 struct tomoyo_aggregator *ptr = 1669 struct tomoyo_aggregator *ptr =
1351 container_of(acl, typeof(*ptr), head); 1670 container_of(acl, typeof(*ptr), head);
1352 tomoyo_set_string(head, 1671 tomoyo_print_namespace(head);
1353 TOMOYO_KEYWORD_AGGREGATOR); 1672 tomoyo_set_string(head, "aggregator ");
1354 tomoyo_set_string(head, 1673 tomoyo_set_string(head,
1355 ptr->original_name->name); 1674 ptr->original_name->name);
1356 tomoyo_set_space(head); 1675 tomoyo_set_space(head);
@@ -1358,24 +1677,6 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1358 ptr->aggregated_name->name); 1677 ptr->aggregated_name->name);
1359 } 1678 }
1360 break; 1679 break;
1361 case TOMOYO_ID_PATTERN:
1362 {
1363 struct tomoyo_no_pattern *ptr =
1364 container_of(acl, typeof(*ptr), head);
1365 tomoyo_set_string(head,
1366 TOMOYO_KEYWORD_FILE_PATTERN);
1367 tomoyo_set_string(head, ptr->pattern->name);
1368 }
1369 break;
1370 case TOMOYO_ID_NO_REWRITE:
1371 {
1372 struct tomoyo_no_rewrite *ptr =
1373 container_of(acl, typeof(*ptr), head);
1374 tomoyo_set_string(head,
1375 TOMOYO_KEYWORD_DENY_REWRITE);
1376 tomoyo_set_string(head, ptr->pattern->name);
1377 }
1378 break;
1379 default: 1680 default:
1380 continue; 1681 continue;
1381 } 1682 }
@@ -1394,6 +1695,8 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1394 */ 1695 */
1395static void tomoyo_read_exception(struct tomoyo_io_buffer *head) 1696static void tomoyo_read_exception(struct tomoyo_io_buffer *head)
1396{ 1697{
1698 struct tomoyo_policy_namespace *ns =
1699 container_of(head->r.ns, typeof(*ns), namespace_list);
1397 if (head->r.eof) 1700 if (head->r.eof)
1398 return; 1701 return;
1399 while (head->r.step < TOMOYO_MAX_POLICY && 1702 while (head->r.step < TOMOYO_MAX_POLICY &&
@@ -1406,95 +1709,40 @@ static void tomoyo_read_exception(struct tomoyo_io_buffer *head)
1406 head->r.step++; 1709 head->r.step++;
1407 if (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP) 1710 if (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP)
1408 return; 1711 return;
1712 while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP
1713 + TOMOYO_MAX_ACL_GROUPS) {
1714 head->r.acl_group_index = head->r.step - TOMOYO_MAX_POLICY
1715 - TOMOYO_MAX_GROUP;
1716 if (!tomoyo_read_domain2(head, &ns->acl_group
1717 [head->r.acl_group_index]))
1718 return;
1719 head->r.step++;
1720 }
1409 head->r.eof = true; 1721 head->r.eof = true;
1410} 1722}
1411 1723
1412/** 1724/* Wait queue for kernel -> userspace notification. */
1413 * tomoyo_print_header - Get header line of audit log.
1414 *
1415 * @r: Pointer to "struct tomoyo_request_info".
1416 *
1417 * Returns string representation.
1418 *
1419 * This function uses kmalloc(), so caller must kfree() if this function
1420 * didn't return NULL.
1421 */
1422static char *tomoyo_print_header(struct tomoyo_request_info *r)
1423{
1424 struct timeval tv;
1425 const pid_t gpid = task_pid_nr(current);
1426 static const int tomoyo_buffer_len = 4096;
1427 char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
1428 pid_t ppid;
1429 if (!buffer)
1430 return NULL;
1431 do_gettimeofday(&tv);
1432 rcu_read_lock();
1433 ppid = task_tgid_vnr(current->real_parent);
1434 rcu_read_unlock();
1435 snprintf(buffer, tomoyo_buffer_len - 1,
1436 "#timestamp=%lu profile=%u mode=%s (global-pid=%u)"
1437 " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u"
1438 " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }",
1439 tv.tv_sec, r->profile, tomoyo_mode[r->mode], gpid,
1440 task_tgid_vnr(current), ppid,
1441 current_uid(), current_gid(), current_euid(),
1442 current_egid(), current_suid(), current_sgid(),
1443 current_fsuid(), current_fsgid());
1444 return buffer;
1445}
1446
1447/**
1448 * tomoyo_init_audit_log - Allocate buffer for audit logs.
1449 *
1450 * @len: Required size.
1451 * @r: Pointer to "struct tomoyo_request_info".
1452 *
1453 * Returns pointer to allocated memory.
1454 *
1455 * The @len is updated to add the header lines' size on success.
1456 *
1457 * This function uses kzalloc(), so caller must kfree() if this function
1458 * didn't return NULL.
1459 */
1460static char *tomoyo_init_audit_log(int *len, struct tomoyo_request_info *r)
1461{
1462 char *buf = NULL;
1463 const char *header;
1464 const char *domainname;
1465 if (!r->domain)
1466 r->domain = tomoyo_domain();
1467 domainname = r->domain->domainname->name;
1468 header = tomoyo_print_header(r);
1469 if (!header)
1470 return NULL;
1471 *len += strlen(domainname) + strlen(header) + 10;
1472 buf = kzalloc(*len, GFP_NOFS);
1473 if (buf)
1474 snprintf(buf, (*len) - 1, "%s\n%s\n", header, domainname);
1475 kfree(header);
1476 return buf;
1477}
1478
1479/* Wait queue for tomoyo_query_list. */
1480static DECLARE_WAIT_QUEUE_HEAD(tomoyo_query_wait); 1725static DECLARE_WAIT_QUEUE_HEAD(tomoyo_query_wait);
1481 1726/* Wait queue for userspace -> kernel notification. */
1482/* Lock for manipulating tomoyo_query_list. */ 1727static DECLARE_WAIT_QUEUE_HEAD(tomoyo_answer_wait);
1483static DEFINE_SPINLOCK(tomoyo_query_list_lock);
1484 1728
1485/* Structure for query. */ 1729/* Structure for query. */
1486struct tomoyo_query { 1730struct tomoyo_query {
1487 struct list_head list; 1731 struct list_head list;
1488 char *query; 1732 char *query;
1489 int query_len; 1733 size_t query_len;
1490 unsigned int serial; 1734 unsigned int serial;
1491 int timer; 1735 u8 timer;
1492 int answer; 1736 u8 answer;
1737 u8 retry;
1493}; 1738};
1494 1739
1495/* The list for "struct tomoyo_query". */ 1740/* The list for "struct tomoyo_query". */
1496static LIST_HEAD(tomoyo_query_list); 1741static LIST_HEAD(tomoyo_query_list);
1497 1742
1743/* Lock for manipulating tomoyo_query_list. */
1744static DEFINE_SPINLOCK(tomoyo_query_list_lock);
1745
1498/* 1746/*
1499 * Number of "struct file" referring /sys/kernel/security/tomoyo/query 1747 * Number of "struct file" referring /sys/kernel/security/tomoyo/query
1500 * interface. 1748 * interface.
@@ -1502,10 +1750,82 @@ static LIST_HEAD(tomoyo_query_list);
1502static atomic_t tomoyo_query_observers = ATOMIC_INIT(0); 1750static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
1503 1751
1504/** 1752/**
1753 * tomoyo_truncate - Truncate a line.
1754 *
1755 * @str: String to truncate.
1756 *
1757 * Returns length of truncated @str.
1758 */
1759static int tomoyo_truncate(char *str)
1760{
1761 char *start = str;
1762 while (*(unsigned char *) str > (unsigned char) ' ')
1763 str++;
1764 *str = '\0';
1765 return strlen(start) + 1;
1766}
1767
1768/**
1769 * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
1770 *
1771 * @domain: Pointer to "struct tomoyo_domain_info".
1772 * @header: Lines containing ACL.
1773 *
1774 * Returns nothing.
1775 */
1776static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
1777{
1778 char *buffer;
1779 char *realpath = NULL;
1780 char *argv0 = NULL;
1781 char *symlink = NULL;
1782 char *cp = strchr(header, '\n');
1783 int len;
1784 if (!cp)
1785 return;
1786 cp = strchr(cp + 1, '\n');
1787 if (!cp)
1788 return;
1789 *cp++ = '\0';
1790 len = strlen(cp) + 1;
1791 /* strstr() will return NULL if ordering is wrong. */
1792 if (*cp == 'f') {
1793 argv0 = strstr(header, " argv[]={ \"");
1794 if (argv0) {
1795 argv0 += 10;
1796 len += tomoyo_truncate(argv0) + 14;
1797 }
1798 realpath = strstr(header, " exec={ realpath=\"");
1799 if (realpath) {
1800 realpath += 8;
1801 len += tomoyo_truncate(realpath) + 6;
1802 }
1803 symlink = strstr(header, " symlink.target=\"");
1804 if (symlink)
1805 len += tomoyo_truncate(symlink + 1) + 1;
1806 }
1807 buffer = kmalloc(len, GFP_NOFS);
1808 if (!buffer)
1809 return;
1810 snprintf(buffer, len - 1, "%s", cp);
1811 if (realpath)
1812 tomoyo_addprintf(buffer, len, " exec.%s", realpath);
1813 if (argv0)
1814 tomoyo_addprintf(buffer, len, " exec.argv[0]=%s", argv0);
1815 if (symlink)
1816 tomoyo_addprintf(buffer, len, "%s", symlink);
1817 tomoyo_normalize_line(buffer);
1818 if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
1819 false))
1820 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
1821 kfree(buffer);
1822}
1823
1824/**
1505 * tomoyo_supervisor - Ask for the supervisor's decision. 1825 * tomoyo_supervisor - Ask for the supervisor's decision.
1506 * 1826 *
1507 * @r: Pointer to "struct tomoyo_request_info". 1827 * @r: Pointer to "struct tomoyo_request_info".
1508 * @fmt: The printf()'s format string, followed by parameters. 1828 * @fmt: The printf()'s format string, followed by parameters.
1509 * 1829 *
1510 * Returns 0 if the supervisor decided to permit the access request which 1830 * Returns 0 if the supervisor decided to permit the access request which
1511 * violated the policy in enforcing mode, TOMOYO_RETRY_REQUEST if the 1831 * violated the policy in enforcing mode, TOMOYO_RETRY_REQUEST if the
@@ -1515,88 +1835,79 @@ static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
1515int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...) 1835int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
1516{ 1836{
1517 va_list args; 1837 va_list args;
1518 int error = -EPERM; 1838 int error;
1519 int pos;
1520 int len; 1839 int len;
1521 static unsigned int tomoyo_serial; 1840 static unsigned int tomoyo_serial;
1522 struct tomoyo_query *entry = NULL; 1841 struct tomoyo_query entry = { };
1523 bool quota_exceeded = false; 1842 bool quota_exceeded = false;
1524 char *header; 1843 va_start(args, fmt);
1844 len = vsnprintf((char *) &len, 1, fmt, args) + 1;
1845 va_end(args);
1846 /* Write /sys/kernel/security/tomoyo/audit. */
1847 va_start(args, fmt);
1848 tomoyo_write_log2(r, len, fmt, args);
1849 va_end(args);
1850 /* Nothing more to do if granted. */
1851 if (r->granted)
1852 return 0;
1853 if (r->mode)
1854 tomoyo_update_stat(r->mode);
1525 switch (r->mode) { 1855 switch (r->mode) {
1526 char *buffer; 1856 case TOMOYO_CONFIG_ENFORCING:
1857 error = -EPERM;
1858 if (atomic_read(&tomoyo_query_observers))
1859 break;
1860 goto out;
1527 case TOMOYO_CONFIG_LEARNING: 1861 case TOMOYO_CONFIG_LEARNING:
1528 if (!tomoyo_domain_quota_is_ok(r)) 1862 error = 0;
1529 return 0; 1863 /* Check max_learning_entry parameter. */
1530 va_start(args, fmt); 1864 if (tomoyo_domain_quota_is_ok(r))
1531 len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 4; 1865 break;
1532 va_end(args);
1533 buffer = kmalloc(len, GFP_NOFS);
1534 if (!buffer)
1535 return 0;
1536 va_start(args, fmt);
1537 vsnprintf(buffer, len - 1, fmt, args);
1538 va_end(args);
1539 tomoyo_normalize_line(buffer);
1540 tomoyo_write_domain2(buffer, r->domain, false);
1541 kfree(buffer);
1542 /* fall through */ 1866 /* fall through */
1543 case TOMOYO_CONFIG_PERMISSIVE: 1867 default:
1544 return 0; 1868 return 0;
1545 } 1869 }
1546 if (!r->domain) 1870 /* Get message. */
1547 r->domain = tomoyo_domain();
1548 if (!atomic_read(&tomoyo_query_observers))
1549 return -EPERM;
1550 va_start(args, fmt); 1871 va_start(args, fmt);
1551 len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32; 1872 entry.query = tomoyo_init_log(r, len, fmt, args);
1552 va_end(args); 1873 va_end(args);
1553 header = tomoyo_init_audit_log(&len, r); 1874 if (!entry.query)
1554 if (!header)
1555 goto out; 1875 goto out;
1556 entry = kzalloc(sizeof(*entry), GFP_NOFS); 1876 entry.query_len = strlen(entry.query) + 1;
1557 if (!entry) 1877 if (!error) {
1878 tomoyo_add_entry(r->domain, entry.query);
1558 goto out; 1879 goto out;
1559 entry->query = kzalloc(len, GFP_NOFS); 1880 }
1560 if (!entry->query) 1881 len = tomoyo_round2(entry.query_len);
1561 goto out;
1562 len = ksize(entry->query);
1563 spin_lock(&tomoyo_query_list_lock); 1882 spin_lock(&tomoyo_query_list_lock);
1564 if (tomoyo_quota_for_query && tomoyo_query_memory_size + len + 1883 if (tomoyo_memory_quota[TOMOYO_MEMORY_QUERY] &&
1565 sizeof(*entry) >= tomoyo_quota_for_query) { 1884 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] + len
1885 >= tomoyo_memory_quota[TOMOYO_MEMORY_QUERY]) {
1566 quota_exceeded = true; 1886 quota_exceeded = true;
1567 } else { 1887 } else {
1568 tomoyo_query_memory_size += len + sizeof(*entry); 1888 entry.serial = tomoyo_serial++;
1569 entry->serial = tomoyo_serial++; 1889 entry.retry = r->retry;
1890 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] += len;
1891 list_add_tail(&entry.list, &tomoyo_query_list);
1570 } 1892 }
1571 spin_unlock(&tomoyo_query_list_lock); 1893 spin_unlock(&tomoyo_query_list_lock);
1572 if (quota_exceeded) 1894 if (quota_exceeded)
1573 goto out; 1895 goto out;
1574 pos = snprintf(entry->query, len - 1, "Q%u-%hu\n%s",
1575 entry->serial, r->retry, header);
1576 kfree(header);
1577 header = NULL;
1578 va_start(args, fmt);
1579 vsnprintf(entry->query + pos, len - 1 - pos, fmt, args);
1580 entry->query_len = strlen(entry->query) + 1;
1581 va_end(args);
1582 spin_lock(&tomoyo_query_list_lock);
1583 list_add_tail(&entry->list, &tomoyo_query_list);
1584 spin_unlock(&tomoyo_query_list_lock);
1585 /* Give 10 seconds for supervisor's opinion. */ 1896 /* Give 10 seconds for supervisor's opinion. */
1586 for (entry->timer = 0; 1897 while (entry.timer < 10) {
1587 atomic_read(&tomoyo_query_observers) && entry->timer < 100; 1898 wake_up_all(&tomoyo_query_wait);
1588 entry->timer++) { 1899 if (wait_event_interruptible_timeout
1589 wake_up(&tomoyo_query_wait); 1900 (tomoyo_answer_wait, entry.answer ||
1590 set_current_state(TASK_INTERRUPTIBLE); 1901 !atomic_read(&tomoyo_query_observers), HZ))
1591 schedule_timeout(HZ / 10);
1592 if (entry->answer)
1593 break; 1902 break;
1903 else
1904 entry.timer++;
1594 } 1905 }
1595 spin_lock(&tomoyo_query_list_lock); 1906 spin_lock(&tomoyo_query_list_lock);
1596 list_del(&entry->list); 1907 list_del(&entry.list);
1597 tomoyo_query_memory_size -= len + sizeof(*entry); 1908 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] -= len;
1598 spin_unlock(&tomoyo_query_list_lock); 1909 spin_unlock(&tomoyo_query_list_lock);
1599 switch (entry->answer) { 1910 switch (entry.answer) {
1600 case 3: /* Asked to retry by administrator. */ 1911 case 3: /* Asked to retry by administrator. */
1601 error = TOMOYO_RETRY_REQUEST; 1912 error = TOMOYO_RETRY_REQUEST;
1602 r->retry++; 1913 r->retry++;
@@ -1605,18 +1916,12 @@ int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
1605 /* Granted by administrator. */ 1916 /* Granted by administrator. */
1606 error = 0; 1917 error = 0;
1607 break; 1918 break;
1608 case 0:
1609 /* Timed out. */
1610 break;
1611 default: 1919 default:
1612 /* Rejected by administrator. */ 1920 /* Timed out or rejected by administrator. */
1613 break; 1921 break;
1614 } 1922 }
1615 out: 1923out:
1616 if (entry) 1924 kfree(entry.query);
1617 kfree(entry->query);
1618 kfree(entry);
1619 kfree(header);
1620 return error; 1925 return error;
1621} 1926}
1622 1927
@@ -1663,8 +1968,8 @@ static int tomoyo_poll_query(struct file *file, poll_table *wait)
1663static void tomoyo_read_query(struct tomoyo_io_buffer *head) 1968static void tomoyo_read_query(struct tomoyo_io_buffer *head)
1664{ 1969{
1665 struct list_head *tmp; 1970 struct list_head *tmp;
1666 int pos = 0; 1971 unsigned int pos = 0;
1667 int len = 0; 1972 size_t len = 0;
1668 char *buf; 1973 char *buf;
1669 if (head->r.w_pos) 1974 if (head->r.w_pos)
1670 return; 1975 return;
@@ -1687,7 +1992,7 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head)
1687 head->r.query_index = 0; 1992 head->r.query_index = 0;
1688 return; 1993 return;
1689 } 1994 }
1690 buf = kzalloc(len, GFP_NOFS); 1995 buf = kzalloc(len + 32, GFP_NOFS);
1691 if (!buf) 1996 if (!buf)
1692 return; 1997 return;
1693 pos = 0; 1998 pos = 0;
@@ -1703,7 +2008,8 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head)
1703 * can change, but I don't care. 2008 * can change, but I don't care.
1704 */ 2009 */
1705 if (len == ptr->query_len) 2010 if (len == ptr->query_len)
1706 memmove(buf, ptr->query, len); 2011 snprintf(buf, len + 31, "Q%u-%hu\n%s", ptr->serial,
2012 ptr->retry, ptr->query);
1707 break; 2013 break;
1708 } 2014 }
1709 spin_unlock(&tomoyo_query_list_lock); 2015 spin_unlock(&tomoyo_query_list_lock);
@@ -1760,7 +2066,7 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
1760static void tomoyo_read_version(struct tomoyo_io_buffer *head) 2066static void tomoyo_read_version(struct tomoyo_io_buffer *head)
1761{ 2067{
1762 if (!head->r.eof) { 2068 if (!head->r.eof) {
1763 tomoyo_io_printf(head, "2.3.0"); 2069 tomoyo_io_printf(head, "2.4.0");
1764 head->r.eof = true; 2070 head->r.eof = true;
1765 } 2071 }
1766} 2072}
@@ -1785,15 +2091,111 @@ static void tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
1785 } 2091 }
1786} 2092}
1787 2093
2094/* String table for /sys/kernel/security/tomoyo/stat interface. */
2095static const char * const tomoyo_policy_headers[TOMOYO_MAX_POLICY_STAT] = {
2096 [TOMOYO_STAT_POLICY_UPDATES] = "update:",
2097 [TOMOYO_STAT_POLICY_LEARNING] = "violation in learning mode:",
2098 [TOMOYO_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:",
2099 [TOMOYO_STAT_POLICY_ENFORCING] = "violation in enforcing mode:",
2100};
2101
2102/* String table for /sys/kernel/security/tomoyo/stat interface. */
2103static const char * const tomoyo_memory_headers[TOMOYO_MAX_MEMORY_STAT] = {
2104 [TOMOYO_MEMORY_POLICY] = "policy:",
2105 [TOMOYO_MEMORY_AUDIT] = "audit log:",
2106 [TOMOYO_MEMORY_QUERY] = "query message:",
2107};
2108
2109/* Timestamp counter for last updated. */
2110static unsigned int tomoyo_stat_updated[TOMOYO_MAX_POLICY_STAT];
2111/* Counter for number of updates. */
2112static unsigned int tomoyo_stat_modified[TOMOYO_MAX_POLICY_STAT];
2113
2114/**
2115 * tomoyo_update_stat - Update statistic counters.
2116 *
2117 * @index: Index for policy type.
2118 *
2119 * Returns nothing.
2120 */
2121void tomoyo_update_stat(const u8 index)
2122{
2123 struct timeval tv;
2124 do_gettimeofday(&tv);
2125 /*
2126 * I don't use atomic operations because race condition is not fatal.
2127 */
2128 tomoyo_stat_updated[index]++;
2129 tomoyo_stat_modified[index] = tv.tv_sec;
2130}
2131
2132/**
2133 * tomoyo_read_stat - Read statistic data.
2134 *
2135 * @head: Pointer to "struct tomoyo_io_buffer".
2136 *
2137 * Returns nothing.
2138 */
2139static void tomoyo_read_stat(struct tomoyo_io_buffer *head)
2140{
2141 u8 i;
2142 unsigned int total = 0;
2143 if (head->r.eof)
2144 return;
2145 for (i = 0; i < TOMOYO_MAX_POLICY_STAT; i++) {
2146 tomoyo_io_printf(head, "Policy %-30s %10u",
2147 tomoyo_policy_headers[i],
2148 tomoyo_stat_updated[i]);
2149 if (tomoyo_stat_modified[i]) {
2150 struct tomoyo_time stamp;
2151 tomoyo_convert_time(tomoyo_stat_modified[i], &stamp);
2152 tomoyo_io_printf(head, " (Last: %04u/%02u/%02u "
2153 "%02u:%02u:%02u)",
2154 stamp.year, stamp.month, stamp.day,
2155 stamp.hour, stamp.min, stamp.sec);
2156 }
2157 tomoyo_set_lf(head);
2158 }
2159 for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) {
2160 unsigned int used = tomoyo_memory_used[i];
2161 total += used;
2162 tomoyo_io_printf(head, "Memory used by %-22s %10u",
2163 tomoyo_memory_headers[i], used);
2164 used = tomoyo_memory_quota[i];
2165 if (used)
2166 tomoyo_io_printf(head, " (Quota: %10u)", used);
2167 tomoyo_set_lf(head);
2168 }
2169 tomoyo_io_printf(head, "Total memory used: %10u\n",
2170 total);
2171 head->r.eof = true;
2172}
2173
2174/**
2175 * tomoyo_write_stat - Set memory quota.
2176 *
2177 * @head: Pointer to "struct tomoyo_io_buffer".
2178 *
2179 * Returns 0.
2180 */
2181static int tomoyo_write_stat(struct tomoyo_io_buffer *head)
2182{
2183 char *data = head->write_buf;
2184 u8 i;
2185 if (tomoyo_str_starts(&data, "Memory used by "))
2186 for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++)
2187 if (tomoyo_str_starts(&data, tomoyo_memory_headers[i]))
2188 sscanf(data, "%u", &tomoyo_memory_quota[i]);
2189 return 0;
2190}
2191
1788/** 2192/**
1789 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface. 2193 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface.
1790 * 2194 *
1791 * @type: Type of interface. 2195 * @type: Type of interface.
1792 * @file: Pointer to "struct file". 2196 * @file: Pointer to "struct file".
1793 * 2197 *
1794 * Associates policy handler and returns 0 on success, -ENOMEM otherwise. 2198 * Returns 0 on success, negative value otherwise.
1795 *
1796 * Caller acquires tomoyo_read_lock().
1797 */ 2199 */
1798int tomoyo_open_control(const u8 type, struct file *file) 2200int tomoyo_open_control(const u8 type, struct file *file)
1799{ 2201{
@@ -1814,15 +2216,15 @@ int tomoyo_open_control(const u8 type, struct file *file)
1814 head->write = tomoyo_write_exception; 2216 head->write = tomoyo_write_exception;
1815 head->read = tomoyo_read_exception; 2217 head->read = tomoyo_read_exception;
1816 break; 2218 break;
2219 case TOMOYO_AUDIT:
2220 /* /sys/kernel/security/tomoyo/audit */
2221 head->poll = tomoyo_poll_log;
2222 head->read = tomoyo_read_log;
2223 break;
1817 case TOMOYO_SELFDOMAIN: 2224 case TOMOYO_SELFDOMAIN:
1818 /* /sys/kernel/security/tomoyo/self_domain */ 2225 /* /sys/kernel/security/tomoyo/self_domain */
1819 head->read = tomoyo_read_self_domain; 2226 head->read = tomoyo_read_self_domain;
1820 break; 2227 break;
1821 case TOMOYO_DOMAIN_STATUS:
1822 /* /sys/kernel/security/tomoyo/.domain_status */
1823 head->write = tomoyo_write_domain_profile;
1824 head->read = tomoyo_read_domain_profile;
1825 break;
1826 case TOMOYO_PROCESS_STATUS: 2228 case TOMOYO_PROCESS_STATUS:
1827 /* /sys/kernel/security/tomoyo/.process_status */ 2229 /* /sys/kernel/security/tomoyo/.process_status */
1828 head->write = tomoyo_write_pid; 2230 head->write = tomoyo_write_pid;
@@ -1833,11 +2235,11 @@ int tomoyo_open_control(const u8 type, struct file *file)
1833 head->read = tomoyo_read_version; 2235 head->read = tomoyo_read_version;
1834 head->readbuf_size = 128; 2236 head->readbuf_size = 128;
1835 break; 2237 break;
1836 case TOMOYO_MEMINFO: 2238 case TOMOYO_STAT:
1837 /* /sys/kernel/security/tomoyo/meminfo */ 2239 /* /sys/kernel/security/tomoyo/stat */
1838 head->write = tomoyo_write_memory_quota; 2240 head->write = tomoyo_write_stat;
1839 head->read = tomoyo_read_memory_counter; 2241 head->read = tomoyo_read_stat;
1840 head->readbuf_size = 512; 2242 head->readbuf_size = 1024;
1841 break; 2243 break;
1842 case TOMOYO_PROFILE: 2244 case TOMOYO_PROFILE:
1843 /* /sys/kernel/security/tomoyo/profile */ 2245 /* /sys/kernel/security/tomoyo/profile */
@@ -1887,26 +2289,16 @@ int tomoyo_open_control(const u8 type, struct file *file)
1887 return -ENOMEM; 2289 return -ENOMEM;
1888 } 2290 }
1889 } 2291 }
1890 if (type != TOMOYO_QUERY)
1891 head->reader_idx = tomoyo_read_lock();
1892 file->private_data = head;
1893 /*
1894 * Call the handler now if the file is
1895 * /sys/kernel/security/tomoyo/self_domain
1896 * so that the user can use
1897 * cat < /sys/kernel/security/tomoyo/self_domain"
1898 * to know the current process's domainname.
1899 */
1900 if (type == TOMOYO_SELFDOMAIN)
1901 tomoyo_read_control(file, NULL, 0);
1902 /* 2292 /*
1903 * If the file is /sys/kernel/security/tomoyo/query , increment the 2293 * If the file is /sys/kernel/security/tomoyo/query , increment the
1904 * observer counter. 2294 * observer counter.
1905 * The obserber counter is used by tomoyo_supervisor() to see if 2295 * The obserber counter is used by tomoyo_supervisor() to see if
1906 * there is some process monitoring /sys/kernel/security/tomoyo/query. 2296 * there is some process monitoring /sys/kernel/security/tomoyo/query.
1907 */ 2297 */
1908 else if (type == TOMOYO_QUERY) 2298 if (type == TOMOYO_QUERY)
1909 atomic_inc(&tomoyo_query_observers); 2299 atomic_inc(&tomoyo_query_observers);
2300 file->private_data = head;
2301 tomoyo_notify_gc(head, true);
1910 return 0; 2302 return 0;
1911} 2303}
1912 2304
@@ -1917,7 +2309,8 @@ int tomoyo_open_control(const u8 type, struct file *file)
1917 * @wait: Pointer to "poll_table". 2309 * @wait: Pointer to "poll_table".
1918 * 2310 *
1919 * Waits for read readiness. 2311 * Waits for read readiness.
1920 * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd . 2312 * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd and
2313 * /sys/kernel/security/tomoyo/audit is handled by /usr/sbin/tomoyo-auditd.
1921 */ 2314 */
1922int tomoyo_poll_control(struct file *file, poll_table *wait) 2315int tomoyo_poll_control(struct file *file, poll_table *wait)
1923{ 2316{
@@ -1928,21 +2321,58 @@ int tomoyo_poll_control(struct file *file, poll_table *wait)
1928} 2321}
1929 2322
1930/** 2323/**
2324 * tomoyo_set_namespace_cursor - Set namespace to read.
2325 *
2326 * @head: Pointer to "struct tomoyo_io_buffer".
2327 *
2328 * Returns nothing.
2329 */
2330static inline void tomoyo_set_namespace_cursor(struct tomoyo_io_buffer *head)
2331{
2332 struct list_head *ns;
2333 if (head->type != TOMOYO_EXCEPTIONPOLICY &&
2334 head->type != TOMOYO_PROFILE)
2335 return;
2336 /*
2337 * If this is the first read, or reading previous namespace finished
2338 * and has more namespaces to read, update the namespace cursor.
2339 */
2340 ns = head->r.ns;
2341 if (!ns || (head->r.eof && ns->next != &tomoyo_namespace_list)) {
2342 /* Clearing is OK because tomoyo_flush() returned true. */
2343 memset(&head->r, 0, sizeof(head->r));
2344 head->r.ns = ns ? ns->next : tomoyo_namespace_list.next;
2345 }
2346}
2347
2348/**
2349 * tomoyo_has_more_namespace - Check for unread namespaces.
2350 *
2351 * @head: Pointer to "struct tomoyo_io_buffer".
2352 *
2353 * Returns true if we have more entries to print, false otherwise.
2354 */
2355static inline bool tomoyo_has_more_namespace(struct tomoyo_io_buffer *head)
2356{
2357 return (head->type == TOMOYO_EXCEPTIONPOLICY ||
2358 head->type == TOMOYO_PROFILE) && head->r.eof &&
2359 head->r.ns->next != &tomoyo_namespace_list;
2360}
2361
2362/**
1931 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface. 2363 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
1932 * 2364 *
1933 * @file: Pointer to "struct file". 2365 * @head: Pointer to "struct tomoyo_io_buffer".
1934 * @buffer: Poiner to buffer to write to. 2366 * @buffer: Poiner to buffer to write to.
1935 * @buffer_len: Size of @buffer. 2367 * @buffer_len: Size of @buffer.
1936 * 2368 *
1937 * Returns bytes read on success, negative value otherwise. 2369 * Returns bytes read on success, negative value otherwise.
1938 *
1939 * Caller holds tomoyo_read_lock().
1940 */ 2370 */
1941int tomoyo_read_control(struct file *file, char __user *buffer, 2371ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
1942 const int buffer_len) 2372 const int buffer_len)
1943{ 2373{
1944 int len; 2374 int len;
1945 struct tomoyo_io_buffer *head = file->private_data; 2375 int idx;
1946 2376
1947 if (!head->read) 2377 if (!head->read)
1948 return -ENOSYS; 2378 return -ENOSYS;
@@ -1950,64 +2380,156 @@ int tomoyo_read_control(struct file *file, char __user *buffer,
1950 return -EINTR; 2380 return -EINTR;
1951 head->read_user_buf = buffer; 2381 head->read_user_buf = buffer;
1952 head->read_user_buf_avail = buffer_len; 2382 head->read_user_buf_avail = buffer_len;
2383 idx = tomoyo_read_lock();
1953 if (tomoyo_flush(head)) 2384 if (tomoyo_flush(head))
1954 /* Call the policy handler. */ 2385 /* Call the policy handler. */
1955 head->read(head); 2386 do {
1956 tomoyo_flush(head); 2387 tomoyo_set_namespace_cursor(head);
2388 head->read(head);
2389 } while (tomoyo_flush(head) &&
2390 tomoyo_has_more_namespace(head));
2391 tomoyo_read_unlock(idx);
1957 len = head->read_user_buf - buffer; 2392 len = head->read_user_buf - buffer;
1958 mutex_unlock(&head->io_sem); 2393 mutex_unlock(&head->io_sem);
1959 return len; 2394 return len;
1960} 2395}
1961 2396
1962/** 2397/**
2398 * tomoyo_parse_policy - Parse a policy line.
2399 *
2400 * @head: Poiter to "struct tomoyo_io_buffer".
2401 * @line: Line to parse.
2402 *
2403 * Returns 0 on success, negative value otherwise.
2404 *
2405 * Caller holds tomoyo_read_lock().
2406 */
2407static int tomoyo_parse_policy(struct tomoyo_io_buffer *head, char *line)
2408{
2409 /* Delete request? */
2410 head->w.is_delete = !strncmp(line, "delete ", 7);
2411 if (head->w.is_delete)
2412 memmove(line, line + 7, strlen(line + 7) + 1);
2413 /* Selecting namespace to update. */
2414 if (head->type == TOMOYO_EXCEPTIONPOLICY ||
2415 head->type == TOMOYO_PROFILE) {
2416 if (*line == '<') {
2417 char *cp = strchr(line, ' ');
2418 if (cp) {
2419 *cp++ = '\0';
2420 head->w.ns = tomoyo_assign_namespace(line);
2421 memmove(line, cp, strlen(cp) + 1);
2422 } else
2423 head->w.ns = NULL;
2424 } else
2425 head->w.ns = &tomoyo_kernel_namespace;
2426 /* Don't allow updating if namespace is invalid. */
2427 if (!head->w.ns)
2428 return -ENOENT;
2429 }
2430 /* Do the update. */
2431 return head->write(head);
2432}
2433
2434/**
1963 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface. 2435 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface.
1964 * 2436 *
1965 * @file: Pointer to "struct file". 2437 * @head: Pointer to "struct tomoyo_io_buffer".
1966 * @buffer: Pointer to buffer to read from. 2438 * @buffer: Pointer to buffer to read from.
1967 * @buffer_len: Size of @buffer. 2439 * @buffer_len: Size of @buffer.
1968 * 2440 *
1969 * Returns @buffer_len on success, negative value otherwise. 2441 * Returns @buffer_len on success, negative value otherwise.
1970 *
1971 * Caller holds tomoyo_read_lock().
1972 */ 2442 */
1973int tomoyo_write_control(struct file *file, const char __user *buffer, 2443ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
1974 const int buffer_len) 2444 const char __user *buffer, const int buffer_len)
1975{ 2445{
1976 struct tomoyo_io_buffer *head = file->private_data;
1977 int error = buffer_len; 2446 int error = buffer_len;
1978 int avail_len = buffer_len; 2447 size_t avail_len = buffer_len;
1979 char *cp0 = head->write_buf; 2448 char *cp0 = head->write_buf;
1980 2449 int idx;
1981 if (!head->write) 2450 if (!head->write)
1982 return -ENOSYS; 2451 return -ENOSYS;
1983 if (!access_ok(VERIFY_READ, buffer, buffer_len)) 2452 if (!access_ok(VERIFY_READ, buffer, buffer_len))
1984 return -EFAULT; 2453 return -EFAULT;
1985 /* Don't allow updating policies by non manager programs. */
1986 if (head->write != tomoyo_write_pid &&
1987 head->write != tomoyo_write_domain && !tomoyo_manager())
1988 return -EPERM;
1989 if (mutex_lock_interruptible(&head->io_sem)) 2454 if (mutex_lock_interruptible(&head->io_sem))
1990 return -EINTR; 2455 return -EINTR;
2456 idx = tomoyo_read_lock();
1991 /* Read a line and dispatch it to the policy handler. */ 2457 /* Read a line and dispatch it to the policy handler. */
1992 while (avail_len > 0) { 2458 while (avail_len > 0) {
1993 char c; 2459 char c;
1994 if (head->write_avail >= head->writebuf_size - 1) { 2460 if (head->w.avail >= head->writebuf_size - 1) {
1995 error = -ENOMEM; 2461 const int len = head->writebuf_size * 2;
1996 break; 2462 char *cp = kzalloc(len, GFP_NOFS);
1997 } else if (get_user(c, buffer)) { 2463 if (!cp) {
2464 error = -ENOMEM;
2465 break;
2466 }
2467 memmove(cp, cp0, head->w.avail);
2468 kfree(cp0);
2469 head->write_buf = cp;
2470 cp0 = cp;
2471 head->writebuf_size = len;
2472 }
2473 if (get_user(c, buffer)) {
1998 error = -EFAULT; 2474 error = -EFAULT;
1999 break; 2475 break;
2000 } 2476 }
2001 buffer++; 2477 buffer++;
2002 avail_len--; 2478 avail_len--;
2003 cp0[head->write_avail++] = c; 2479 cp0[head->w.avail++] = c;
2004 if (c != '\n') 2480 if (c != '\n')
2005 continue; 2481 continue;
2006 cp0[head->write_avail - 1] = '\0'; 2482 cp0[head->w.avail - 1] = '\0';
2007 head->write_avail = 0; 2483 head->w.avail = 0;
2008 tomoyo_normalize_line(cp0); 2484 tomoyo_normalize_line(cp0);
2009 head->write(head); 2485 if (!strcmp(cp0, "reset")) {
2486 head->w.ns = &tomoyo_kernel_namespace;
2487 head->w.domain = NULL;
2488 memset(&head->r, 0, sizeof(head->r));
2489 continue;
2490 }
2491 /* Don't allow updating policies by non manager programs. */
2492 switch (head->type) {
2493 case TOMOYO_PROCESS_STATUS:
2494 /* This does not write anything. */
2495 break;
2496 case TOMOYO_DOMAINPOLICY:
2497 if (tomoyo_select_domain(head, cp0))
2498 continue;
2499 /* fall through */
2500 case TOMOYO_EXCEPTIONPOLICY:
2501 if (!strcmp(cp0, "select transition_only")) {
2502 head->r.print_transition_related_only = true;
2503 continue;
2504 }
2505 /* fall through */
2506 default:
2507 if (!tomoyo_manager()) {
2508 error = -EPERM;
2509 goto out;
2510 }
2511 }
2512 switch (tomoyo_parse_policy(head, cp0)) {
2513 case -EPERM:
2514 error = -EPERM;
2515 goto out;
2516 case 0:
2517 switch (head->type) {
2518 case TOMOYO_DOMAINPOLICY:
2519 case TOMOYO_EXCEPTIONPOLICY:
2520 case TOMOYO_STAT:
2521 case TOMOYO_PROFILE:
2522 case TOMOYO_MANAGER:
2523 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
2524 break;
2525 default:
2526 break;
2527 }
2528 break;
2529 }
2010 } 2530 }
2531out:
2532 tomoyo_read_unlock(idx);
2011 mutex_unlock(&head->io_sem); 2533 mutex_unlock(&head->io_sem);
2012 return error; 2534 return error;
2013} 2535}
@@ -2015,35 +2537,20 @@ int tomoyo_write_control(struct file *file, const char __user *buffer,
2015/** 2537/**
2016 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface. 2538 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface.
2017 * 2539 *
2018 * @file: Pointer to "struct file". 2540 * @head: Pointer to "struct tomoyo_io_buffer".
2019 *
2020 * Releases memory and returns 0.
2021 * 2541 *
2022 * Caller looses tomoyo_read_lock(). 2542 * Returns 0.
2023 */ 2543 */
2024int tomoyo_close_control(struct file *file) 2544int tomoyo_close_control(struct tomoyo_io_buffer *head)
2025{ 2545{
2026 struct tomoyo_io_buffer *head = file->private_data;
2027 const bool is_write = !!head->write_buf;
2028
2029 /* 2546 /*
2030 * If the file is /sys/kernel/security/tomoyo/query , decrement the 2547 * If the file is /sys/kernel/security/tomoyo/query , decrement the
2031 * observer counter. 2548 * observer counter.
2032 */ 2549 */
2033 if (head->type == TOMOYO_QUERY) 2550 if (head->type == TOMOYO_QUERY &&
2034 atomic_dec(&tomoyo_query_observers); 2551 atomic_dec_and_test(&tomoyo_query_observers))
2035 else 2552 wake_up_all(&tomoyo_answer_wait);
2036 tomoyo_read_unlock(head->reader_idx); 2553 tomoyo_notify_gc(head, false);
2037 /* Release memory used for policy I/O. */
2038 kfree(head->read_buf);
2039 head->read_buf = NULL;
2040 kfree(head->write_buf);
2041 head->write_buf = NULL;
2042 kfree(head);
2043 head = NULL;
2044 file->private_data = NULL;
2045 if (is_write)
2046 tomoyo_run_gc();
2047 return 0; 2554 return 0;
2048} 2555}
2049 2556
@@ -2055,27 +2562,90 @@ void tomoyo_check_profile(void)
2055 struct tomoyo_domain_info *domain; 2562 struct tomoyo_domain_info *domain;
2056 const int idx = tomoyo_read_lock(); 2563 const int idx = tomoyo_read_lock();
2057 tomoyo_policy_loaded = true; 2564 tomoyo_policy_loaded = true;
2058 /* Check all profiles currently assigned to domains are defined. */ 2565 printk(KERN_INFO "TOMOYO: 2.4.0\n");
2059 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 2566 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
2060 const u8 profile = domain->profile; 2567 const u8 profile = domain->profile;
2061 if (tomoyo_profile_ptr[profile]) 2568 const struct tomoyo_policy_namespace *ns = domain->ns;
2569 if (ns->profile_version != 20100903)
2570 printk(KERN_ERR
2571 "Profile version %u is not supported.\n",
2572 ns->profile_version);
2573 else if (!ns->profile_ptr[profile])
2574 printk(KERN_ERR
2575 "Profile %u (used by '%s') is not defined.\n",
2576 profile, domain->domainname->name);
2577 else
2062 continue; 2578 continue;
2063 printk(KERN_ERR "You need to define profile %u before using it.\n", 2579 printk(KERN_ERR
2064 profile); 2580 "Userland tools for TOMOYO 2.4 must be installed and "
2065 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.3/ " 2581 "policy must be initialized.\n");
2582 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.4/ "
2066 "for more information.\n"); 2583 "for more information.\n");
2067 panic("Profile %u (used by '%s') not defined.\n", 2584 panic("STOP!");
2068 profile, domain->domainname->name);
2069 } 2585 }
2070 tomoyo_read_unlock(idx); 2586 tomoyo_read_unlock(idx);
2071 if (tomoyo_profile_version != 20090903) {
2072 printk(KERN_ERR "You need to install userland programs for "
2073 "TOMOYO 2.3 and initialize policy configuration.\n");
2074 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.3/ "
2075 "for more information.\n");
2076 panic("Profile version %u is not supported.\n",
2077 tomoyo_profile_version);
2078 }
2079 printk(KERN_INFO "TOMOYO: 2.3.0\n");
2080 printk(KERN_INFO "Mandatory Access Control activated.\n"); 2587 printk(KERN_INFO "Mandatory Access Control activated.\n");
2081} 2588}
2589
2590/**
2591 * tomoyo_load_builtin_policy - Load built-in policy.
2592 *
2593 * Returns nothing.
2594 */
2595void __init tomoyo_load_builtin_policy(void)
2596{
2597 /*
2598 * This include file is manually created and contains built-in policy
2599 * named "tomoyo_builtin_profile", "tomoyo_builtin_exception_policy",
2600 * "tomoyo_builtin_domain_policy", "tomoyo_builtin_manager",
2601 * "tomoyo_builtin_stat" in the form of "static char [] __initdata".
2602 */
2603#include "builtin-policy.h"
2604 u8 i;
2605 const int idx = tomoyo_read_lock();
2606 for (i = 0; i < 5; i++) {
2607 struct tomoyo_io_buffer head = { };
2608 char *start = "";
2609 switch (i) {
2610 case 0:
2611 start = tomoyo_builtin_profile;
2612 head.type = TOMOYO_PROFILE;
2613 head.write = tomoyo_write_profile;
2614 break;
2615 case 1:
2616 start = tomoyo_builtin_exception_policy;
2617 head.type = TOMOYO_EXCEPTIONPOLICY;
2618 head.write = tomoyo_write_exception;
2619 break;
2620 case 2:
2621 start = tomoyo_builtin_domain_policy;
2622 head.type = TOMOYO_DOMAINPOLICY;
2623 head.write = tomoyo_write_domain;
2624 break;
2625 case 3:
2626 start = tomoyo_builtin_manager;
2627 head.type = TOMOYO_MANAGER;
2628 head.write = tomoyo_write_manager;
2629 break;
2630 case 4:
2631 start = tomoyo_builtin_stat;
2632 head.type = TOMOYO_STAT;
2633 head.write = tomoyo_write_stat;
2634 break;
2635 }
2636 while (1) {
2637 char *end = strchr(start, '\n');
2638 if (!end)
2639 break;
2640 *end = '\0';
2641 tomoyo_normalize_line(start);
2642 head.write_buf = start;
2643 tomoyo_parse_policy(&head, start);
2644 start = end + 1;
2645 }
2646 }
2647 tomoyo_read_unlock(idx);
2648#ifdef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
2649 tomoyo_check_profile();
2650#endif
2651}
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 7c66bd89878..f7fbaa66e44 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -21,7 +21,8 @@
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/cred.h> 22#include <linux/cred.h>
23#include <linux/poll.h> 23#include <linux/poll.h>
24struct linux_binprm; 24#include <linux/binfmts.h>
25#include <linux/highmem.h>
25 26
26/********** Constants definitions. **********/ 27/********** Constants definitions. **********/
27 28
@@ -38,66 +39,149 @@ struct linux_binprm;
38/* Profile number is an integer between 0 and 255. */ 39/* Profile number is an integer between 0 and 255. */
39#define TOMOYO_MAX_PROFILES 256 40#define TOMOYO_MAX_PROFILES 256
40 41
42/* Group number is an integer between 0 and 255. */
43#define TOMOYO_MAX_ACL_GROUPS 256
44
45/* Index numbers for "struct tomoyo_condition". */
46enum tomoyo_conditions_index {
47 TOMOYO_TASK_UID, /* current_uid() */
48 TOMOYO_TASK_EUID, /* current_euid() */
49 TOMOYO_TASK_SUID, /* current_suid() */
50 TOMOYO_TASK_FSUID, /* current_fsuid() */
51 TOMOYO_TASK_GID, /* current_gid() */
52 TOMOYO_TASK_EGID, /* current_egid() */
53 TOMOYO_TASK_SGID, /* current_sgid() */
54 TOMOYO_TASK_FSGID, /* current_fsgid() */
55 TOMOYO_TASK_PID, /* sys_getpid() */
56 TOMOYO_TASK_PPID, /* sys_getppid() */
57 TOMOYO_EXEC_ARGC, /* "struct linux_binprm *"->argc */
58 TOMOYO_EXEC_ENVC, /* "struct linux_binprm *"->envc */
59 TOMOYO_TYPE_IS_SOCKET, /* S_IFSOCK */
60 TOMOYO_TYPE_IS_SYMLINK, /* S_IFLNK */
61 TOMOYO_TYPE_IS_FILE, /* S_IFREG */
62 TOMOYO_TYPE_IS_BLOCK_DEV, /* S_IFBLK */
63 TOMOYO_TYPE_IS_DIRECTORY, /* S_IFDIR */
64 TOMOYO_TYPE_IS_CHAR_DEV, /* S_IFCHR */
65 TOMOYO_TYPE_IS_FIFO, /* S_IFIFO */
66 TOMOYO_MODE_SETUID, /* S_ISUID */
67 TOMOYO_MODE_SETGID, /* S_ISGID */
68 TOMOYO_MODE_STICKY, /* S_ISVTX */
69 TOMOYO_MODE_OWNER_READ, /* S_IRUSR */
70 TOMOYO_MODE_OWNER_WRITE, /* S_IWUSR */
71 TOMOYO_MODE_OWNER_EXECUTE, /* S_IXUSR */
72 TOMOYO_MODE_GROUP_READ, /* S_IRGRP */
73 TOMOYO_MODE_GROUP_WRITE, /* S_IWGRP */
74 TOMOYO_MODE_GROUP_EXECUTE, /* S_IXGRP */
75 TOMOYO_MODE_OTHERS_READ, /* S_IROTH */
76 TOMOYO_MODE_OTHERS_WRITE, /* S_IWOTH */
77 TOMOYO_MODE_OTHERS_EXECUTE, /* S_IXOTH */
78 TOMOYO_EXEC_REALPATH,
79 TOMOYO_SYMLINK_TARGET,
80 TOMOYO_PATH1_UID,
81 TOMOYO_PATH1_GID,
82 TOMOYO_PATH1_INO,
83 TOMOYO_PATH1_MAJOR,
84 TOMOYO_PATH1_MINOR,
85 TOMOYO_PATH1_PERM,
86 TOMOYO_PATH1_TYPE,
87 TOMOYO_PATH1_DEV_MAJOR,
88 TOMOYO_PATH1_DEV_MINOR,
89 TOMOYO_PATH2_UID,
90 TOMOYO_PATH2_GID,
91 TOMOYO_PATH2_INO,
92 TOMOYO_PATH2_MAJOR,
93 TOMOYO_PATH2_MINOR,
94 TOMOYO_PATH2_PERM,
95 TOMOYO_PATH2_TYPE,
96 TOMOYO_PATH2_DEV_MAJOR,
97 TOMOYO_PATH2_DEV_MINOR,
98 TOMOYO_PATH1_PARENT_UID,
99 TOMOYO_PATH1_PARENT_GID,
100 TOMOYO_PATH1_PARENT_INO,
101 TOMOYO_PATH1_PARENT_PERM,
102 TOMOYO_PATH2_PARENT_UID,
103 TOMOYO_PATH2_PARENT_GID,
104 TOMOYO_PATH2_PARENT_INO,
105 TOMOYO_PATH2_PARENT_PERM,
106 TOMOYO_MAX_CONDITION_KEYWORD,
107 TOMOYO_NUMBER_UNION,
108 TOMOYO_NAME_UNION,
109 TOMOYO_ARGV_ENTRY,
110 TOMOYO_ENVP_ENTRY,
111};
112
113
114/* Index numbers for stat(). */
115enum tomoyo_path_stat_index {
116 /* Do not change this order. */
117 TOMOYO_PATH1,
118 TOMOYO_PATH1_PARENT,
119 TOMOYO_PATH2,
120 TOMOYO_PATH2_PARENT,
121 TOMOYO_MAX_PATH_STAT
122};
123
124/* Index numbers for operation mode. */
41enum tomoyo_mode_index { 125enum tomoyo_mode_index {
42 TOMOYO_CONFIG_DISABLED, 126 TOMOYO_CONFIG_DISABLED,
43 TOMOYO_CONFIG_LEARNING, 127 TOMOYO_CONFIG_LEARNING,
44 TOMOYO_CONFIG_PERMISSIVE, 128 TOMOYO_CONFIG_PERMISSIVE,
45 TOMOYO_CONFIG_ENFORCING, 129 TOMOYO_CONFIG_ENFORCING,
46 TOMOYO_CONFIG_USE_DEFAULT = 255 130 TOMOYO_CONFIG_MAX_MODE,
131 TOMOYO_CONFIG_WANT_REJECT_LOG = 64,
132 TOMOYO_CONFIG_WANT_GRANT_LOG = 128,
133 TOMOYO_CONFIG_USE_DEFAULT = 255,
47}; 134};
48 135
136/* Index numbers for entry type. */
49enum tomoyo_policy_id { 137enum tomoyo_policy_id {
50 TOMOYO_ID_GROUP, 138 TOMOYO_ID_GROUP,
51 TOMOYO_ID_PATH_GROUP, 139 TOMOYO_ID_PATH_GROUP,
52 TOMOYO_ID_NUMBER_GROUP, 140 TOMOYO_ID_NUMBER_GROUP,
53 TOMOYO_ID_TRANSITION_CONTROL, 141 TOMOYO_ID_TRANSITION_CONTROL,
54 TOMOYO_ID_AGGREGATOR, 142 TOMOYO_ID_AGGREGATOR,
55 TOMOYO_ID_GLOBALLY_READABLE,
56 TOMOYO_ID_PATTERN,
57 TOMOYO_ID_NO_REWRITE,
58 TOMOYO_ID_MANAGER, 143 TOMOYO_ID_MANAGER,
144 TOMOYO_ID_CONDITION,
59 TOMOYO_ID_NAME, 145 TOMOYO_ID_NAME,
60 TOMOYO_ID_ACL, 146 TOMOYO_ID_ACL,
61 TOMOYO_ID_DOMAIN, 147 TOMOYO_ID_DOMAIN,
62 TOMOYO_MAX_POLICY 148 TOMOYO_MAX_POLICY
63}; 149};
64 150
151/* Index numbers for domain's attributes. */
152enum tomoyo_domain_info_flags_index {
153 /* Quota warnning flag. */
154 TOMOYO_DIF_QUOTA_WARNED,
155 /*
156 * This domain was unable to create a new domain at
157 * tomoyo_find_next_domain() because the name of the domain to be
158 * created was too long or it could not allocate memory.
159 * More than one process continued execve() without domain transition.
160 */
161 TOMOYO_DIF_TRANSITION_FAILED,
162 TOMOYO_MAX_DOMAIN_INFO_FLAGS
163};
164
165/* Index numbers for group entries. */
65enum tomoyo_group_id { 166enum tomoyo_group_id {
66 TOMOYO_PATH_GROUP, 167 TOMOYO_PATH_GROUP,
67 TOMOYO_NUMBER_GROUP, 168 TOMOYO_NUMBER_GROUP,
68 TOMOYO_MAX_GROUP 169 TOMOYO_MAX_GROUP
69}; 170};
70 171
71/* Keywords for ACLs. */ 172/* Index numbers for type of numeric values. */
72#define TOMOYO_KEYWORD_AGGREGATOR "aggregator " 173enum tomoyo_value_type {
73#define TOMOYO_KEYWORD_ALLOW_MOUNT "allow_mount " 174 TOMOYO_VALUE_TYPE_INVALID,
74#define TOMOYO_KEYWORD_ALLOW_READ "allow_read " 175 TOMOYO_VALUE_TYPE_DECIMAL,
75#define TOMOYO_KEYWORD_DELETE "delete " 176 TOMOYO_VALUE_TYPE_OCTAL,
76#define TOMOYO_KEYWORD_DENY_REWRITE "deny_rewrite " 177 TOMOYO_VALUE_TYPE_HEXADECIMAL,
77#define TOMOYO_KEYWORD_FILE_PATTERN "file_pattern " 178};
78#define TOMOYO_KEYWORD_INITIALIZE_DOMAIN "initialize_domain "
79#define TOMOYO_KEYWORD_KEEP_DOMAIN "keep_domain "
80#define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain "
81#define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain "
82#define TOMOYO_KEYWORD_PATH_GROUP "path_group "
83#define TOMOYO_KEYWORD_NUMBER_GROUP "number_group "
84#define TOMOYO_KEYWORD_SELECT "select "
85#define TOMOYO_KEYWORD_USE_PROFILE "use_profile "
86#define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read"
87#define TOMOYO_KEYWORD_QUOTA_EXCEEDED "quota_exceeded"
88#define TOMOYO_KEYWORD_TRANSITION_FAILED "transition_failed"
89/* A domain definition starts with <kernel>. */
90#define TOMOYO_ROOT_NAME "<kernel>"
91#define TOMOYO_ROOT_NAME_LEN (sizeof(TOMOYO_ROOT_NAME) - 1)
92
93/* Value type definition. */
94#define TOMOYO_VALUE_TYPE_INVALID 0
95#define TOMOYO_VALUE_TYPE_DECIMAL 1
96#define TOMOYO_VALUE_TYPE_OCTAL 2
97#define TOMOYO_VALUE_TYPE_HEXADECIMAL 3
98 179
180/* Index numbers for domain transition control keywords. */
99enum tomoyo_transition_type { 181enum tomoyo_transition_type {
100 /* Do not change this order, */ 182 /* Do not change this order, */
183 TOMOYO_TRANSITION_CONTROL_NO_RESET,
184 TOMOYO_TRANSITION_CONTROL_RESET,
101 TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE, 185 TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE,
102 TOMOYO_TRANSITION_CONTROL_INITIALIZE, 186 TOMOYO_TRANSITION_CONTROL_INITIALIZE,
103 TOMOYO_TRANSITION_CONTROL_NO_KEEP, 187 TOMOYO_TRANSITION_CONTROL_NO_KEEP,
@@ -114,35 +198,29 @@ enum tomoyo_acl_entry_type_index {
114 TOMOYO_TYPE_MOUNT_ACL, 198 TOMOYO_TYPE_MOUNT_ACL,
115}; 199};
116 200
117/* Index numbers for File Controls. */ 201/* Index numbers for access controls with one pathname. */
118
119/*
120 * TOMOYO_TYPE_READ_WRITE is special. TOMOYO_TYPE_READ_WRITE is automatically
121 * set if both TOMOYO_TYPE_READ and TOMOYO_TYPE_WRITE are set.
122 * Both TOMOYO_TYPE_READ and TOMOYO_TYPE_WRITE are automatically set if
123 * TOMOYO_TYPE_READ_WRITE is set.
124 * TOMOYO_TYPE_READ_WRITE is automatically cleared if either TOMOYO_TYPE_READ
125 * or TOMOYO_TYPE_WRITE is cleared.
126 * Both TOMOYO_TYPE_READ and TOMOYO_TYPE_WRITE are automatically cleared if
127 * TOMOYO_TYPE_READ_WRITE is cleared.
128 */
129
130enum tomoyo_path_acl_index { 202enum tomoyo_path_acl_index {
131 TOMOYO_TYPE_READ_WRITE,
132 TOMOYO_TYPE_EXECUTE, 203 TOMOYO_TYPE_EXECUTE,
133 TOMOYO_TYPE_READ, 204 TOMOYO_TYPE_READ,
134 TOMOYO_TYPE_WRITE, 205 TOMOYO_TYPE_WRITE,
206 TOMOYO_TYPE_APPEND,
135 TOMOYO_TYPE_UNLINK, 207 TOMOYO_TYPE_UNLINK,
208 TOMOYO_TYPE_GETATTR,
136 TOMOYO_TYPE_RMDIR, 209 TOMOYO_TYPE_RMDIR,
137 TOMOYO_TYPE_TRUNCATE, 210 TOMOYO_TYPE_TRUNCATE,
138 TOMOYO_TYPE_SYMLINK, 211 TOMOYO_TYPE_SYMLINK,
139 TOMOYO_TYPE_REWRITE,
140 TOMOYO_TYPE_CHROOT, 212 TOMOYO_TYPE_CHROOT,
141 TOMOYO_TYPE_UMOUNT, 213 TOMOYO_TYPE_UMOUNT,
142 TOMOYO_MAX_PATH_OPERATION 214 TOMOYO_MAX_PATH_OPERATION
143}; 215};
144 216
145#define TOMOYO_RW_MASK ((1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE)) 217/* Index numbers for /sys/kernel/security/tomoyo/stat interface. */
218enum tomoyo_memory_stat_type {
219 TOMOYO_MEMORY_POLICY,
220 TOMOYO_MEMORY_AUDIT,
221 TOMOYO_MEMORY_QUERY,
222 TOMOYO_MAX_MEMORY_STAT
223};
146 224
147enum tomoyo_mkdev_acl_index { 225enum tomoyo_mkdev_acl_index {
148 TOMOYO_TYPE_MKBLOCK, 226 TOMOYO_TYPE_MKBLOCK,
@@ -150,6 +228,7 @@ enum tomoyo_mkdev_acl_index {
150 TOMOYO_MAX_MKDEV_OPERATION 228 TOMOYO_MAX_MKDEV_OPERATION
151}; 229};
152 230
231/* Index numbers for access controls with two pathnames. */
153enum tomoyo_path2_acl_index { 232enum tomoyo_path2_acl_index {
154 TOMOYO_TYPE_LINK, 233 TOMOYO_TYPE_LINK,
155 TOMOYO_TYPE_RENAME, 234 TOMOYO_TYPE_RENAME,
@@ -157,6 +236,7 @@ enum tomoyo_path2_acl_index {
157 TOMOYO_MAX_PATH2_OPERATION 236 TOMOYO_MAX_PATH2_OPERATION
158}; 237};
159 238
239/* Index numbers for access controls with one pathname and one number. */
160enum tomoyo_path_number_acl_index { 240enum tomoyo_path_number_acl_index {
161 TOMOYO_TYPE_CREATE, 241 TOMOYO_TYPE_CREATE,
162 TOMOYO_TYPE_MKDIR, 242 TOMOYO_TYPE_MKDIR,
@@ -169,31 +249,45 @@ enum tomoyo_path_number_acl_index {
169 TOMOYO_MAX_PATH_NUMBER_OPERATION 249 TOMOYO_MAX_PATH_NUMBER_OPERATION
170}; 250};
171 251
252/* Index numbers for /sys/kernel/security/tomoyo/ interfaces. */
172enum tomoyo_securityfs_interface_index { 253enum tomoyo_securityfs_interface_index {
173 TOMOYO_DOMAINPOLICY, 254 TOMOYO_DOMAINPOLICY,
174 TOMOYO_EXCEPTIONPOLICY, 255 TOMOYO_EXCEPTIONPOLICY,
175 TOMOYO_DOMAIN_STATUS,
176 TOMOYO_PROCESS_STATUS, 256 TOMOYO_PROCESS_STATUS,
177 TOMOYO_MEMINFO, 257 TOMOYO_STAT,
178 TOMOYO_SELFDOMAIN, 258 TOMOYO_SELFDOMAIN,
259 TOMOYO_AUDIT,
179 TOMOYO_VERSION, 260 TOMOYO_VERSION,
180 TOMOYO_PROFILE, 261 TOMOYO_PROFILE,
181 TOMOYO_QUERY, 262 TOMOYO_QUERY,
182 TOMOYO_MANAGER 263 TOMOYO_MANAGER
183}; 264};
184 265
266/* Index numbers for special mount operations. */
267enum tomoyo_special_mount {
268 TOMOYO_MOUNT_BIND, /* mount --bind /source /dest */
269 TOMOYO_MOUNT_MOVE, /* mount --move /old /new */
270 TOMOYO_MOUNT_REMOUNT, /* mount -o remount /dir */
271 TOMOYO_MOUNT_MAKE_UNBINDABLE, /* mount --make-unbindable /dir */
272 TOMOYO_MOUNT_MAKE_PRIVATE, /* mount --make-private /dir */
273 TOMOYO_MOUNT_MAKE_SLAVE, /* mount --make-slave /dir */
274 TOMOYO_MOUNT_MAKE_SHARED, /* mount --make-shared /dir */
275 TOMOYO_MAX_SPECIAL_MOUNT
276};
277
278/* Index numbers for functionality. */
185enum tomoyo_mac_index { 279enum tomoyo_mac_index {
186 TOMOYO_MAC_FILE_EXECUTE, 280 TOMOYO_MAC_FILE_EXECUTE,
187 TOMOYO_MAC_FILE_OPEN, 281 TOMOYO_MAC_FILE_OPEN,
188 TOMOYO_MAC_FILE_CREATE, 282 TOMOYO_MAC_FILE_CREATE,
189 TOMOYO_MAC_FILE_UNLINK, 283 TOMOYO_MAC_FILE_UNLINK,
284 TOMOYO_MAC_FILE_GETATTR,
190 TOMOYO_MAC_FILE_MKDIR, 285 TOMOYO_MAC_FILE_MKDIR,
191 TOMOYO_MAC_FILE_RMDIR, 286 TOMOYO_MAC_FILE_RMDIR,
192 TOMOYO_MAC_FILE_MKFIFO, 287 TOMOYO_MAC_FILE_MKFIFO,
193 TOMOYO_MAC_FILE_MKSOCK, 288 TOMOYO_MAC_FILE_MKSOCK,
194 TOMOYO_MAC_FILE_TRUNCATE, 289 TOMOYO_MAC_FILE_TRUNCATE,
195 TOMOYO_MAC_FILE_SYMLINK, 290 TOMOYO_MAC_FILE_SYMLINK,
196 TOMOYO_MAC_FILE_REWRITE,
197 TOMOYO_MAC_FILE_MKBLOCK, 291 TOMOYO_MAC_FILE_MKBLOCK,
198 TOMOYO_MAC_FILE_MKCHAR, 292 TOMOYO_MAC_FILE_MKCHAR,
199 TOMOYO_MAC_FILE_LINK, 293 TOMOYO_MAC_FILE_LINK,
@@ -209,38 +303,66 @@ enum tomoyo_mac_index {
209 TOMOYO_MAX_MAC_INDEX 303 TOMOYO_MAX_MAC_INDEX
210}; 304};
211 305
306/* Index numbers for category of functionality. */
212enum tomoyo_mac_category_index { 307enum tomoyo_mac_category_index {
213 TOMOYO_MAC_CATEGORY_FILE, 308 TOMOYO_MAC_CATEGORY_FILE,
214 TOMOYO_MAX_MAC_CATEGORY_INDEX 309 TOMOYO_MAX_MAC_CATEGORY_INDEX
215}; 310};
216 311
217#define TOMOYO_RETRY_REQUEST 1 /* Retry this request. */
218
219/********** Structure definitions. **********/
220
221/* 312/*
222 * tomoyo_acl_head is a structure which is used for holding elements not in 313 * Retry this request. Returned by tomoyo_supervisor() if policy violation has
223 * domain policy. 314 * occurred in enforcing mode and the userspace daemon decided to retry.
224 * It has following fields.
225 * 315 *
226 * (1) "list" which is linked to tomoyo_policy_list[] . 316 * We must choose a positive value in order to distinguish "granted" (which is
227 * (2) "is_deleted" is a bool which is true if marked as deleted, false 317 * 0) and "rejected" (which is a negative value) and "retry".
228 * otherwise.
229 */ 318 */
319#define TOMOYO_RETRY_REQUEST 1
320
321/* Index numbers for /sys/kernel/security/tomoyo/stat interface. */
322enum tomoyo_policy_stat_type {
323 /* Do not change this order. */
324 TOMOYO_STAT_POLICY_UPDATES,
325 TOMOYO_STAT_POLICY_LEARNING, /* == TOMOYO_CONFIG_LEARNING */
326 TOMOYO_STAT_POLICY_PERMISSIVE, /* == TOMOYO_CONFIG_PERMISSIVE */
327 TOMOYO_STAT_POLICY_ENFORCING, /* == TOMOYO_CONFIG_ENFORCING */
328 TOMOYO_MAX_POLICY_STAT
329};
330
331/* Index numbers for profile's PREFERENCE values. */
332enum tomoyo_pref_index {
333 TOMOYO_PREF_MAX_AUDIT_LOG,
334 TOMOYO_PREF_MAX_LEARNING_ENTRY,
335 TOMOYO_MAX_PREF
336};
337
338/********** Structure definitions. **********/
339
340/* Common header for holding ACL entries. */
230struct tomoyo_acl_head { 341struct tomoyo_acl_head {
231 struct list_head list; 342 struct list_head list;
232 bool is_deleted; 343 bool is_deleted;
233} __packed; 344} __packed;
234 345
235/* 346/* Common header for shared entries. */
236 * tomoyo_request_info is a structure which is used for holding 347struct tomoyo_shared_acl_head {
237 * 348 struct list_head list;
238 * (1) Domain information of current process. 349 atomic_t users;
239 * (2) How many retries are made for this request. 350} __packed;
240 * (3) Profile number used for this request. 351
241 * (4) Access control mode of the profile. 352struct tomoyo_policy_namespace;
242 */ 353
354/* Structure for request info. */
243struct tomoyo_request_info { 355struct tomoyo_request_info {
356 /*
357 * For holding parameters specific to operations which deal files.
358 * NULL if not dealing files.
359 */
360 struct tomoyo_obj_info *obj;
361 /*
362 * For holding parameters specific to execve() request.
363 * NULL if not dealing do_execve().
364 */
365 struct tomoyo_execve *ee;
244 struct tomoyo_domain_info *domain; 366 struct tomoyo_domain_info *domain;
245 /* For holding parameters. */ 367 /* For holding parameters. */
246 union { 368 union {
@@ -248,11 +370,13 @@ struct tomoyo_request_info {
248 const struct tomoyo_path_info *filename; 370 const struct tomoyo_path_info *filename;
249 /* For using wildcards at tomoyo_find_next_domain(). */ 371 /* For using wildcards at tomoyo_find_next_domain(). */
250 const struct tomoyo_path_info *matched_path; 372 const struct tomoyo_path_info *matched_path;
373 /* One of values in "enum tomoyo_path_acl_index". */
251 u8 operation; 374 u8 operation;
252 } path; 375 } path;
253 struct { 376 struct {
254 const struct tomoyo_path_info *filename1; 377 const struct tomoyo_path_info *filename1;
255 const struct tomoyo_path_info *filename2; 378 const struct tomoyo_path_info *filename2;
379 /* One of values in "enum tomoyo_path2_acl_index". */
256 u8 operation; 380 u8 operation;
257 } path2; 381 } path2;
258 struct { 382 struct {
@@ -260,11 +384,16 @@ struct tomoyo_request_info {
260 unsigned int mode; 384 unsigned int mode;
261 unsigned int major; 385 unsigned int major;
262 unsigned int minor; 386 unsigned int minor;
387 /* One of values in "enum tomoyo_mkdev_acl_index". */
263 u8 operation; 388 u8 operation;
264 } mkdev; 389 } mkdev;
265 struct { 390 struct {
266 const struct tomoyo_path_info *filename; 391 const struct tomoyo_path_info *filename;
267 unsigned long number; 392 unsigned long number;
393 /*
394 * One of values in
395 * "enum tomoyo_path_number_acl_index".
396 */
268 u8 operation; 397 u8 operation;
269 } path_number; 398 } path_number;
270 struct { 399 struct {
@@ -283,26 +412,7 @@ struct tomoyo_request_info {
283 u8 type; 412 u8 type;
284}; 413};
285 414
286/* 415/* Structure for holding a token. */
287 * tomoyo_path_info is a structure which is used for holding a string data
288 * used by TOMOYO.
289 * This structure has several fields for supporting pattern matching.
290 *
291 * (1) "name" is the '\0' terminated string data.
292 * (2) "hash" is full_name_hash(name, strlen(name)).
293 * This allows tomoyo_pathcmp() to compare by hash before actually compare
294 * using strcmp().
295 * (3) "const_len" is the length of the initial segment of "name" which
296 * consists entirely of non wildcard characters. In other words, the length
297 * which we can compare two strings using strncmp().
298 * (4) "is_dir" is a bool which is true if "name" ends with "/",
299 * false otherwise.
300 * TOMOYO distinguishes directory and non-directory. A directory ends with
301 * "/" and non-directory does not end with "/".
302 * (5) "is_patterned" is a bool which is true if "name" contains wildcard
303 * characters, false otherwise. This allows TOMOYO to use "hash" and
304 * strcmp() for string comparison if "is_patterned" is false.
305 */
306struct tomoyo_path_info { 416struct tomoyo_path_info {
307 const char *name; 417 const char *name;
308 u32 hash; /* = full_name_hash(name, strlen(name)) */ 418 u32 hash; /* = full_name_hash(name, strlen(name)) */
@@ -311,36 +421,32 @@ struct tomoyo_path_info {
311 bool is_patterned; /* = tomoyo_path_contains_pattern(name) */ 421 bool is_patterned; /* = tomoyo_path_contains_pattern(name) */
312}; 422};
313 423
314/* 424/* Structure for holding string data. */
315 * tomoyo_name is a structure which is used for linking
316 * "struct tomoyo_path_info" into tomoyo_name_list .
317 */
318struct tomoyo_name { 425struct tomoyo_name {
319 struct list_head list; 426 struct tomoyo_shared_acl_head head;
320 atomic_t users;
321 struct tomoyo_path_info entry; 427 struct tomoyo_path_info entry;
322}; 428};
323 429
430/* Structure for holding a word. */
324struct tomoyo_name_union { 431struct tomoyo_name_union {
432 /* Either @filename or @group is NULL. */
325 const struct tomoyo_path_info *filename; 433 const struct tomoyo_path_info *filename;
326 struct tomoyo_group *group; 434 struct tomoyo_group *group;
327 u8 is_group;
328}; 435};
329 436
437/* Structure for holding a number. */
330struct tomoyo_number_union { 438struct tomoyo_number_union {
331 unsigned long values[2]; 439 unsigned long values[2];
332 struct tomoyo_group *group; 440 struct tomoyo_group *group; /* Maybe NULL. */
333 u8 min_type; 441 /* One of values in "enum tomoyo_value_type". */
334 u8 max_type; 442 u8 value_type[2];
335 u8 is_group;
336}; 443};
337 444
338/* Structure for "path_group"/"number_group" directive. */ 445/* Structure for "path_group"/"number_group" directive. */
339struct tomoyo_group { 446struct tomoyo_group {
340 struct list_head list; 447 struct tomoyo_shared_acl_head head;
341 const struct tomoyo_path_info *group_name; 448 const struct tomoyo_path_info *group_name;
342 struct list_head member_list; 449 struct list_head member_list;
343 atomic_t users;
344}; 450};
345 451
346/* Structure for "path_group" directive. */ 452/* Structure for "path_group" directive. */
@@ -355,130 +461,158 @@ struct tomoyo_number_group {
355 struct tomoyo_number_union number; 461 struct tomoyo_number_union number;
356}; 462};
357 463
358/* 464/* Subset of "struct stat". Used by conditional ACL and audit logs. */
359 * tomoyo_acl_info is a structure which is used for holding 465struct tomoyo_mini_stat {
360 * 466 uid_t uid;
361 * (1) "list" which is linked to the ->acl_info_list of 467 gid_t gid;
362 * "struct tomoyo_domain_info" 468 ino_t ino;
363 * (2) "is_deleted" is a bool which is true if this domain is marked as 469 mode_t mode;
364 * "deleted", false otherwise. 470 dev_t dev;
365 * (3) "type" which tells type of the entry. 471 dev_t rdev;
366 * 472};
367 * Packing "struct tomoyo_acl_info" allows 473
368 * "struct tomoyo_path_acl" to embed "u16" and "struct tomoyo_path2_acl" 474/* Structure for dumping argv[] and envp[] of "struct linux_binprm". */
369 * "struct tomoyo_path_number_acl" "struct tomoyo_mkdev_acl" to embed 475struct tomoyo_page_dump {
370 * "u8" without enlarging their structure size. 476 struct page *page; /* Previously dumped page. */
371 */ 477 char *data; /* Contents of "page". Size is PAGE_SIZE. */
478};
479
480/* Structure for attribute checks in addition to pathname checks. */
481struct tomoyo_obj_info {
482 /*
483 * True if tomoyo_get_attributes() was already called, false otherwise.
484 */
485 bool validate_done;
486 /* True if @stat[] is valid. */
487 bool stat_valid[TOMOYO_MAX_PATH_STAT];
488 /* First pathname. Initialized with { NULL, NULL } if no path. */
489 struct path path1;
490 /* Second pathname. Initialized with { NULL, NULL } if no path. */
491 struct path path2;
492 /*
493 * Information on @path1, @path1's parent directory, @path2, @path2's
494 * parent directory.
495 */
496 struct tomoyo_mini_stat stat[TOMOYO_MAX_PATH_STAT];
497 /*
498 * Content of symbolic link to be created. NULL for operations other
499 * than symlink().
500 */
501 struct tomoyo_path_info *symlink_target;
502};
503
504/* Structure for argv[]. */
505struct tomoyo_argv {
506 unsigned long index;
507 const struct tomoyo_path_info *value;
508 bool is_not;
509};
510
511/* Structure for envp[]. */
512struct tomoyo_envp {
513 const struct tomoyo_path_info *name;
514 const struct tomoyo_path_info *value;
515 bool is_not;
516};
517
518/* Structure for execve() operation. */
519struct tomoyo_execve {
520 struct tomoyo_request_info r;
521 struct tomoyo_obj_info obj;
522 struct linux_binprm *bprm;
523 /* For dumping argv[] and envp[]. */
524 struct tomoyo_page_dump dump;
525 /* For temporary use. */
526 char *tmp; /* Size is TOMOYO_EXEC_TMPSIZE bytes */
527};
528
529/* Structure for entries which follows "struct tomoyo_condition". */
530struct tomoyo_condition_element {
531 /*
532 * Left hand operand. A "struct tomoyo_argv" for TOMOYO_ARGV_ENTRY, a
533 * "struct tomoyo_envp" for TOMOYO_ENVP_ENTRY is attached to the tail
534 * of the array of this struct.
535 */
536 u8 left;
537 /*
538 * Right hand operand. A "struct tomoyo_number_union" for
539 * TOMOYO_NUMBER_UNION, a "struct tomoyo_name_union" for
540 * TOMOYO_NAME_UNION is attached to the tail of the array of this
541 * struct.
542 */
543 u8 right;
544 /* Equation operator. True if equals or overlaps, false otherwise. */
545 bool equals;
546};
547
548/* Structure for optional arguments. */
549struct tomoyo_condition {
550 struct tomoyo_shared_acl_head head;
551 u32 size; /* Memory size allocated for this entry. */
552 u16 condc; /* Number of conditions in this struct. */
553 u16 numbers_count; /* Number of "struct tomoyo_number_union values". */
554 u16 names_count; /* Number of "struct tomoyo_name_union names". */
555 u16 argc; /* Number of "struct tomoyo_argv". */
556 u16 envc; /* Number of "struct tomoyo_envp". */
557 /*
558 * struct tomoyo_condition_element condition[condc];
559 * struct tomoyo_number_union values[numbers_count];
560 * struct tomoyo_name_union names[names_count];
561 * struct tomoyo_argv argv[argc];
562 * struct tomoyo_envp envp[envc];
563 */
564};
565
566/* Common header for individual entries. */
372struct tomoyo_acl_info { 567struct tomoyo_acl_info {
373 struct list_head list; 568 struct list_head list;
569 struct tomoyo_condition *cond; /* Maybe NULL. */
374 bool is_deleted; 570 bool is_deleted;
375 u8 type; /* = one of values in "enum tomoyo_acl_entry_type_index". */ 571 u8 type; /* One of values in "enum tomoyo_acl_entry_type_index". */
376} __packed; 572} __packed;
377 573
378/* 574/* Structure for domain information. */
379 * tomoyo_domain_info is a structure which is used for holding permissions
380 * (e.g. "allow_read /lib/libc-2.5.so") given to each domain.
381 * It has following fields.
382 *
383 * (1) "list" which is linked to tomoyo_domain_list .
384 * (2) "acl_info_list" which is linked to "struct tomoyo_acl_info".
385 * (3) "domainname" which holds the name of the domain.
386 * (4) "profile" which remembers profile number assigned to this domain.
387 * (5) "is_deleted" is a bool which is true if this domain is marked as
388 * "deleted", false otherwise.
389 * (6) "quota_warned" is a bool which is used for suppressing warning message
390 * when learning mode learned too much entries.
391 * (7) "ignore_global_allow_read" is a bool which is true if this domain
392 * should ignore "allow_read" directive in exception policy.
393 * (8) "transition_failed" is a bool which is set to true when this domain was
394 * unable to create a new domain at tomoyo_find_next_domain() because the
395 * name of the domain to be created was too long or it could not allocate
396 * memory. If set to true, more than one process continued execve()
397 * without domain transition.
398 * (9) "users" is an atomic_t that holds how many "struct cred"->security
399 * are referring this "struct tomoyo_domain_info". If is_deleted == true
400 * and users == 0, this struct will be kfree()d upon next garbage
401 * collection.
402 *
403 * A domain's lifecycle is an analogy of files on / directory.
404 * Multiple domains with the same domainname cannot be created (as with
405 * creating files with the same filename fails with -EEXIST).
406 * If a process reached a domain, that process can reside in that domain after
407 * that domain is marked as "deleted" (as with a process can access an already
408 * open()ed file after that file was unlink()ed).
409 */
410struct tomoyo_domain_info { 575struct tomoyo_domain_info {
411 struct list_head list; 576 struct list_head list;
412 struct list_head acl_info_list; 577 struct list_head acl_info_list;
413 /* Name of this domain. Never NULL. */ 578 /* Name of this domain. Never NULL. */
414 const struct tomoyo_path_info *domainname; 579 const struct tomoyo_path_info *domainname;
580 /* Namespace for this domain. Never NULL. */
581 struct tomoyo_policy_namespace *ns;
415 u8 profile; /* Profile number to use. */ 582 u8 profile; /* Profile number to use. */
583 u8 group; /* Group number to use. */
416 bool is_deleted; /* Delete flag. */ 584 bool is_deleted; /* Delete flag. */
417 bool quota_warned; /* Quota warnning flag. */ 585 bool flags[TOMOYO_MAX_DOMAIN_INFO_FLAGS];
418 bool ignore_global_allow_read; /* Ignore "allow_read" flag. */
419 bool transition_failed; /* Domain transition failed flag. */
420 atomic_t users; /* Number of referring credentials. */ 586 atomic_t users; /* Number of referring credentials. */
421}; 587};
422 588
423/* 589/*
424 * tomoyo_path_acl is a structure which is used for holding an 590 * Structure for "file execute", "file read", "file write", "file append",
425 * entry with one pathname operation (e.g. open(), mkdir()). 591 * "file unlink", "file getattr", "file rmdir", "file truncate",
426 * It has following fields. 592 * "file symlink", "file chroot" and "file unmount" directive.
427 *
428 * (1) "head" which is a "struct tomoyo_acl_info".
429 * (2) "perm" which is a bitmask of permitted operations.
430 * (3) "name" is the pathname.
431 *
432 * Directives held by this structure are "allow_read/write", "allow_execute",
433 * "allow_read", "allow_write", "allow_unlink", "allow_rmdir",
434 * "allow_truncate", "allow_symlink", "allow_rewrite", "allow_chroot" and
435 * "allow_unmount".
436 */ 593 */
437struct tomoyo_path_acl { 594struct tomoyo_path_acl {
438 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_ACL */ 595 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_ACL */
439 u16 perm; 596 u16 perm; /* Bitmask of values in "enum tomoyo_path_acl_index". */
440 struct tomoyo_name_union name; 597 struct tomoyo_name_union name;
441}; 598};
442 599
443/* 600/*
444 * tomoyo_path_number_acl is a structure which is used for holding an 601 * Structure for "file create", "file mkdir", "file mkfifo", "file mksock",
445 * entry with one pathname and one number operation. 602 * "file ioctl", "file chmod", "file chown" and "file chgrp" directive.
446 * It has following fields.
447 *
448 * (1) "head" which is a "struct tomoyo_acl_info".
449 * (2) "perm" which is a bitmask of permitted operations.
450 * (3) "name" is the pathname.
451 * (4) "number" is the numeric value.
452 *
453 * Directives held by this structure are "allow_create", "allow_mkdir",
454 * "allow_ioctl", "allow_mkfifo", "allow_mksock", "allow_chmod", "allow_chown"
455 * and "allow_chgrp".
456 *
457 */ 603 */
458struct tomoyo_path_number_acl { 604struct tomoyo_path_number_acl {
459 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_NUMBER_ACL */ 605 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_NUMBER_ACL */
606 /* Bitmask of values in "enum tomoyo_path_number_acl_index". */
460 u8 perm; 607 u8 perm;
461 struct tomoyo_name_union name; 608 struct tomoyo_name_union name;
462 struct tomoyo_number_union number; 609 struct tomoyo_number_union number;
463}; 610};
464 611
465/* 612/* Structure for "file mkblock" and "file mkchar" directive. */
466 * tomoyo_mkdev_acl is a structure which is used for holding an
467 * entry with one pathname and three numbers operation.
468 * It has following fields.
469 *
470 * (1) "head" which is a "struct tomoyo_acl_info".
471 * (2) "perm" which is a bitmask of permitted operations.
472 * (3) "mode" is the create mode.
473 * (4) "major" is the major number of device node.
474 * (5) "minor" is the minor number of device node.
475 *
476 * Directives held by this structure are "allow_mkchar", "allow_mkblock".
477 *
478 */
479struct tomoyo_mkdev_acl { 613struct tomoyo_mkdev_acl {
480 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_MKDEV_ACL */ 614 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_MKDEV_ACL */
481 u8 perm; 615 u8 perm; /* Bitmask of values in "enum tomoyo_mkdev_acl_index". */
482 struct tomoyo_name_union name; 616 struct tomoyo_name_union name;
483 struct tomoyo_number_union mode; 617 struct tomoyo_number_union mode;
484 struct tomoyo_number_union major; 618 struct tomoyo_number_union major;
@@ -486,38 +620,16 @@ struct tomoyo_mkdev_acl {
486}; 620};
487 621
488/* 622/*
489 * tomoyo_path2_acl is a structure which is used for holding an 623 * Structure for "file rename", "file link" and "file pivot_root" directive.
490 * entry with two pathnames operation (i.e. link(), rename() and pivot_root()).
491 * It has following fields.
492 *
493 * (1) "head" which is a "struct tomoyo_acl_info".
494 * (2) "perm" which is a bitmask of permitted operations.
495 * (3) "name1" is the source/old pathname.
496 * (4) "name2" is the destination/new pathname.
497 *
498 * Directives held by this structure are "allow_rename", "allow_link" and
499 * "allow_pivot_root".
500 */ 624 */
501struct tomoyo_path2_acl { 625struct tomoyo_path2_acl {
502 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH2_ACL */ 626 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH2_ACL */
503 u8 perm; 627 u8 perm; /* Bitmask of values in "enum tomoyo_path2_acl_index". */
504 struct tomoyo_name_union name1; 628 struct tomoyo_name_union name1;
505 struct tomoyo_name_union name2; 629 struct tomoyo_name_union name2;
506}; 630};
507 631
508/* 632/* Structure for "file mount" directive. */
509 * tomoyo_mount_acl is a structure which is used for holding an
510 * entry for mount operation.
511 * It has following fields.
512 *
513 * (1) "head" which is a "struct tomoyo_acl_info".
514 * (2) "dev_name" is the device name.
515 * (3) "dir_name" is the mount point.
516 * (4) "fs_type" is the filesystem type.
517 * (5) "flags" is the mount flags.
518 *
519 * Directive held by this structure is "allow_mount".
520 */
521struct tomoyo_mount_acl { 633struct tomoyo_mount_acl {
522 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_MOUNT_ACL */ 634 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_MOUNT_ACL */
523 struct tomoyo_name_union dev_name; 635 struct tomoyo_name_union dev_name;
@@ -526,7 +638,15 @@ struct tomoyo_mount_acl {
526 struct tomoyo_number_union flags; 638 struct tomoyo_number_union flags;
527}; 639};
528 640
529#define TOMOYO_MAX_IO_READ_QUEUE 32 641/* Structure for holding a line from /sys/kernel/security/tomoyo/ interface. */
642struct tomoyo_acl_param {
643 char *data;
644 struct list_head *list;
645 struct tomoyo_policy_namespace *ns;
646 bool is_delete;
647};
648
649#define TOMOYO_MAX_IO_READ_QUEUE 64
530 650
531/* 651/*
532 * Structure for reading/writing policy via /sys/kernel/security/tomoyo 652 * Structure for reading/writing policy via /sys/kernel/security/tomoyo
@@ -538,95 +658,55 @@ struct tomoyo_io_buffer {
538 int (*poll) (struct file *file, poll_table *wait); 658 int (*poll) (struct file *file, poll_table *wait);
539 /* Exclusive lock for this structure. */ 659 /* Exclusive lock for this structure. */
540 struct mutex io_sem; 660 struct mutex io_sem;
541 /* Index returned by tomoyo_read_lock(). */
542 int reader_idx;
543 char __user *read_user_buf; 661 char __user *read_user_buf;
544 int read_user_buf_avail; 662 size_t read_user_buf_avail;
545 struct { 663 struct {
664 struct list_head *ns;
546 struct list_head *domain; 665 struct list_head *domain;
547 struct list_head *group; 666 struct list_head *group;
548 struct list_head *acl; 667 struct list_head *acl;
549 int avail; 668 size_t avail;
550 int step; 669 unsigned int step;
551 int query_index; 670 unsigned int query_index;
552 u16 index; 671 u16 index;
672 u16 cond_index;
673 u8 acl_group_index;
674 u8 cond_step;
553 u8 bit; 675 u8 bit;
554 u8 w_pos; 676 u8 w_pos;
555 bool eof; 677 bool eof;
556 bool print_this_domain_only; 678 bool print_this_domain_only;
557 bool print_execute_only; 679 bool print_transition_related_only;
680 bool print_cond_part;
558 const char *w[TOMOYO_MAX_IO_READ_QUEUE]; 681 const char *w[TOMOYO_MAX_IO_READ_QUEUE];
559 } r; 682 } r;
560 /* The position currently writing to. */ 683 struct {
561 struct tomoyo_domain_info *write_var1; 684 struct tomoyo_policy_namespace *ns;
685 /* The position currently writing to. */
686 struct tomoyo_domain_info *domain;
687 /* Bytes available for writing. */
688 size_t avail;
689 bool is_delete;
690 } w;
562 /* Buffer for reading. */ 691 /* Buffer for reading. */
563 char *read_buf; 692 char *read_buf;
564 /* Size of read buffer. */ 693 /* Size of read buffer. */
565 int readbuf_size; 694 size_t readbuf_size;
566 /* Buffer for writing. */ 695 /* Buffer for writing. */
567 char *write_buf; 696 char *write_buf;
568 /* Bytes available for writing. */
569 int write_avail;
570 /* Size of write buffer. */ 697 /* Size of write buffer. */
571 int writebuf_size; 698 size_t writebuf_size;
572 /* Type of this interface. */ 699 /* Type of this interface. */
573 u8 type; 700 enum tomoyo_securityfs_interface_index type;
574}; 701 /* Users counter protected by tomoyo_io_buffer_list_lock. */
575 702 u8 users;
576/* 703 /* List for telling GC not to kfree() elements. */
577 * tomoyo_readable_file is a structure which is used for holding 704 struct list_head list;
578 * "allow_read" entries.
579 * It has following fields.
580 *
581 * (1) "head" is "struct tomoyo_acl_head".
582 * (2) "filename" is a pathname which is allowed to open(O_RDONLY).
583 */
584struct tomoyo_readable_file {
585 struct tomoyo_acl_head head;
586 const struct tomoyo_path_info *filename;
587};
588
589/*
590 * tomoyo_no_pattern is a structure which is used for holding
591 * "file_pattern" entries.
592 * It has following fields.
593 *
594 * (1) "head" is "struct tomoyo_acl_head".
595 * (2) "pattern" is a pathname pattern which is used for converting pathnames
596 * to pathname patterns during learning mode.
597 */
598struct tomoyo_no_pattern {
599 struct tomoyo_acl_head head;
600 const struct tomoyo_path_info *pattern;
601};
602
603/*
604 * tomoyo_no_rewrite is a structure which is used for holding
605 * "deny_rewrite" entries.
606 * It has following fields.
607 *
608 * (1) "head" is "struct tomoyo_acl_head".
609 * (2) "pattern" is a pathname which is by default not permitted to modify
610 * already existing content.
611 */
612struct tomoyo_no_rewrite {
613 struct tomoyo_acl_head head;
614 const struct tomoyo_path_info *pattern;
615}; 705};
616 706
617/* 707/*
618 * tomoyo_transition_control is a structure which is used for holding 708 * Structure for "initialize_domain"/"no_initialize_domain"/"keep_domain"/
619 * "initialize_domain"/"no_initialize_domain"/"keep_domain"/"no_keep_domain" 709 * "no_keep_domain" keyword.
620 * entries.
621 * It has following fields.
622 *
623 * (1) "head" is "struct tomoyo_acl_head".
624 * (2) "type" is type of this entry.
625 * (3) "is_last_name" is a bool which is true if "domainname" is "the last
626 * component of a domainname", false otherwise.
627 * (4) "domainname" which is "a domainname" or "the last component of a
628 * domainname".
629 * (5) "program" which is a program's pathname.
630 */ 710 */
631struct tomoyo_transition_control { 711struct tomoyo_transition_control {
632 struct tomoyo_acl_head head; 712 struct tomoyo_acl_head head;
@@ -637,32 +717,14 @@ struct tomoyo_transition_control {
637 const struct tomoyo_path_info *program; /* Maybe NULL */ 717 const struct tomoyo_path_info *program; /* Maybe NULL */
638}; 718};
639 719
640/* 720/* Structure for "aggregator" keyword. */
641 * tomoyo_aggregator is a structure which is used for holding
642 * "aggregator" entries.
643 * It has following fields.
644 *
645 * (1) "head" is "struct tomoyo_acl_head".
646 * (2) "original_name" which is originally requested name.
647 * (3) "aggregated_name" which is name to rewrite.
648 */
649struct tomoyo_aggregator { 721struct tomoyo_aggregator {
650 struct tomoyo_acl_head head; 722 struct tomoyo_acl_head head;
651 const struct tomoyo_path_info *original_name; 723 const struct tomoyo_path_info *original_name;
652 const struct tomoyo_path_info *aggregated_name; 724 const struct tomoyo_path_info *aggregated_name;
653}; 725};
654 726
655/* 727/* Structure for policy manager. */
656 * tomoyo_manager is a structure which is used for holding list of
657 * domainnames or programs which are permitted to modify configuration via
658 * /sys/kernel/security/tomoyo/ interface.
659 * It has following fields.
660 *
661 * (1) "head" is "struct tomoyo_acl_head".
662 * (2) "is_domain" is a bool which is true if "manager" is a domainname, false
663 * otherwise.
664 * (3) "manager" is a domainname or a program's pathname.
665 */
666struct tomoyo_manager { 728struct tomoyo_manager {
667 struct tomoyo_acl_head head; 729 struct tomoyo_acl_head head;
668 bool is_domain; /* True if manager is a domainname. */ 730 bool is_domain; /* True if manager is a domainname. */
@@ -677,6 +739,7 @@ struct tomoyo_preference {
677 bool permissive_verbose; 739 bool permissive_verbose;
678}; 740};
679 741
742/* Structure for /sys/kernel/security/tomnoyo/profile interface. */
680struct tomoyo_profile { 743struct tomoyo_profile {
681 const struct tomoyo_path_info *comment; 744 const struct tomoyo_path_info *comment;
682 struct tomoyo_preference *learning; 745 struct tomoyo_preference *learning;
@@ -685,323 +748,409 @@ struct tomoyo_profile {
685 struct tomoyo_preference preference; 748 struct tomoyo_preference preference;
686 u8 default_config; 749 u8 default_config;
687 u8 config[TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX]; 750 u8 config[TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX];
751 unsigned int pref[TOMOYO_MAX_PREF];
752};
753
754/* Structure for representing YYYY/MM/DD hh/mm/ss. */
755struct tomoyo_time {
756 u16 year;
757 u8 month;
758 u8 day;
759 u8 hour;
760 u8 min;
761 u8 sec;
762};
763
764/* Structure for policy namespace. */
765struct tomoyo_policy_namespace {
766 /* Profile table. Memory is allocated as needed. */
767 struct tomoyo_profile *profile_ptr[TOMOYO_MAX_PROFILES];
768 /* List of "struct tomoyo_group". */
769 struct list_head group_list[TOMOYO_MAX_GROUP];
770 /* List of policy. */
771 struct list_head policy_list[TOMOYO_MAX_POLICY];
772 /* The global ACL referred by "use_group" keyword. */
773 struct list_head acl_group[TOMOYO_MAX_ACL_GROUPS];
774 /* List for connecting to tomoyo_namespace_list list. */
775 struct list_head namespace_list;
776 /* Profile version. Currently only 20100903 is defined. */
777 unsigned int profile_version;
778 /* Name of this namespace (e.g. "<kernel>", "</usr/sbin/httpd>" ). */
779 const char *name;
688}; 780};
689 781
690/********** Function prototypes. **********/ 782/********** Function prototypes. **********/
691 783
692/* Check whether the given string starts with the given keyword. */
693bool tomoyo_str_starts(char **src, const char *find);
694/* Get tomoyo_realpath() of current process. */
695const char *tomoyo_get_exe(void);
696/* Format string. */
697void tomoyo_normalize_line(unsigned char *buffer);
698/* Print warning or error message on console. */
699void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...)
700 __attribute__ ((format(printf, 2, 3)));
701/* Check all profiles currently assigned to domains are defined. */
702void tomoyo_check_profile(void);
703/* Open operation for /sys/kernel/security/tomoyo/ interface. */
704int tomoyo_open_control(const u8 type, struct file *file);
705/* Close /sys/kernel/security/tomoyo/ interface. */
706int tomoyo_close_control(struct file *file);
707/* Poll operation for /sys/kernel/security/tomoyo/ interface. */
708int tomoyo_poll_control(struct file *file, poll_table *wait);
709/* Read operation for /sys/kernel/security/tomoyo/ interface. */
710int tomoyo_read_control(struct file *file, char __user *buffer,
711 const int buffer_len);
712/* Write operation for /sys/kernel/security/tomoyo/ interface. */
713int tomoyo_write_control(struct file *file, const char __user *buffer,
714 const int buffer_len);
715/* Check whether the domain has too many ACL entries to hold. */
716bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
717/* Print out of memory warning message. */
718void tomoyo_warn_oom(const char *function);
719/* Check whether the given name matches the given name_union. */
720const struct tomoyo_path_info *
721tomoyo_compare_name_union(const struct tomoyo_path_info *name,
722 const struct tomoyo_name_union *ptr);
723/* Check whether the given number matches the given number_union. */
724bool tomoyo_compare_number_union(const unsigned long value, 784bool tomoyo_compare_number_union(const unsigned long value,
725 const struct tomoyo_number_union *ptr); 785 const struct tomoyo_number_union *ptr);
726int tomoyo_get_mode(const u8 profile, const u8 index); 786bool tomoyo_condition(struct tomoyo_request_info *r,
727void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 787 const struct tomoyo_condition *cond);
728 __attribute__ ((format(printf, 2, 3)));
729/* Check whether the domainname is correct. */
730bool tomoyo_correct_domain(const unsigned char *domainname); 788bool tomoyo_correct_domain(const unsigned char *domainname);
731/* Check whether the token is correct. */
732bool tomoyo_correct_path(const char *filename); 789bool tomoyo_correct_path(const char *filename);
733bool tomoyo_correct_word(const char *string); 790bool tomoyo_correct_word(const char *string);
734/* Check whether the token can be a domainname. */
735bool tomoyo_domain_def(const unsigned char *buffer); 791bool tomoyo_domain_def(const unsigned char *buffer);
736bool tomoyo_parse_name_union(const char *filename, 792bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
737 struct tomoyo_name_union *ptr); 793bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
738/* Check whether the given filename matches the given path_group. */ 794 struct tomoyo_page_dump *dump);
739const struct tomoyo_path_info * 795bool tomoyo_memory_ok(void *ptr);
740tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
741 const struct tomoyo_group *group);
742/* Check whether the given value matches the given number_group. */
743bool tomoyo_number_matches_group(const unsigned long min, 796bool tomoyo_number_matches_group(const unsigned long min,
744 const unsigned long max, 797 const unsigned long max,
745 const struct tomoyo_group *group); 798 const struct tomoyo_group *group);
746/* Check whether the given filename matches the given pattern. */ 799bool tomoyo_parse_name_union(struct tomoyo_acl_param *param,
800 struct tomoyo_name_union *ptr);
801bool tomoyo_parse_number_union(struct tomoyo_acl_param *param,
802 struct tomoyo_number_union *ptr);
747bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, 803bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
748 const struct tomoyo_path_info *pattern); 804 const struct tomoyo_path_info *pattern);
749 805bool tomoyo_permstr(const char *string, const char *keyword);
750bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num); 806bool tomoyo_str_starts(char **src, const char *find);
751/* Tokenize a line. */
752bool tomoyo_tokenize(char *buffer, char *w[], size_t size);
753/* Write domain policy violation warning message to console? */
754bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain);
755/* Fill "struct tomoyo_request_info". */
756int tomoyo_init_request_info(struct tomoyo_request_info *r,
757 struct tomoyo_domain_info *domain,
758 const u8 index);
759/* Check permission for mount operation. */
760int tomoyo_mount_permission(char *dev_name, struct path *path, char *type,
761 unsigned long flags, void *data_page);
762/* Create "aggregator" entry in exception policy. */
763int tomoyo_write_aggregator(char *data, const bool is_delete);
764int tomoyo_write_transition_control(char *data, const bool is_delete,
765 const u8 type);
766/*
767 * Create "allow_read/write", "allow_execute", "allow_read", "allow_write",
768 * "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir",
769 * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar",
770 * "allow_truncate", "allow_symlink", "allow_rewrite", "allow_rename" and
771 * "allow_link" entry in domain policy.
772 */
773int tomoyo_write_file(char *data, struct tomoyo_domain_info *domain,
774 const bool is_delete);
775/* Create "allow_read" entry in exception policy. */
776int tomoyo_write_globally_readable(char *data, const bool is_delete);
777/* Create "allow_mount" entry in domain policy. */
778int tomoyo_write_mount(char *data, struct tomoyo_domain_info *domain,
779 const bool is_delete);
780/* Create "deny_rewrite" entry in exception policy. */
781int tomoyo_write_no_rewrite(char *data, const bool is_delete);
782/* Create "file_pattern" entry in exception policy. */
783int tomoyo_write_pattern(char *data, const bool is_delete);
784/* Create "path_group"/"number_group" entry in exception policy. */
785int tomoyo_write_group(char *data, const bool is_delete, const u8 type);
786int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
787 __attribute__ ((format(printf, 2, 3)));
788/* Find a domain by the given name. */
789struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
790/* Find or create a domain by the given name. */
791struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
792 const u8 profile);
793struct tomoyo_profile *tomoyo_profile(const u8 profile);
794/*
795 * Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group".
796 */
797struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 type);
798
799/* Check mode for specified functionality. */
800unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
801 const u8 index);
802/* Fill in "struct tomoyo_path_info" members. */
803void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
804/* Run policy loader when /sbin/init starts. */
805void tomoyo_load_policy(const char *filename);
806
807void tomoyo_put_number_union(struct tomoyo_number_union *ptr);
808
809/* Convert binary string to ascii string. */
810char *tomoyo_encode(const char *str); 807char *tomoyo_encode(const char *str);
811 808char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
812/* 809 va_list args);
813 * Returns realpath(3) of the given pathname except that 810char *tomoyo_read_token(struct tomoyo_acl_param *param);
814 * ignores chroot'ed root and does not follow the final symlink.
815 */
816char *tomoyo_realpath_nofollow(const char *pathname);
817/*
818 * Returns realpath(3) of the given pathname except that
819 * ignores chroot'ed root and the pathname is already solved.
820 */
821char *tomoyo_realpath_from_path(struct path *path); 811char *tomoyo_realpath_from_path(struct path *path);
822/* Get patterned pathname. */ 812char *tomoyo_realpath_nofollow(const char *pathname);
823const char *tomoyo_pattern(const struct tomoyo_path_info *filename); 813const char *tomoyo_get_exe(void);
824 814const char *tomoyo_yesno(const unsigned int value);
825/* Check memory quota. */ 815const struct tomoyo_path_info *tomoyo_compare_name_union
826bool tomoyo_memory_ok(void *ptr); 816(const struct tomoyo_path_info *name, const struct tomoyo_name_union *ptr);
827void *tomoyo_commit_ok(void *data, const unsigned int size);
828
829/*
830 * Keep the given name on the RAM.
831 * The RAM is shared, so NEVER try to modify or kfree() the returned name.
832 */
833const struct tomoyo_path_info *tomoyo_get_name(const char *name); 817const struct tomoyo_path_info *tomoyo_get_name(const char *name);
834 818const struct tomoyo_path_info *tomoyo_path_matches_group
835/* Check for memory usage. */ 819(const struct tomoyo_path_info *pathname, const struct tomoyo_group *group);
836void tomoyo_read_memory_counter(struct tomoyo_io_buffer *head);
837
838/* Set memory quota. */
839int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head);
840
841/* Initialize mm related code. */
842void __init tomoyo_mm_init(void);
843int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
844 const struct tomoyo_path_info *filename);
845int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, 820int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
846 struct path *path, const int flag); 821 struct path *path, const int flag);
847int tomoyo_path_number_perm(const u8 operation, struct path *path, 822int tomoyo_close_control(struct tomoyo_io_buffer *head);
848 unsigned long number); 823int tomoyo_find_next_domain(struct linux_binprm *bprm);
824int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
825 const u8 index);
826int tomoyo_init_request_info(struct tomoyo_request_info *r,
827 struct tomoyo_domain_info *domain,
828 const u8 index);
849int tomoyo_mkdev_perm(const u8 operation, struct path *path, 829int tomoyo_mkdev_perm(const u8 operation, struct path *path,
850 const unsigned int mode, unsigned int dev); 830 const unsigned int mode, unsigned int dev);
851int tomoyo_path_perm(const u8 operation, struct path *path); 831int tomoyo_mount_permission(char *dev_name, struct path *path,
832 const char *type, unsigned long flags,
833 void *data_page);
834int tomoyo_open_control(const u8 type, struct file *file);
852int tomoyo_path2_perm(const u8 operation, struct path *path1, 835int tomoyo_path2_perm(const u8 operation, struct path *path1,
853 struct path *path2); 836 struct path *path2);
854int tomoyo_find_next_domain(struct linux_binprm *bprm); 837int tomoyo_path_number_perm(const u8 operation, struct path *path,
855 838 unsigned long number);
856void tomoyo_print_ulong(char *buffer, const int buffer_len, 839int tomoyo_path_perm(const u8 operation, struct path *path,
857 const unsigned long value, const u8 type); 840 const char *target);
858 841int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
859/* Drop refcount on tomoyo_name_union. */ 842 const struct tomoyo_path_info *filename);
860void tomoyo_put_name_union(struct tomoyo_name_union *ptr); 843int tomoyo_poll_control(struct file *file, poll_table *wait);
861 844int tomoyo_poll_log(struct file *file, poll_table *wait);
862/* Run garbage collector. */ 845int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
863void tomoyo_run_gc(void); 846 __printf(2, 3);
864
865void tomoyo_memory_free(void *ptr);
866
867int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, 847int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
868 bool is_delete, struct tomoyo_domain_info *domain, 848 struct tomoyo_acl_param *param,
869 bool (*check_duplicate) (const struct tomoyo_acl_info 849 bool (*check_duplicate)
870 *, 850 (const struct tomoyo_acl_info *,
871 const struct tomoyo_acl_info 851 const struct tomoyo_acl_info *),
872 *), 852 bool (*merge_duplicate)
873 bool (*merge_duplicate) (struct tomoyo_acl_info *, 853 (struct tomoyo_acl_info *, struct tomoyo_acl_info *,
874 struct tomoyo_acl_info *, 854 const bool));
875 const bool));
876int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size, 855int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
877 bool is_delete, struct list_head *list, 856 struct tomoyo_acl_param *param,
878 bool (*check_duplicate) (const struct tomoyo_acl_head 857 bool (*check_duplicate)
879 *, 858 (const struct tomoyo_acl_head *,
880 const struct tomoyo_acl_head 859 const struct tomoyo_acl_head *));
881 *)); 860int tomoyo_write_aggregator(struct tomoyo_acl_param *param);
861int tomoyo_write_file(struct tomoyo_acl_param *param);
862int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type);
863int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
864 const u8 type);
865ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
866 const int buffer_len);
867ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
868 const char __user *buffer, const int buffer_len);
869struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param);
870struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
871 const bool transit);
872struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
873struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
874 const u8 idx);
875struct tomoyo_policy_namespace *tomoyo_assign_namespace
876(const char *domainname);
877struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns,
878 const u8 profile);
879unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
880 const u8 index);
881u8 tomoyo_parse_ulong(unsigned long *result, char **str);
882void *tomoyo_commit_ok(void *data, const unsigned int size);
883void __init tomoyo_load_builtin_policy(void);
884void __init tomoyo_mm_init(void);
882void tomoyo_check_acl(struct tomoyo_request_info *r, 885void tomoyo_check_acl(struct tomoyo_request_info *r,
883 bool (*check_entry) (struct tomoyo_request_info *, 886 bool (*check_entry) (struct tomoyo_request_info *,
884 const struct tomoyo_acl_info *)); 887 const struct tomoyo_acl_info *));
888void tomoyo_check_profile(void);
889void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp);
890void tomoyo_del_condition(struct list_head *element);
891void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
892void tomoyo_get_attributes(struct tomoyo_obj_info *obj);
893void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns);
894void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
895 __printf(2, 3);
896void tomoyo_load_policy(const char *filename);
897void tomoyo_memory_free(void *ptr);
898void tomoyo_normalize_line(unsigned char *buffer);
899void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register);
900void tomoyo_print_ulong(char *buffer, const int buffer_len,
901 const unsigned long value, const u8 type);
902void tomoyo_put_name_union(struct tomoyo_name_union *ptr);
903void tomoyo_put_number_union(struct tomoyo_number_union *ptr);
904void tomoyo_read_log(struct tomoyo_io_buffer *head);
905void tomoyo_update_stat(const u8 index);
906void tomoyo_warn_oom(const char *function);
907void tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...)
908 __printf(2, 3);
909void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
910 va_list args);
885 911
886/********** External variable definitions. **********/ 912/********** External variable definitions. **********/
887 913
888/* Lock for GC. */ 914extern bool tomoyo_policy_loaded;
889extern struct srcu_struct tomoyo_ss; 915extern const char * const tomoyo_condition_keyword
890 916[TOMOYO_MAX_CONDITION_KEYWORD];
891/* The list for "struct tomoyo_domain_info". */ 917extern const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS];
918extern const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
919 + TOMOYO_MAX_MAC_CATEGORY_INDEX];
920extern const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE];
921extern const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION];
922extern const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX];
923extern const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION];
924extern const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION];
925extern const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION];
926extern struct list_head tomoyo_condition_list;
892extern struct list_head tomoyo_domain_list; 927extern struct list_head tomoyo_domain_list;
893
894extern struct list_head tomoyo_policy_list[TOMOYO_MAX_POLICY];
895extern struct list_head tomoyo_group_list[TOMOYO_MAX_GROUP];
896extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 928extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
897 929extern struct list_head tomoyo_namespace_list;
898/* Lock for protecting policy. */
899extern struct mutex tomoyo_policy_lock; 930extern struct mutex tomoyo_policy_lock;
900 931extern struct srcu_struct tomoyo_ss;
901/* Has /sbin/init started? */
902extern bool tomoyo_policy_loaded;
903
904/* The kernel's domain. */
905extern struct tomoyo_domain_info tomoyo_kernel_domain; 932extern struct tomoyo_domain_info tomoyo_kernel_domain;
906 933extern struct tomoyo_policy_namespace tomoyo_kernel_namespace;
907extern const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION]; 934extern unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
908extern const char *tomoyo_mkdev_keyword[TOMOYO_MAX_MKDEV_OPERATION]; 935extern unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
909extern const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION];
910extern const char *tomoyo_path_number_keyword[TOMOYO_MAX_PATH_NUMBER_OPERATION];
911
912extern unsigned int tomoyo_quota_for_query;
913extern unsigned int tomoyo_query_memory_size;
914 936
915/********** Inlined functions. **********/ 937/********** Inlined functions. **********/
916 938
939/**
940 * tomoyo_read_lock - Take lock for protecting policy.
941 *
942 * Returns index number for tomoyo_read_unlock().
943 */
917static inline int tomoyo_read_lock(void) 944static inline int tomoyo_read_lock(void)
918{ 945{
919 return srcu_read_lock(&tomoyo_ss); 946 return srcu_read_lock(&tomoyo_ss);
920} 947}
921 948
949/**
950 * tomoyo_read_unlock - Release lock for protecting policy.
951 *
952 * @idx: Index number returned by tomoyo_read_lock().
953 *
954 * Returns nothing.
955 */
922static inline void tomoyo_read_unlock(int idx) 956static inline void tomoyo_read_unlock(int idx)
923{ 957{
924 srcu_read_unlock(&tomoyo_ss, idx); 958 srcu_read_unlock(&tomoyo_ss, idx);
925} 959}
926 960
927/* strcmp() for "struct tomoyo_path_info" structure. */ 961/**
928static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a, 962 * tomoyo_sys_getppid - Copy of getppid().
929 const struct tomoyo_path_info *b) 963 *
964 * Returns parent process's PID.
965 *
966 * Alpha does not have getppid() defined. To be able to build this module on
967 * Alpha, I have to copy getppid() from kernel/timer.c.
968 */
969static inline pid_t tomoyo_sys_getppid(void)
930{ 970{
931 return a->hash != b->hash || strcmp(a->name, b->name); 971 pid_t pid;
972 rcu_read_lock();
973 pid = task_tgid_vnr(current->real_parent);
974 rcu_read_unlock();
975 return pid;
932} 976}
933 977
934/** 978/**
935 * tomoyo_valid - Check whether the character is a valid char. 979 * tomoyo_sys_getpid - Copy of getpid().
936 * 980 *
937 * @c: The character to check. 981 * Returns current thread's PID.
938 * 982 *
939 * Returns true if @c is a valid character, false otherwise. 983 * Alpha does not have getpid() defined. To be able to build this module on
984 * Alpha, I have to copy getpid() from kernel/timer.c.
940 */ 985 */
941static inline bool tomoyo_valid(const unsigned char c) 986static inline pid_t tomoyo_sys_getpid(void)
942{ 987{
943 return c > ' ' && c < 127; 988 return task_tgid_vnr(current);
944} 989}
945 990
946/** 991/**
947 * tomoyo_invalid - Check whether the character is an invalid char. 992 * tomoyo_pathcmp - strcmp() for "struct tomoyo_path_info" structure.
948 * 993 *
949 * @c: The character to check. 994 * @a: Pointer to "struct tomoyo_path_info".
995 * @b: Pointer to "struct tomoyo_path_info".
950 * 996 *
951 * Returns true if @c is an invalid character, false otherwise. 997 * Returns true if @a == @b, false otherwise.
952 */ 998 */
953static inline bool tomoyo_invalid(const unsigned char c) 999static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a,
1000 const struct tomoyo_path_info *b)
954{ 1001{
955 return c && (c <= ' ' || c >= 127); 1002 return a->hash != b->hash || strcmp(a->name, b->name);
956} 1003}
957 1004
1005/**
1006 * tomoyo_put_name - Drop reference on "struct tomoyo_name".
1007 *
1008 * @name: Pointer to "struct tomoyo_path_info". Maybe NULL.
1009 *
1010 * Returns nothing.
1011 */
958static inline void tomoyo_put_name(const struct tomoyo_path_info *name) 1012static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
959{ 1013{
960 if (name) { 1014 if (name) {
961 struct tomoyo_name *ptr = 1015 struct tomoyo_name *ptr =
962 container_of(name, typeof(*ptr), entry); 1016 container_of(name, typeof(*ptr), entry);
963 atomic_dec(&ptr->users); 1017 atomic_dec(&ptr->head.users);
964 } 1018 }
965} 1019}
966 1020
1021/**
1022 * tomoyo_put_condition - Drop reference on "struct tomoyo_condition".
1023 *
1024 * @cond: Pointer to "struct tomoyo_condition". Maybe NULL.
1025 *
1026 * Returns nothing.
1027 */
1028static inline void tomoyo_put_condition(struct tomoyo_condition *cond)
1029{
1030 if (cond)
1031 atomic_dec(&cond->head.users);
1032}
1033
1034/**
1035 * tomoyo_put_group - Drop reference on "struct tomoyo_group".
1036 *
1037 * @group: Pointer to "struct tomoyo_group". Maybe NULL.
1038 *
1039 * Returns nothing.
1040 */
967static inline void tomoyo_put_group(struct tomoyo_group *group) 1041static inline void tomoyo_put_group(struct tomoyo_group *group)
968{ 1042{
969 if (group) 1043 if (group)
970 atomic_dec(&group->users); 1044 atomic_dec(&group->head.users);
971} 1045}
972 1046
1047/**
1048 * tomoyo_domain - Get "struct tomoyo_domain_info" for current thread.
1049 *
1050 * Returns pointer to "struct tomoyo_domain_info" for current thread.
1051 */
973static inline struct tomoyo_domain_info *tomoyo_domain(void) 1052static inline struct tomoyo_domain_info *tomoyo_domain(void)
974{ 1053{
975 return current_cred()->security; 1054 return current_cred()->security;
976} 1055}
977 1056
1057/**
1058 * tomoyo_real_domain - Get "struct tomoyo_domain_info" for specified thread.
1059 *
1060 * @task: Pointer to "struct task_struct".
1061 *
1062 * Returns pointer to "struct tomoyo_security" for specified thread.
1063 */
978static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct 1064static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
979 *task) 1065 *task)
980{ 1066{
981 return task_cred_xxx(task, security); 1067 return task_cred_xxx(task, security);
982} 1068}
983 1069
984static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *p1, 1070/**
985 const struct tomoyo_acl_info *p2) 1071 * tomoyo_same_name_union - Check for duplicated "struct tomoyo_name_union" entry.
1072 *
1073 * @a: Pointer to "struct tomoyo_name_union".
1074 * @b: Pointer to "struct tomoyo_name_union".
1075 *
1076 * Returns true if @a == @b, false otherwise.
1077 */
1078static inline bool tomoyo_same_name_union
1079(const struct tomoyo_name_union *a, const struct tomoyo_name_union *b)
986{ 1080{
987 return p1->type == p2->type; 1081 return a->filename == b->filename && a->group == b->group;
988} 1082}
989 1083
990static inline bool tomoyo_same_name_union 1084/**
991(const struct tomoyo_name_union *p1, const struct tomoyo_name_union *p2) 1085 * tomoyo_same_number_union - Check for duplicated "struct tomoyo_number_union" entry.
1086 *
1087 * @a: Pointer to "struct tomoyo_number_union".
1088 * @b: Pointer to "struct tomoyo_number_union".
1089 *
1090 * Returns true if @a == @b, false otherwise.
1091 */
1092static inline bool tomoyo_same_number_union
1093(const struct tomoyo_number_union *a, const struct tomoyo_number_union *b)
992{ 1094{
993 return p1->filename == p2->filename && p1->group == p2->group && 1095 return a->values[0] == b->values[0] && a->values[1] == b->values[1] &&
994 p1->is_group == p2->is_group; 1096 a->group == b->group && a->value_type[0] == b->value_type[0] &&
1097 a->value_type[1] == b->value_type[1];
995} 1098}
996 1099
997static inline bool tomoyo_same_number_union 1100/**
998(const struct tomoyo_number_union *p1, const struct tomoyo_number_union *p2) 1101 * tomoyo_current_namespace - Get "struct tomoyo_policy_namespace" for current thread.
1102 *
1103 * Returns pointer to "struct tomoyo_policy_namespace" for current thread.
1104 */
1105static inline struct tomoyo_policy_namespace *tomoyo_current_namespace(void)
1106{
1107 return tomoyo_domain()->ns;
1108}
1109
1110#if defined(CONFIG_SLOB)
1111
1112/**
1113 * tomoyo_round2 - Round up to power of 2 for calculating memory usage.
1114 *
1115 * @size: Size to be rounded up.
1116 *
1117 * Returns @size.
1118 *
1119 * Since SLOB does not round up, this function simply returns @size.
1120 */
1121static inline int tomoyo_round2(size_t size)
1122{
1123 return size;
1124}
1125
1126#else
1127
1128/**
1129 * tomoyo_round2 - Round up to power of 2 for calculating memory usage.
1130 *
1131 * @size: Size to be rounded up.
1132 *
1133 * Returns rounded size.
1134 *
1135 * Strictly speaking, SLAB may be able to allocate (e.g.) 96 bytes instead of
1136 * (e.g.) 128 bytes.
1137 */
1138static inline int tomoyo_round2(size_t size)
999{ 1139{
1000 return p1->values[0] == p2->values[0] && p1->values[1] == p2->values[1] 1140#if PAGE_SIZE == 4096
1001 && p1->group == p2->group && p1->min_type == p2->min_type && 1141 size_t bsize = 32;
1002 p1->max_type == p2->max_type && p1->is_group == p2->is_group; 1142#else
1143 size_t bsize = 64;
1144#endif
1145 if (!size)
1146 return 0;
1147 while (size > bsize)
1148 bsize <<= 1;
1149 return bsize;
1003} 1150}
1004 1151
1152#endif
1153
1005/** 1154/**
1006 * list_for_each_cookie - iterate over a list with cookie. 1155 * list_for_each_cookie - iterate over a list with cookie.
1007 * @pos: the &struct list_head to use as a loop cursor. 1156 * @pos: the &struct list_head to use as a loop cursor.
diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c
new file mode 100644
index 00000000000..8a05f71eaf6
--- /dev/null
+++ b/security/tomoyo/condition.c
@@ -0,0 +1,1035 @@
1/*
2 * security/tomoyo/condition.c
3 *
4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */
6
7#include "common.h"
8#include <linux/slab.h>
9
10/* List of "struct tomoyo_condition". */
11LIST_HEAD(tomoyo_condition_list);
12
13/**
14 * tomoyo_argv - Check argv[] in "struct linux_binbrm".
15 *
16 * @index: Index number of @arg_ptr.
17 * @arg_ptr: Contents of argv[@index].
18 * @argc: Length of @argv.
19 * @argv: Pointer to "struct tomoyo_argv".
20 * @checked: Set to true if @argv[@index] was found.
21 *
22 * Returns true on success, false otherwise.
23 */
24static bool tomoyo_argv(const unsigned int index, const char *arg_ptr,
25 const int argc, const struct tomoyo_argv *argv,
26 u8 *checked)
27{
28 int i;
29 struct tomoyo_path_info arg;
30 arg.name = arg_ptr;
31 for (i = 0; i < argc; argv++, checked++, i++) {
32 bool result;
33 if (index != argv->index)
34 continue;
35 *checked = 1;
36 tomoyo_fill_path_info(&arg);
37 result = tomoyo_path_matches_pattern(&arg, argv->value);
38 if (argv->is_not)
39 result = !result;
40 if (!result)
41 return false;
42 }
43 return true;
44}
45
46/**
47 * tomoyo_envp - Check envp[] in "struct linux_binbrm".
48 *
49 * @env_name: The name of environment variable.
50 * @env_value: The value of environment variable.
51 * @envc: Length of @envp.
52 * @envp: Pointer to "struct tomoyo_envp".
53 * @checked: Set to true if @envp[@env_name] was found.
54 *
55 * Returns true on success, false otherwise.
56 */
57static bool tomoyo_envp(const char *env_name, const char *env_value,
58 const int envc, const struct tomoyo_envp *envp,
59 u8 *checked)
60{
61 int i;
62 struct tomoyo_path_info name;
63 struct tomoyo_path_info value;
64 name.name = env_name;
65 tomoyo_fill_path_info(&name);
66 value.name = env_value;
67 tomoyo_fill_path_info(&value);
68 for (i = 0; i < envc; envp++, checked++, i++) {
69 bool result;
70 if (!tomoyo_path_matches_pattern(&name, envp->name))
71 continue;
72 *checked = 1;
73 if (envp->value) {
74 result = tomoyo_path_matches_pattern(&value,
75 envp->value);
76 if (envp->is_not)
77 result = !result;
78 } else {
79 result = true;
80 if (!envp->is_not)
81 result = !result;
82 }
83 if (!result)
84 return false;
85 }
86 return true;
87}
88
89/**
90 * tomoyo_scan_bprm - Scan "struct linux_binprm".
91 *
92 * @ee: Pointer to "struct tomoyo_execve".
93 * @argc: Length of @argc.
94 * @argv: Pointer to "struct tomoyo_argv".
95 * @envc: Length of @envp.
96 * @envp: Poiner to "struct tomoyo_envp".
97 *
98 * Returns true on success, false otherwise.
99 */
100static bool tomoyo_scan_bprm(struct tomoyo_execve *ee,
101 const u16 argc, const struct tomoyo_argv *argv,
102 const u16 envc, const struct tomoyo_envp *envp)
103{
104 struct linux_binprm *bprm = ee->bprm;
105 struct tomoyo_page_dump *dump = &ee->dump;
106 char *arg_ptr = ee->tmp;
107 int arg_len = 0;
108 unsigned long pos = bprm->p;
109 int offset = pos % PAGE_SIZE;
110 int argv_count = bprm->argc;
111 int envp_count = bprm->envc;
112 bool result = true;
113 u8 local_checked[32];
114 u8 *checked;
115 if (argc + envc <= sizeof(local_checked)) {
116 checked = local_checked;
117 memset(local_checked, 0, sizeof(local_checked));
118 } else {
119 checked = kzalloc(argc + envc, GFP_NOFS);
120 if (!checked)
121 return false;
122 }
123 while (argv_count || envp_count) {
124 if (!tomoyo_dump_page(bprm, pos, dump)) {
125 result = false;
126 goto out;
127 }
128 pos += PAGE_SIZE - offset;
129 while (offset < PAGE_SIZE) {
130 /* Read. */
131 const char *kaddr = dump->data;
132 const unsigned char c = kaddr[offset++];
133 if (c && arg_len < TOMOYO_EXEC_TMPSIZE - 10) {
134 if (c == '\\') {
135 arg_ptr[arg_len++] = '\\';
136 arg_ptr[arg_len++] = '\\';
137 } else if (c > ' ' && c < 127) {
138 arg_ptr[arg_len++] = c;
139 } else {
140 arg_ptr[arg_len++] = '\\';
141 arg_ptr[arg_len++] = (c >> 6) + '0';
142 arg_ptr[arg_len++] =
143 ((c >> 3) & 7) + '0';
144 arg_ptr[arg_len++] = (c & 7) + '0';
145 }
146 } else {
147 arg_ptr[arg_len] = '\0';
148 }
149 if (c)
150 continue;
151 /* Check. */
152 if (argv_count) {
153 if (!tomoyo_argv(bprm->argc - argv_count,
154 arg_ptr, argc, argv,
155 checked)) {
156 result = false;
157 break;
158 }
159 argv_count--;
160 } else if (envp_count) {
161 char *cp = strchr(arg_ptr, '=');
162 if (cp) {
163 *cp = '\0';
164 if (!tomoyo_envp(arg_ptr, cp + 1,
165 envc, envp,
166 checked + argc)) {
167 result = false;
168 break;
169 }
170 }
171 envp_count--;
172 } else {
173 break;
174 }
175 arg_len = 0;
176 }
177 offset = 0;
178 if (!result)
179 break;
180 }
181out:
182 if (result) {
183 int i;
184 /* Check not-yet-checked entries. */
185 for (i = 0; i < argc; i++) {
186 if (checked[i])
187 continue;
188 /*
189 * Return true only if all unchecked indexes in
190 * bprm->argv[] are not matched.
191 */
192 if (argv[i].is_not)
193 continue;
194 result = false;
195 break;
196 }
197 for (i = 0; i < envc; envp++, i++) {
198 if (checked[argc + i])
199 continue;
200 /*
201 * Return true only if all unchecked environ variables
202 * in bprm->envp[] are either undefined or not matched.
203 */
204 if ((!envp->value && !envp->is_not) ||
205 (envp->value && envp->is_not))
206 continue;
207 result = false;
208 break;
209 }
210 }
211 if (checked != local_checked)
212 kfree(checked);
213 return result;
214}
215
216/**
217 * tomoyo_scan_exec_realpath - Check "exec.realpath" parameter of "struct tomoyo_condition".
218 *
219 * @file: Pointer to "struct file".
220 * @ptr: Pointer to "struct tomoyo_name_union".
221 * @match: True if "exec.realpath=", false if "exec.realpath!=".
222 *
223 * Returns true on success, false otherwise.
224 */
225static bool tomoyo_scan_exec_realpath(struct file *file,
226 const struct tomoyo_name_union *ptr,
227 const bool match)
228{
229 bool result;
230 struct tomoyo_path_info exe;
231 if (!file)
232 return false;
233 exe.name = tomoyo_realpath_from_path(&file->f_path);
234 if (!exe.name)
235 return false;
236 tomoyo_fill_path_info(&exe);
237 result = tomoyo_compare_name_union(&exe, ptr);
238 kfree(exe.name);
239 return result == match;
240}
241
242/**
243 * tomoyo_get_dqword - tomoyo_get_name() for a quoted string.
244 *
245 * @start: String to save.
246 *
247 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
248 */
249static const struct tomoyo_path_info *tomoyo_get_dqword(char *start)
250{
251 char *cp = start + strlen(start) - 1;
252 if (cp == start || *start++ != '"' || *cp != '"')
253 return NULL;
254 *cp = '\0';
255 if (*start && !tomoyo_correct_word(start))
256 return NULL;
257 return tomoyo_get_name(start);
258}
259
260/**
261 * tomoyo_parse_name_union_quoted - Parse a quoted word.
262 *
263 * @param: Pointer to "struct tomoyo_acl_param".
264 * @ptr: Pointer to "struct tomoyo_name_union".
265 *
266 * Returns true on success, false otherwise.
267 */
268static bool tomoyo_parse_name_union_quoted(struct tomoyo_acl_param *param,
269 struct tomoyo_name_union *ptr)
270{
271 char *filename = param->data;
272 if (*filename == '@')
273 return tomoyo_parse_name_union(param, ptr);
274 ptr->filename = tomoyo_get_dqword(filename);
275 return ptr->filename != NULL;
276}
277
278/**
279 * tomoyo_parse_argv - Parse an argv[] condition part.
280 *
281 * @left: Lefthand value.
282 * @right: Righthand value.
283 * @argv: Pointer to "struct tomoyo_argv".
284 *
285 * Returns true on success, false otherwise.
286 */
287static bool tomoyo_parse_argv(char *left, char *right,
288 struct tomoyo_argv *argv)
289{
290 if (tomoyo_parse_ulong(&argv->index, &left) !=
291 TOMOYO_VALUE_TYPE_DECIMAL || *left++ != ']' || *left)
292 return false;
293 argv->value = tomoyo_get_dqword(right);
294 return argv->value != NULL;
295}
296
297/**
298 * tomoyo_parse_envp - Parse an envp[] condition part.
299 *
300 * @left: Lefthand value.
301 * @right: Righthand value.
302 * @envp: Pointer to "struct tomoyo_envp".
303 *
304 * Returns true on success, false otherwise.
305 */
306static bool tomoyo_parse_envp(char *left, char *right,
307 struct tomoyo_envp *envp)
308{
309 const struct tomoyo_path_info *name;
310 const struct tomoyo_path_info *value;
311 char *cp = left + strlen(left) - 1;
312 if (*cp-- != ']' || *cp != '"')
313 goto out;
314 *cp = '\0';
315 if (!tomoyo_correct_word(left))
316 goto out;
317 name = tomoyo_get_name(left);
318 if (!name)
319 goto out;
320 if (!strcmp(right, "NULL")) {
321 value = NULL;
322 } else {
323 value = tomoyo_get_dqword(right);
324 if (!value) {
325 tomoyo_put_name(name);
326 goto out;
327 }
328 }
329 envp->name = name;
330 envp->value = value;
331 return true;
332out:
333 return false;
334}
335
336/**
337 * tomoyo_same_condition - Check for duplicated "struct tomoyo_condition" entry.
338 *
339 * @a: Pointer to "struct tomoyo_condition".
340 * @b: Pointer to "struct tomoyo_condition".
341 *
342 * Returns true if @a == @b, false otherwise.
343 */
344static inline bool tomoyo_same_condition(const struct tomoyo_condition *a,
345 const struct tomoyo_condition *b)
346{
347 return a->size == b->size && a->condc == b->condc &&
348 a->numbers_count == b->numbers_count &&
349 a->names_count == b->names_count &&
350 a->argc == b->argc && a->envc == b->envc &&
351 !memcmp(a + 1, b + 1, a->size - sizeof(*a));
352}
353
354/**
355 * tomoyo_condition_type - Get condition type.
356 *
357 * @word: Keyword string.
358 *
359 * Returns one of values in "enum tomoyo_conditions_index" on success,
360 * TOMOYO_MAX_CONDITION_KEYWORD otherwise.
361 */
362static u8 tomoyo_condition_type(const char *word)
363{
364 u8 i;
365 for (i = 0; i < TOMOYO_MAX_CONDITION_KEYWORD; i++) {
366 if (!strcmp(word, tomoyo_condition_keyword[i]))
367 break;
368 }
369 return i;
370}
371
372/* Define this to enable debug mode. */
373/* #define DEBUG_CONDITION */
374
375#ifdef DEBUG_CONDITION
376#define dprintk printk
377#else
378#define dprintk(...) do { } while (0)
379#endif
380
381/**
382 * tomoyo_commit_condition - Commit "struct tomoyo_condition".
383 *
384 * @entry: Pointer to "struct tomoyo_condition".
385 *
386 * Returns pointer to "struct tomoyo_condition" on success, NULL otherwise.
387 *
388 * This function merges duplicated entries. This function returns NULL if
389 * @entry is not duplicated but memory quota for policy has exceeded.
390 */
391static struct tomoyo_condition *tomoyo_commit_condition
392(struct tomoyo_condition *entry)
393{
394 struct tomoyo_condition *ptr;
395 bool found = false;
396 if (mutex_lock_interruptible(&tomoyo_policy_lock)) {
397 dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
398 ptr = NULL;
399 found = true;
400 goto out;
401 }
402 list_for_each_entry_rcu(ptr, &tomoyo_condition_list, head.list) {
403 if (!tomoyo_same_condition(ptr, entry))
404 continue;
405 /* Same entry found. Share this entry. */
406 atomic_inc(&ptr->head.users);
407 found = true;
408 break;
409 }
410 if (!found) {
411 if (tomoyo_memory_ok(entry)) {
412 atomic_set(&entry->head.users, 1);
413 list_add_rcu(&entry->head.list,
414 &tomoyo_condition_list);
415 } else {
416 found = true;
417 ptr = NULL;
418 }
419 }
420 mutex_unlock(&tomoyo_policy_lock);
421out:
422 if (found) {
423 tomoyo_del_condition(&entry->head.list);
424 kfree(entry);
425 entry = ptr;
426 }
427 return entry;
428}
429
430/**
431 * tomoyo_get_condition - Parse condition part.
432 *
433 * @param: Pointer to "struct tomoyo_acl_param".
434 *
435 * Returns pointer to "struct tomoyo_condition" on success, NULL otherwise.
436 */
437struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param)
438{
439 struct tomoyo_condition *entry = NULL;
440 struct tomoyo_condition_element *condp = NULL;
441 struct tomoyo_number_union *numbers_p = NULL;
442 struct tomoyo_name_union *names_p = NULL;
443 struct tomoyo_argv *argv = NULL;
444 struct tomoyo_envp *envp = NULL;
445 struct tomoyo_condition e = { };
446 char * const start_of_string = param->data;
447 char * const end_of_string = start_of_string + strlen(start_of_string);
448 char *pos;
449rerun:
450 pos = start_of_string;
451 while (1) {
452 u8 left = -1;
453 u8 right = -1;
454 char *left_word = pos;
455 char *cp;
456 char *right_word;
457 bool is_not;
458 if (!*left_word)
459 break;
460 /*
461 * Since left-hand condition does not allow use of "path_group"
462 * or "number_group" and environment variable's names do not
463 * accept '=', it is guaranteed that the original line consists
464 * of one or more repetition of $left$operator$right blocks
465 * where "$left is free from '=' and ' '" and "$operator is
466 * either '=' or '!='" and "$right is free from ' '".
467 * Therefore, we can reconstruct the original line at the end
468 * of dry run even if we overwrite $operator with '\0'.
469 */
470 cp = strchr(pos, ' ');
471 if (cp) {
472 *cp = '\0'; /* Will restore later. */
473 pos = cp + 1;
474 } else {
475 pos = "";
476 }
477 right_word = strchr(left_word, '=');
478 if (!right_word || right_word == left_word)
479 goto out;
480 is_not = *(right_word - 1) == '!';
481 if (is_not)
482 *(right_word++ - 1) = '\0'; /* Will restore later. */
483 else if (*(right_word + 1) != '=')
484 *right_word++ = '\0'; /* Will restore later. */
485 else
486 goto out;
487 dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word,
488 is_not ? "!" : "", right_word);
489 if (!strncmp(left_word, "exec.argv[", 10)) {
490 if (!argv) {
491 e.argc++;
492 e.condc++;
493 } else {
494 e.argc--;
495 e.condc--;
496 left = TOMOYO_ARGV_ENTRY;
497 argv->is_not = is_not;
498 if (!tomoyo_parse_argv(left_word + 10,
499 right_word, argv++))
500 goto out;
501 }
502 goto store_value;
503 }
504 if (!strncmp(left_word, "exec.envp[\"", 11)) {
505 if (!envp) {
506 e.envc++;
507 e.condc++;
508 } else {
509 e.envc--;
510 e.condc--;
511 left = TOMOYO_ENVP_ENTRY;
512 envp->is_not = is_not;
513 if (!tomoyo_parse_envp(left_word + 11,
514 right_word, envp++))
515 goto out;
516 }
517 goto store_value;
518 }
519 left = tomoyo_condition_type(left_word);
520 dprintk(KERN_WARNING "%u: <%s> left=%u\n", __LINE__, left_word,
521 left);
522 if (left == TOMOYO_MAX_CONDITION_KEYWORD) {
523 if (!numbers_p) {
524 e.numbers_count++;
525 } else {
526 e.numbers_count--;
527 left = TOMOYO_NUMBER_UNION;
528 param->data = left_word;
529 if (*left_word == '@' ||
530 !tomoyo_parse_number_union(param,
531 numbers_p++))
532 goto out;
533 }
534 }
535 if (!condp)
536 e.condc++;
537 else
538 e.condc--;
539 if (left == TOMOYO_EXEC_REALPATH ||
540 left == TOMOYO_SYMLINK_TARGET) {
541 if (!names_p) {
542 e.names_count++;
543 } else {
544 e.names_count--;
545 right = TOMOYO_NAME_UNION;
546 param->data = right_word;
547 if (!tomoyo_parse_name_union_quoted(param,
548 names_p++))
549 goto out;
550 }
551 goto store_value;
552 }
553 right = tomoyo_condition_type(right_word);
554 if (right == TOMOYO_MAX_CONDITION_KEYWORD) {
555 if (!numbers_p) {
556 e.numbers_count++;
557 } else {
558 e.numbers_count--;
559 right = TOMOYO_NUMBER_UNION;
560 param->data = right_word;
561 if (!tomoyo_parse_number_union(param,
562 numbers_p++))
563 goto out;
564 }
565 }
566store_value:
567 if (!condp) {
568 dprintk(KERN_WARNING "%u: dry_run left=%u right=%u "
569 "match=%u\n", __LINE__, left, right, !is_not);
570 continue;
571 }
572 condp->left = left;
573 condp->right = right;
574 condp->equals = !is_not;
575 dprintk(KERN_WARNING "%u: left=%u right=%u match=%u\n",
576 __LINE__, condp->left, condp->right,
577 condp->equals);
578 condp++;
579 }
580 dprintk(KERN_INFO "%u: cond=%u numbers=%u names=%u ac=%u ec=%u\n",
581 __LINE__, e.condc, e.numbers_count, e.names_count, e.argc,
582 e.envc);
583 if (entry) {
584 BUG_ON(e.names_count | e.numbers_count | e.argc | e.envc |
585 e.condc);
586 return tomoyo_commit_condition(entry);
587 }
588 e.size = sizeof(*entry)
589 + e.condc * sizeof(struct tomoyo_condition_element)
590 + e.numbers_count * sizeof(struct tomoyo_number_union)
591 + e.names_count * sizeof(struct tomoyo_name_union)
592 + e.argc * sizeof(struct tomoyo_argv)
593 + e.envc * sizeof(struct tomoyo_envp);
594 entry = kzalloc(e.size, GFP_NOFS);
595 if (!entry)
596 return NULL;
597 *entry = e;
598 condp = (struct tomoyo_condition_element *) (entry + 1);
599 numbers_p = (struct tomoyo_number_union *) (condp + e.condc);
600 names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count);
601 argv = (struct tomoyo_argv *) (names_p + e.names_count);
602 envp = (struct tomoyo_envp *) (argv + e.argc);
603 {
604 bool flag = false;
605 for (pos = start_of_string; pos < end_of_string; pos++) {
606 if (*pos)
607 continue;
608 if (flag) /* Restore " ". */
609 *pos = ' ';
610 else if (*(pos + 1) == '=') /* Restore "!=". */
611 *pos = '!';
612 else /* Restore "=". */
613 *pos = '=';
614 flag = !flag;
615 }
616 }
617 goto rerun;
618out:
619 dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
620 if (entry) {
621 tomoyo_del_condition(&entry->head.list);
622 kfree(entry);
623 }
624 return NULL;
625}
626
627/**
628 * tomoyo_get_attributes - Revalidate "struct inode".
629 *
630 * @obj: Pointer to "struct tomoyo_obj_info".
631 *
632 * Returns nothing.
633 */
634void tomoyo_get_attributes(struct tomoyo_obj_info *obj)
635{
636 u8 i;
637 struct dentry *dentry = NULL;
638
639 for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) {
640 struct inode *inode;
641 switch (i) {
642 case TOMOYO_PATH1:
643 dentry = obj->path1.dentry;
644 if (!dentry)
645 continue;
646 break;
647 case TOMOYO_PATH2:
648 dentry = obj->path2.dentry;
649 if (!dentry)
650 continue;
651 break;
652 default:
653 if (!dentry)
654 continue;
655 dentry = dget_parent(dentry);
656 break;
657 }
658 inode = dentry->d_inode;
659 if (inode) {
660 struct tomoyo_mini_stat *stat = &obj->stat[i];
661 stat->uid = inode->i_uid;
662 stat->gid = inode->i_gid;
663 stat->ino = inode->i_ino;
664 stat->mode = inode->i_mode;
665 stat->dev = inode->i_sb->s_dev;
666 stat->rdev = inode->i_rdev;
667 obj->stat_valid[i] = true;
668 }
669 if (i & 1) /* i == TOMOYO_PATH1_PARENT ||
670 i == TOMOYO_PATH2_PARENT */
671 dput(dentry);
672 }
673}
674
675/**
676 * tomoyo_condition - Check condition part.
677 *
678 * @r: Pointer to "struct tomoyo_request_info".
679 * @cond: Pointer to "struct tomoyo_condition". Maybe NULL.
680 *
681 * Returns true on success, false otherwise.
682 *
683 * Caller holds tomoyo_read_lock().
684 */
685bool tomoyo_condition(struct tomoyo_request_info *r,
686 const struct tomoyo_condition *cond)
687{
688 u32 i;
689 unsigned long min_v[2] = { 0, 0 };
690 unsigned long max_v[2] = { 0, 0 };
691 const struct tomoyo_condition_element *condp;
692 const struct tomoyo_number_union *numbers_p;
693 const struct tomoyo_name_union *names_p;
694 const struct tomoyo_argv *argv;
695 const struct tomoyo_envp *envp;
696 struct tomoyo_obj_info *obj;
697 u16 condc;
698 u16 argc;
699 u16 envc;
700 struct linux_binprm *bprm = NULL;
701 if (!cond)
702 return true;
703 condc = cond->condc;
704 argc = cond->argc;
705 envc = cond->envc;
706 obj = r->obj;
707 if (r->ee)
708 bprm = r->ee->bprm;
709 if (!bprm && (argc || envc))
710 return false;
711 condp = (struct tomoyo_condition_element *) (cond + 1);
712 numbers_p = (const struct tomoyo_number_union *) (condp + condc);
713 names_p = (const struct tomoyo_name_union *)
714 (numbers_p + cond->numbers_count);
715 argv = (const struct tomoyo_argv *) (names_p + cond->names_count);
716 envp = (const struct tomoyo_envp *) (argv + argc);
717 for (i = 0; i < condc; i++) {
718 const bool match = condp->equals;
719 const u8 left = condp->left;
720 const u8 right = condp->right;
721 bool is_bitop[2] = { false, false };
722 u8 j;
723 condp++;
724 /* Check argv[] and envp[] later. */
725 if (left == TOMOYO_ARGV_ENTRY || left == TOMOYO_ENVP_ENTRY)
726 continue;
727 /* Check string expressions. */
728 if (right == TOMOYO_NAME_UNION) {
729 const struct tomoyo_name_union *ptr = names_p++;
730 switch (left) {
731 struct tomoyo_path_info *symlink;
732 struct tomoyo_execve *ee;
733 struct file *file;
734 case TOMOYO_SYMLINK_TARGET:
735 symlink = obj ? obj->symlink_target : NULL;
736 if (!symlink ||
737 !tomoyo_compare_name_union(symlink, ptr)
738 == match)
739 goto out;
740 break;
741 case TOMOYO_EXEC_REALPATH:
742 ee = r->ee;
743 file = ee ? ee->bprm->file : NULL;
744 if (!tomoyo_scan_exec_realpath(file, ptr,
745 match))
746 goto out;
747 break;
748 }
749 continue;
750 }
751 /* Check numeric or bit-op expressions. */
752 for (j = 0; j < 2; j++) {
753 const u8 index = j ? right : left;
754 unsigned long value = 0;
755 switch (index) {
756 case TOMOYO_TASK_UID:
757 value = current_uid();
758 break;
759 case TOMOYO_TASK_EUID:
760 value = current_euid();
761 break;
762 case TOMOYO_TASK_SUID:
763 value = current_suid();
764 break;
765 case TOMOYO_TASK_FSUID:
766 value = current_fsuid();
767 break;
768 case TOMOYO_TASK_GID:
769 value = current_gid();
770 break;
771 case TOMOYO_TASK_EGID:
772 value = current_egid();
773 break;
774 case TOMOYO_TASK_SGID:
775 value = current_sgid();
776 break;
777 case TOMOYO_TASK_FSGID:
778 value = current_fsgid();
779 break;
780 case TOMOYO_TASK_PID:
781 value = tomoyo_sys_getpid();
782 break;
783 case TOMOYO_TASK_PPID:
784 value = tomoyo_sys_getppid();
785 break;
786 case TOMOYO_TYPE_IS_SOCKET:
787 value = S_IFSOCK;
788 break;
789 case TOMOYO_TYPE_IS_SYMLINK:
790 value = S_IFLNK;
791 break;
792 case TOMOYO_TYPE_IS_FILE:
793 value = S_IFREG;
794 break;
795 case TOMOYO_TYPE_IS_BLOCK_DEV:
796 value = S_IFBLK;
797 break;
798 case TOMOYO_TYPE_IS_DIRECTORY:
799 value = S_IFDIR;
800 break;
801 case TOMOYO_TYPE_IS_CHAR_DEV:
802 value = S_IFCHR;
803 break;
804 case TOMOYO_TYPE_IS_FIFO:
805 value = S_IFIFO;
806 break;
807 case TOMOYO_MODE_SETUID:
808 value = S_ISUID;
809 break;
810 case TOMOYO_MODE_SETGID:
811 value = S_ISGID;
812 break;
813 case TOMOYO_MODE_STICKY:
814 value = S_ISVTX;
815 break;
816 case TOMOYO_MODE_OWNER_READ:
817 value = S_IRUSR;
818 break;
819 case TOMOYO_MODE_OWNER_WRITE:
820 value = S_IWUSR;
821 break;
822 case TOMOYO_MODE_OWNER_EXECUTE:
823 value = S_IXUSR;
824 break;
825 case TOMOYO_MODE_GROUP_READ:
826 value = S_IRGRP;
827 break;
828 case TOMOYO_MODE_GROUP_WRITE:
829 value = S_IWGRP;
830 break;
831 case TOMOYO_MODE_GROUP_EXECUTE:
832 value = S_IXGRP;
833 break;
834 case TOMOYO_MODE_OTHERS_READ:
835 value = S_IROTH;
836 break;
837 case TOMOYO_MODE_OTHERS_WRITE:
838 value = S_IWOTH;
839 break;
840 case TOMOYO_MODE_OTHERS_EXECUTE:
841 value = S_IXOTH;
842 break;
843 case TOMOYO_EXEC_ARGC:
844 if (!bprm)
845 goto out;
846 value = bprm->argc;
847 break;
848 case TOMOYO_EXEC_ENVC:
849 if (!bprm)
850 goto out;
851 value = bprm->envc;
852 break;
853 case TOMOYO_NUMBER_UNION:
854 /* Fetch values later. */
855 break;
856 default:
857 if (!obj)
858 goto out;
859 if (!obj->validate_done) {
860 tomoyo_get_attributes(obj);
861 obj->validate_done = true;
862 }
863 {
864 u8 stat_index;
865 struct tomoyo_mini_stat *stat;
866 switch (index) {
867 case TOMOYO_PATH1_UID:
868 case TOMOYO_PATH1_GID:
869 case TOMOYO_PATH1_INO:
870 case TOMOYO_PATH1_MAJOR:
871 case TOMOYO_PATH1_MINOR:
872 case TOMOYO_PATH1_TYPE:
873 case TOMOYO_PATH1_DEV_MAJOR:
874 case TOMOYO_PATH1_DEV_MINOR:
875 case TOMOYO_PATH1_PERM:
876 stat_index = TOMOYO_PATH1;
877 break;
878 case TOMOYO_PATH2_UID:
879 case TOMOYO_PATH2_GID:
880 case TOMOYO_PATH2_INO:
881 case TOMOYO_PATH2_MAJOR:
882 case TOMOYO_PATH2_MINOR:
883 case TOMOYO_PATH2_TYPE:
884 case TOMOYO_PATH2_DEV_MAJOR:
885 case TOMOYO_PATH2_DEV_MINOR:
886 case TOMOYO_PATH2_PERM:
887 stat_index = TOMOYO_PATH2;
888 break;
889 case TOMOYO_PATH1_PARENT_UID:
890 case TOMOYO_PATH1_PARENT_GID:
891 case TOMOYO_PATH1_PARENT_INO:
892 case TOMOYO_PATH1_PARENT_PERM:
893 stat_index =
894 TOMOYO_PATH1_PARENT;
895 break;
896 case TOMOYO_PATH2_PARENT_UID:
897 case TOMOYO_PATH2_PARENT_GID:
898 case TOMOYO_PATH2_PARENT_INO:
899 case TOMOYO_PATH2_PARENT_PERM:
900 stat_index =
901 TOMOYO_PATH2_PARENT;
902 break;
903 default:
904 goto out;
905 }
906 if (!obj->stat_valid[stat_index])
907 goto out;
908 stat = &obj->stat[stat_index];
909 switch (index) {
910 case TOMOYO_PATH1_UID:
911 case TOMOYO_PATH2_UID:
912 case TOMOYO_PATH1_PARENT_UID:
913 case TOMOYO_PATH2_PARENT_UID:
914 value = stat->uid;
915 break;
916 case TOMOYO_PATH1_GID:
917 case TOMOYO_PATH2_GID:
918 case TOMOYO_PATH1_PARENT_GID:
919 case TOMOYO_PATH2_PARENT_GID:
920 value = stat->gid;
921 break;
922 case TOMOYO_PATH1_INO:
923 case TOMOYO_PATH2_INO:
924 case TOMOYO_PATH1_PARENT_INO:
925 case TOMOYO_PATH2_PARENT_INO:
926 value = stat->ino;
927 break;
928 case TOMOYO_PATH1_MAJOR:
929 case TOMOYO_PATH2_MAJOR:
930 value = MAJOR(stat->dev);
931 break;
932 case TOMOYO_PATH1_MINOR:
933 case TOMOYO_PATH2_MINOR:
934 value = MINOR(stat->dev);
935 break;
936 case TOMOYO_PATH1_TYPE:
937 case TOMOYO_PATH2_TYPE:
938 value = stat->mode & S_IFMT;
939 break;
940 case TOMOYO_PATH1_DEV_MAJOR:
941 case TOMOYO_PATH2_DEV_MAJOR:
942 value = MAJOR(stat->rdev);
943 break;
944 case TOMOYO_PATH1_DEV_MINOR:
945 case TOMOYO_PATH2_DEV_MINOR:
946 value = MINOR(stat->rdev);
947 break;
948 case TOMOYO_PATH1_PERM:
949 case TOMOYO_PATH2_PERM:
950 case TOMOYO_PATH1_PARENT_PERM:
951 case TOMOYO_PATH2_PARENT_PERM:
952 value = stat->mode & S_IALLUGO;
953 break;
954 }
955 }
956 break;
957 }
958 max_v[j] = value;
959 min_v[j] = value;
960 switch (index) {
961 case TOMOYO_MODE_SETUID:
962 case TOMOYO_MODE_SETGID:
963 case TOMOYO_MODE_STICKY:
964 case TOMOYO_MODE_OWNER_READ:
965 case TOMOYO_MODE_OWNER_WRITE:
966 case TOMOYO_MODE_OWNER_EXECUTE:
967 case TOMOYO_MODE_GROUP_READ:
968 case TOMOYO_MODE_GROUP_WRITE:
969 case TOMOYO_MODE_GROUP_EXECUTE:
970 case TOMOYO_MODE_OTHERS_READ:
971 case TOMOYO_MODE_OTHERS_WRITE:
972 case TOMOYO_MODE_OTHERS_EXECUTE:
973 is_bitop[j] = true;
974 }
975 }
976 if (left == TOMOYO_NUMBER_UNION) {
977 /* Fetch values now. */
978 const struct tomoyo_number_union *ptr = numbers_p++;
979 min_v[0] = ptr->values[0];
980 max_v[0] = ptr->values[1];
981 }
982 if (right == TOMOYO_NUMBER_UNION) {
983 /* Fetch values now. */
984 const struct tomoyo_number_union *ptr = numbers_p++;
985 if (ptr->group) {
986 if (tomoyo_number_matches_group(min_v[0],
987 max_v[0],
988 ptr->group)
989 == match)
990 continue;
991 } else {
992 if ((min_v[0] <= ptr->values[1] &&
993 max_v[0] >= ptr->values[0]) == match)
994 continue;
995 }
996 goto out;
997 }
998 /*
999 * Bit operation is valid only when counterpart value
1000 * represents permission.
1001 */
1002 if (is_bitop[0] && is_bitop[1]) {
1003 goto out;
1004 } else if (is_bitop[0]) {
1005 switch (right) {
1006 case TOMOYO_PATH1_PERM:
1007 case TOMOYO_PATH1_PARENT_PERM:
1008 case TOMOYO_PATH2_PERM:
1009 case TOMOYO_PATH2_PARENT_PERM:
1010 if (!(max_v[0] & max_v[1]) == !match)
1011 continue;
1012 }
1013 goto out;
1014 } else if (is_bitop[1]) {
1015 switch (left) {
1016 case TOMOYO_PATH1_PERM:
1017 case TOMOYO_PATH1_PARENT_PERM:
1018 case TOMOYO_PATH2_PERM:
1019 case TOMOYO_PATH2_PARENT_PERM:
1020 if (!(max_v[0] & max_v[1]) == !match)
1021 continue;
1022 }
1023 goto out;
1024 }
1025 /* Normal value range comparison. */
1026 if ((min_v[0] <= max_v[1] && max_v[0] >= min_v[1]) == match)
1027 continue;
1028out:
1029 return false;
1030 }
1031 /* Check argv[] and envp[] now. */
1032 if (r->ee && (argc || envc))
1033 return tomoyo_scan_bprm(r->ee, argc, argv, envc, envp);
1034 return true;
1035}
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 35388408e47..cd0f92d88bb 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * security/tomoyo/domain.c 2 * security/tomoyo/domain.c
3 * 3 *
4 * Domain transition functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include "common.h" 7#include "common.h"
@@ -20,8 +18,7 @@ struct tomoyo_domain_info tomoyo_kernel_domain;
20 * 18 *
21 * @new_entry: Pointer to "struct tomoyo_acl_info". 19 * @new_entry: Pointer to "struct tomoyo_acl_info".
22 * @size: Size of @new_entry in bytes. 20 * @size: Size of @new_entry in bytes.
23 * @is_delete: True if it is a delete request. 21 * @param: Pointer to "struct tomoyo_acl_param".
24 * @list: Pointer to "struct list_head".
25 * @check_duplicate: Callback function to find duplicated entry. 22 * @check_duplicate: Callback function to find duplicated entry.
26 * 23 *
27 * Returns 0 on success, negative value otherwise. 24 * Returns 0 on success, negative value otherwise.
@@ -29,25 +26,26 @@ struct tomoyo_domain_info tomoyo_kernel_domain;
29 * Caller holds tomoyo_read_lock(). 26 * Caller holds tomoyo_read_lock().
30 */ 27 */
31int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size, 28int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
32 bool is_delete, struct list_head *list, 29 struct tomoyo_acl_param *param,
33 bool (*check_duplicate) (const struct tomoyo_acl_head 30 bool (*check_duplicate) (const struct tomoyo_acl_head
34 *, 31 *,
35 const struct tomoyo_acl_head 32 const struct tomoyo_acl_head
36 *)) 33 *))
37{ 34{
38 int error = is_delete ? -ENOENT : -ENOMEM; 35 int error = param->is_delete ? -ENOENT : -ENOMEM;
39 struct tomoyo_acl_head *entry; 36 struct tomoyo_acl_head *entry;
37 struct list_head *list = param->list;
40 38
41 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 39 if (mutex_lock_interruptible(&tomoyo_policy_lock))
42 return -ENOMEM; 40 return -ENOMEM;
43 list_for_each_entry_rcu(entry, list, list) { 41 list_for_each_entry_rcu(entry, list, list) {
44 if (!check_duplicate(entry, new_entry)) 42 if (!check_duplicate(entry, new_entry))
45 continue; 43 continue;
46 entry->is_deleted = is_delete; 44 entry->is_deleted = param->is_delete;
47 error = 0; 45 error = 0;
48 break; 46 break;
49 } 47 }
50 if (error && !is_delete) { 48 if (error && !param->is_delete) {
51 entry = tomoyo_commit_ok(new_entry, size); 49 entry = tomoyo_commit_ok(new_entry, size);
52 if (entry) { 50 if (entry) {
53 list_add_tail_rcu(&entry->list, list); 51 list_add_tail_rcu(&entry->list, list);
@@ -59,12 +57,25 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
59} 57}
60 58
61/** 59/**
60 * tomoyo_same_acl_head - Check for duplicated "struct tomoyo_acl_info" entry.
61 *
62 * @a: Pointer to "struct tomoyo_acl_info".
63 * @b: Pointer to "struct tomoyo_acl_info".
64 *
65 * Returns true if @a == @b, false otherwise.
66 */
67static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *a,
68 const struct tomoyo_acl_info *b)
69{
70 return a->type == b->type && a->cond == b->cond;
71}
72
73/**
62 * tomoyo_update_domain - Update an entry for domain policy. 74 * tomoyo_update_domain - Update an entry for domain policy.
63 * 75 *
64 * @new_entry: Pointer to "struct tomoyo_acl_info". 76 * @new_entry: Pointer to "struct tomoyo_acl_info".
65 * @size: Size of @new_entry in bytes. 77 * @size: Size of @new_entry in bytes.
66 * @is_delete: True if it is a delete request. 78 * @param: Pointer to "struct tomoyo_acl_param".
67 * @domain: Pointer to "struct tomoyo_domain_info".
68 * @check_duplicate: Callback function to find duplicated entry. 79 * @check_duplicate: Callback function to find duplicated entry.
69 * @merge_duplicate: Callback function to merge duplicated entry. 80 * @merge_duplicate: Callback function to merge duplicated entry.
70 * 81 *
@@ -73,7 +84,7 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
73 * Caller holds tomoyo_read_lock(). 84 * Caller holds tomoyo_read_lock().
74 */ 85 */
75int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, 86int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
76 bool is_delete, struct tomoyo_domain_info *domain, 87 struct tomoyo_acl_param *param,
77 bool (*check_duplicate) (const struct tomoyo_acl_info 88 bool (*check_duplicate) (const struct tomoyo_acl_info
78 *, 89 *,
79 const struct tomoyo_acl_info 90 const struct tomoyo_acl_info
@@ -82,13 +93,21 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
82 struct tomoyo_acl_info *, 93 struct tomoyo_acl_info *,
83 const bool)) 94 const bool))
84{ 95{
96 const bool is_delete = param->is_delete;
85 int error = is_delete ? -ENOENT : -ENOMEM; 97 int error = is_delete ? -ENOENT : -ENOMEM;
86 struct tomoyo_acl_info *entry; 98 struct tomoyo_acl_info *entry;
99 struct list_head * const list = param->list;
87 100
101 if (param->data[0]) {
102 new_entry->cond = tomoyo_get_condition(param);
103 if (!new_entry->cond)
104 return -EINVAL;
105 }
88 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 106 if (mutex_lock_interruptible(&tomoyo_policy_lock))
89 return error; 107 goto out;
90 list_for_each_entry_rcu(entry, &domain->acl_info_list, list) { 108 list_for_each_entry_rcu(entry, list, list) {
91 if (!check_duplicate(entry, new_entry)) 109 if (!tomoyo_same_acl_head(entry, new_entry) ||
110 !check_duplicate(entry, new_entry))
92 continue; 111 continue;
93 if (merge_duplicate) 112 if (merge_duplicate)
94 entry->is_deleted = merge_duplicate(entry, new_entry, 113 entry->is_deleted = merge_duplicate(entry, new_entry,
@@ -101,28 +120,50 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
101 if (error && !is_delete) { 120 if (error && !is_delete) {
102 entry = tomoyo_commit_ok(new_entry, size); 121 entry = tomoyo_commit_ok(new_entry, size);
103 if (entry) { 122 if (entry) {
104 list_add_tail_rcu(&entry->list, &domain->acl_info_list); 123 list_add_tail_rcu(&entry->list, list);
105 error = 0; 124 error = 0;
106 } 125 }
107 } 126 }
108 mutex_unlock(&tomoyo_policy_lock); 127 mutex_unlock(&tomoyo_policy_lock);
128out:
129 tomoyo_put_condition(new_entry->cond);
109 return error; 130 return error;
110} 131}
111 132
133/**
134 * tomoyo_check_acl - Do permission check.
135 *
136 * @r: Pointer to "struct tomoyo_request_info".
137 * @check_entry: Callback function to check type specific parameters.
138 *
139 * Returns 0 on success, negative value otherwise.
140 *
141 * Caller holds tomoyo_read_lock().
142 */
112void tomoyo_check_acl(struct tomoyo_request_info *r, 143void tomoyo_check_acl(struct tomoyo_request_info *r,
113 bool (*check_entry) (struct tomoyo_request_info *, 144 bool (*check_entry) (struct tomoyo_request_info *,
114 const struct tomoyo_acl_info *)) 145 const struct tomoyo_acl_info *))
115{ 146{
116 const struct tomoyo_domain_info *domain = r->domain; 147 const struct tomoyo_domain_info *domain = r->domain;
117 struct tomoyo_acl_info *ptr; 148 struct tomoyo_acl_info *ptr;
149 bool retried = false;
150 const struct list_head *list = &domain->acl_info_list;
118 151
119 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 152retry:
153 list_for_each_entry_rcu(ptr, list, list) {
120 if (ptr->is_deleted || ptr->type != r->param_type) 154 if (ptr->is_deleted || ptr->type != r->param_type)
121 continue; 155 continue;
122 if (check_entry(r, ptr)) { 156 if (!check_entry(r, ptr))
123 r->granted = true; 157 continue;
124 return; 158 if (!tomoyo_condition(r, ptr->cond))
125 } 159 continue;
160 r->granted = true;
161 return;
162 }
163 if (!retried) {
164 retried = true;
165 list = &domain->ns->acl_group[domain->group];
166 goto retry;
126 } 167 }
127 r->granted = false; 168 r->granted = false;
128} 169}
@@ -130,24 +171,29 @@ void tomoyo_check_acl(struct tomoyo_request_info *r,
130/* The list for "struct tomoyo_domain_info". */ 171/* The list for "struct tomoyo_domain_info". */
131LIST_HEAD(tomoyo_domain_list); 172LIST_HEAD(tomoyo_domain_list);
132 173
133struct list_head tomoyo_policy_list[TOMOYO_MAX_POLICY];
134struct list_head tomoyo_group_list[TOMOYO_MAX_GROUP];
135
136/** 174/**
137 * tomoyo_last_word - Get last component of a domainname. 175 * tomoyo_last_word - Get last component of a domainname.
138 * 176 *
139 * @domainname: Domainname to check. 177 * @name: Domainname to check.
140 * 178 *
141 * Returns the last word of @domainname. 179 * Returns the last word of @domainname.
142 */ 180 */
143static const char *tomoyo_last_word(const char *name) 181static const char *tomoyo_last_word(const char *name)
144{ 182{
145 const char *cp = strrchr(name, ' '); 183 const char *cp = strrchr(name, ' ');
146 if (cp) 184 if (cp)
147 return cp + 1; 185 return cp + 1;
148 return name; 186 return name;
149} 187}
150 188
189/**
190 * tomoyo_same_transition_control - Check for duplicated "struct tomoyo_transition_control" entry.
191 *
192 * @a: Pointer to "struct tomoyo_acl_head".
193 * @b: Pointer to "struct tomoyo_acl_head".
194 *
195 * Returns true if @a == @b, false otherwise.
196 */
151static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a, 197static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a,
152 const struct tomoyo_acl_head *b) 198 const struct tomoyo_acl_head *b)
153{ 199{
@@ -163,30 +209,36 @@ static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a,
163} 209}
164 210
165/** 211/**
166 * tomoyo_update_transition_control_entry - Update "struct tomoyo_transition_control" list. 212 * tomoyo_write_transition_control - Write "struct tomoyo_transition_control" list.
167 * 213 *
168 * @domainname: The name of domain. Maybe NULL. 214 * @param: Pointer to "struct tomoyo_acl_param".
169 * @program: The name of program. Maybe NULL. 215 * @type: Type of this entry.
170 * @type: Type of transition.
171 * @is_delete: True if it is a delete request.
172 * 216 *
173 * Returns 0 on success, negative value otherwise. 217 * Returns 0 on success, negative value otherwise.
174 */ 218 */
175static int tomoyo_update_transition_control_entry(const char *domainname, 219int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
176 const char *program, 220 const u8 type)
177 const u8 type,
178 const bool is_delete)
179{ 221{
180 struct tomoyo_transition_control e = { .type = type }; 222 struct tomoyo_transition_control e = { .type = type };
181 int error = is_delete ? -ENOENT : -ENOMEM; 223 int error = param->is_delete ? -ENOENT : -ENOMEM;
182 if (program) { 224 char *program = param->data;
225 char *domainname = strstr(program, " from ");
226 if (domainname) {
227 *domainname = '\0';
228 domainname += 6;
229 } else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP ||
230 type == TOMOYO_TRANSITION_CONTROL_KEEP) {
231 domainname = program;
232 program = NULL;
233 }
234 if (program && strcmp(program, "any")) {
183 if (!tomoyo_correct_path(program)) 235 if (!tomoyo_correct_path(program))
184 return -EINVAL; 236 return -EINVAL;
185 e.program = tomoyo_get_name(program); 237 e.program = tomoyo_get_name(program);
186 if (!e.program) 238 if (!e.program)
187 goto out; 239 goto out;
188 } 240 }
189 if (domainname) { 241 if (domainname && strcmp(domainname, "any")) {
190 if (!tomoyo_correct_domain(domainname)) { 242 if (!tomoyo_correct_domain(domainname)) {
191 if (!tomoyo_correct_path(domainname)) 243 if (!tomoyo_correct_path(domainname))
192 goto out; 244 goto out;
@@ -196,126 +248,136 @@ static int tomoyo_update_transition_control_entry(const char *domainname,
196 if (!e.domainname) 248 if (!e.domainname)
197 goto out; 249 goto out;
198 } 250 }
199 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 251 param->list = &param->ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
200 &tomoyo_policy_list 252 error = tomoyo_update_policy(&e.head, sizeof(e), param,
201 [TOMOYO_ID_TRANSITION_CONTROL],
202 tomoyo_same_transition_control); 253 tomoyo_same_transition_control);
203 out: 254out:
204 tomoyo_put_name(e.domainname); 255 tomoyo_put_name(e.domainname);
205 tomoyo_put_name(e.program); 256 tomoyo_put_name(e.program);
206 return error; 257 return error;
207} 258}
208 259
209/** 260/**
210 * tomoyo_write_transition_control - Write "struct tomoyo_transition_control" list. 261 * tomoyo_scan_transition - Try to find specific domain transition type.
211 * 262 *
212 * @data: String to parse. 263 * @list: Pointer to "struct list_head".
213 * @is_delete: True if it is a delete request. 264 * @domainname: The name of current domain.
214 * @type: Type of this entry. 265 * @program: The name of requested program.
266 * @last_name: The last component of @domainname.
267 * @type: One of values in "enum tomoyo_transition_type".
215 * 268 *
216 * Returns 0 on success, negative value otherwise. 269 * Returns true if found one, false otherwise.
270 *
271 * Caller holds tomoyo_read_lock().
217 */ 272 */
218int tomoyo_write_transition_control(char *data, const bool is_delete, 273static inline bool tomoyo_scan_transition
219 const u8 type) 274(const struct list_head *list, const struct tomoyo_path_info *domainname,
275 const struct tomoyo_path_info *program, const char *last_name,
276 const enum tomoyo_transition_type type)
220{ 277{
221 char *domainname = strstr(data, " from "); 278 const struct tomoyo_transition_control *ptr;
222 if (domainname) { 279 list_for_each_entry_rcu(ptr, list, head.list) {
223 *domainname = '\0'; 280 if (ptr->head.is_deleted || ptr->type != type)
224 domainname += 6; 281 continue;
225 } else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP || 282 if (ptr->domainname) {
226 type == TOMOYO_TRANSITION_CONTROL_KEEP) { 283 if (!ptr->is_last_name) {
227 domainname = data; 284 if (ptr->domainname != domainname)
228 data = NULL; 285 continue;
286 } else {
287 /*
288 * Use direct strcmp() since this is
289 * unlikely used.
290 */
291 if (strcmp(ptr->domainname->name, last_name))
292 continue;
293 }
294 }
295 if (ptr->program && tomoyo_pathcmp(ptr->program, program))
296 continue;
297 return true;
229 } 298 }
230 return tomoyo_update_transition_control_entry(domainname, data, type, 299 return false;
231 is_delete);
232} 300}
233 301
234/** 302/**
235 * tomoyo_transition_type - Get domain transition type. 303 * tomoyo_transition_type - Get domain transition type.
236 * 304 *
237 * @domainname: The name of domain. 305 * @ns: Pointer to "struct tomoyo_policy_namespace".
238 * @program: The name of program. 306 * @domainname: The name of current domain.
307 * @program: The name of requested program.
239 * 308 *
240 * Returns TOMOYO_TRANSITION_CONTROL_INITIALIZE if executing @program 309 * Returns TOMOYO_TRANSITION_CONTROL_TRANSIT if executing @program causes
241 * reinitializes domain transition, TOMOYO_TRANSITION_CONTROL_KEEP if executing 310 * domain transition across namespaces, TOMOYO_TRANSITION_CONTROL_INITIALIZE if
242 * @program suppresses domain transition, others otherwise. 311 * executing @program reinitializes domain transition within that namespace,
312 * TOMOYO_TRANSITION_CONTROL_KEEP if executing @program stays at @domainname ,
313 * others otherwise.
243 * 314 *
244 * Caller holds tomoyo_read_lock(). 315 * Caller holds tomoyo_read_lock().
245 */ 316 */
246static u8 tomoyo_transition_type(const struct tomoyo_path_info *domainname, 317static enum tomoyo_transition_type tomoyo_transition_type
247 const struct tomoyo_path_info *program) 318(const struct tomoyo_policy_namespace *ns,
319 const struct tomoyo_path_info *domainname,
320 const struct tomoyo_path_info *program)
248{ 321{
249 const struct tomoyo_transition_control *ptr;
250 const char *last_name = tomoyo_last_word(domainname->name); 322 const char *last_name = tomoyo_last_word(domainname->name);
251 u8 type; 323 enum tomoyo_transition_type type = TOMOYO_TRANSITION_CONTROL_NO_RESET;
252 for (type = 0; type < TOMOYO_MAX_TRANSITION_TYPE; type++) { 324 while (type < TOMOYO_MAX_TRANSITION_TYPE) {
253 next: 325 const struct list_head * const list =
254 list_for_each_entry_rcu(ptr, &tomoyo_policy_list 326 &ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
255 [TOMOYO_ID_TRANSITION_CONTROL], 327 if (!tomoyo_scan_transition(list, domainname, program,
256 head.list) { 328 last_name, type)) {
257 if (ptr->head.is_deleted || ptr->type != type) 329 type++;
258 continue; 330 continue;
259 if (ptr->domainname) {
260 if (!ptr->is_last_name) {
261 if (ptr->domainname != domainname)
262 continue;
263 } else {
264 /*
265 * Use direct strcmp() since this is
266 * unlikely used.
267 */
268 if (strcmp(ptr->domainname->name,
269 last_name))
270 continue;
271 }
272 }
273 if (ptr->program &&
274 tomoyo_pathcmp(ptr->program, program))
275 continue;
276 if (type == TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE) {
277 /*
278 * Do not check for initialize_domain if
279 * no_initialize_domain matched.
280 */
281 type = TOMOYO_TRANSITION_CONTROL_NO_KEEP;
282 goto next;
283 }
284 goto done;
285 } 331 }
332 if (type != TOMOYO_TRANSITION_CONTROL_NO_RESET &&
333 type != TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE)
334 break;
335 /*
336 * Do not check for reset_domain if no_reset_domain matched.
337 * Do not check for initialize_domain if no_initialize_domain
338 * matched.
339 */
340 type++;
341 type++;
286 } 342 }
287 done:
288 return type; 343 return type;
289} 344}
290 345
346/**
347 * tomoyo_same_aggregator - Check for duplicated "struct tomoyo_aggregator" entry.
348 *
349 * @a: Pointer to "struct tomoyo_acl_head".
350 * @b: Pointer to "struct tomoyo_acl_head".
351 *
352 * Returns true if @a == @b, false otherwise.
353 */
291static bool tomoyo_same_aggregator(const struct tomoyo_acl_head *a, 354static bool tomoyo_same_aggregator(const struct tomoyo_acl_head *a,
292 const struct tomoyo_acl_head *b) 355 const struct tomoyo_acl_head *b)
293{ 356{
294 const struct tomoyo_aggregator *p1 = container_of(a, typeof(*p1), head); 357 const struct tomoyo_aggregator *p1 = container_of(a, typeof(*p1),
295 const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2), head); 358 head);
359 const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2),
360 head);
296 return p1->original_name == p2->original_name && 361 return p1->original_name == p2->original_name &&
297 p1->aggregated_name == p2->aggregated_name; 362 p1->aggregated_name == p2->aggregated_name;
298} 363}
299 364
300/** 365/**
301 * tomoyo_update_aggregator_entry - Update "struct tomoyo_aggregator" list. 366 * tomoyo_write_aggregator - Write "struct tomoyo_aggregator" list.
302 * 367 *
303 * @original_name: The original program's name. 368 * @param: Pointer to "struct tomoyo_acl_param".
304 * @aggregated_name: The program name to use.
305 * @is_delete: True if it is a delete request.
306 * 369 *
307 * Returns 0 on success, negative value otherwise. 370 * Returns 0 on success, negative value otherwise.
308 * 371 *
309 * Caller holds tomoyo_read_lock(). 372 * Caller holds tomoyo_read_lock().
310 */ 373 */
311static int tomoyo_update_aggregator_entry(const char *original_name, 374int tomoyo_write_aggregator(struct tomoyo_acl_param *param)
312 const char *aggregated_name,
313 const bool is_delete)
314{ 375{
315 struct tomoyo_aggregator e = { }; 376 struct tomoyo_aggregator e = { };
316 int error = is_delete ? -ENOENT : -ENOMEM; 377 int error = param->is_delete ? -ENOENT : -ENOMEM;
317 378 const char *original_name = tomoyo_read_token(param);
318 if (!tomoyo_correct_path(original_name) || 379 const char *aggregated_name = tomoyo_read_token(param);
380 if (!tomoyo_correct_word(original_name) ||
319 !tomoyo_correct_path(aggregated_name)) 381 !tomoyo_correct_path(aggregated_name))
320 return -EINVAL; 382 return -EINVAL;
321 e.original_name = tomoyo_get_name(original_name); 383 e.original_name = tomoyo_get_name(original_name);
@@ -323,83 +385,181 @@ static int tomoyo_update_aggregator_entry(const char *original_name,
323 if (!e.original_name || !e.aggregated_name || 385 if (!e.original_name || !e.aggregated_name ||
324 e.aggregated_name->is_patterned) /* No patterns allowed. */ 386 e.aggregated_name->is_patterned) /* No patterns allowed. */
325 goto out; 387 goto out;
326 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 388 param->list = &param->ns->policy_list[TOMOYO_ID_AGGREGATOR];
327 &tomoyo_policy_list[TOMOYO_ID_AGGREGATOR], 389 error = tomoyo_update_policy(&e.head, sizeof(e), param,
328 tomoyo_same_aggregator); 390 tomoyo_same_aggregator);
329 out: 391out:
330 tomoyo_put_name(e.original_name); 392 tomoyo_put_name(e.original_name);
331 tomoyo_put_name(e.aggregated_name); 393 tomoyo_put_name(e.aggregated_name);
332 return error; 394 return error;
333} 395}
334 396
335/** 397/**
336 * tomoyo_write_aggregator - Write "struct tomoyo_aggregator" list. 398 * tomoyo_find_namespace - Find specified namespace.
337 * 399 *
338 * @data: String to parse. 400 * @name: Name of namespace to find.
339 * @is_delete: True if it is a delete request. 401 * @len: Length of @name.
340 * 402 *
341 * Returns 0 on success, negative value otherwise. 403 * Returns pointer to "struct tomoyo_policy_namespace" if found,
404 * NULL otherwise.
342 * 405 *
343 * Caller holds tomoyo_read_lock(). 406 * Caller holds tomoyo_read_lock().
344 */ 407 */
345int tomoyo_write_aggregator(char *data, const bool is_delete) 408static struct tomoyo_policy_namespace *tomoyo_find_namespace
409(const char *name, const unsigned int len)
346{ 410{
347 char *cp = strchr(data, ' '); 411 struct tomoyo_policy_namespace *ns;
412 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
413 if (strncmp(name, ns->name, len) ||
414 (name[len] && name[len] != ' '))
415 continue;
416 return ns;
417 }
418 return NULL;
419}
348 420
349 if (!cp) 421/**
350 return -EINVAL; 422 * tomoyo_assign_namespace - Create a new namespace.
351 *cp++ = '\0'; 423 *
352 return tomoyo_update_aggregator_entry(data, cp, is_delete); 424 * @domainname: Name of namespace to create.
425 *
426 * Returns pointer to "struct tomoyo_policy_namespace" on success,
427 * NULL otherwise.
428 *
429 * Caller holds tomoyo_read_lock().
430 */
431struct tomoyo_policy_namespace *tomoyo_assign_namespace(const char *domainname)
432{
433 struct tomoyo_policy_namespace *ptr;
434 struct tomoyo_policy_namespace *entry;
435 const char *cp = domainname;
436 unsigned int len = 0;
437 while (*cp && *cp++ != ' ')
438 len++;
439 ptr = tomoyo_find_namespace(domainname, len);
440 if (ptr)
441 return ptr;
442 if (len >= TOMOYO_EXEC_TMPSIZE - 10 || !tomoyo_domain_def(domainname))
443 return NULL;
444 entry = kzalloc(sizeof(*entry) + len + 1, GFP_NOFS);
445 if (!entry)
446 return NULL;
447 if (mutex_lock_interruptible(&tomoyo_policy_lock))
448 goto out;
449 ptr = tomoyo_find_namespace(domainname, len);
450 if (!ptr && tomoyo_memory_ok(entry)) {
451 char *name = (char *) (entry + 1);
452 ptr = entry;
453 memmove(name, domainname, len);
454 name[len] = '\0';
455 entry->name = name;
456 tomoyo_init_policy_namespace(entry);
457 entry = NULL;
458 }
459 mutex_unlock(&tomoyo_policy_lock);
460out:
461 kfree(entry);
462 return ptr;
353} 463}
354 464
355/** 465/**
356 * tomoyo_assign_domain - Create a domain. 466 * tomoyo_namespace_jump - Check for namespace jump.
467 *
468 * @domainname: Name of domain.
469 *
470 * Returns true if namespace differs, false otherwise.
471 */
472static bool tomoyo_namespace_jump(const char *domainname)
473{
474 const char *namespace = tomoyo_current_namespace()->name;
475 const int len = strlen(namespace);
476 return strncmp(domainname, namespace, len) ||
477 (domainname[len] && domainname[len] != ' ');
478}
479
480/**
481 * tomoyo_assign_domain - Create a domain or a namespace.
357 * 482 *
358 * @domainname: The name of domain. 483 * @domainname: The name of domain.
359 * @profile: Profile number to assign if the domain was newly created. 484 * @transit: True if transit to domain found or created.
360 * 485 *
361 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise. 486 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
362 * 487 *
363 * Caller holds tomoyo_read_lock(). 488 * Caller holds tomoyo_read_lock().
364 */ 489 */
365struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname, 490struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
366 const u8 profile) 491 const bool transit)
367{ 492{
368 struct tomoyo_domain_info *entry; 493 struct tomoyo_domain_info e = { };
369 struct tomoyo_domain_info *domain = NULL; 494 struct tomoyo_domain_info *entry = tomoyo_find_domain(domainname);
370 const struct tomoyo_path_info *saved_domainname; 495 bool created = false;
371 bool found = false; 496 if (entry) {
372 497 if (transit) {
373 if (!tomoyo_correct_domain(domainname)) 498 /*
499 * Since namespace is created at runtime, profiles may
500 * not be created by the moment the process transits to
501 * that domain. Do not perform domain transition if
502 * profile for that domain is not yet created.
503 */
504 if (!entry->ns->profile_ptr[entry->profile])
505 return NULL;
506 }
507 return entry;
508 }
509 /* Requested domain does not exist. */
510 /* Don't create requested domain if domainname is invalid. */
511 if (strlen(domainname) >= TOMOYO_EXEC_TMPSIZE - 10 ||
512 !tomoyo_correct_domain(domainname))
513 return NULL;
514 /*
515 * Since definition of profiles and acl_groups may differ across
516 * namespaces, do not inherit "use_profile" and "use_group" settings
517 * by automatically creating requested domain upon domain transition.
518 */
519 if (transit && tomoyo_namespace_jump(domainname))
520 return NULL;
521 e.ns = tomoyo_assign_namespace(domainname);
522 if (!e.ns)
374 return NULL; 523 return NULL;
375 saved_domainname = tomoyo_get_name(domainname); 524 /*
376 if (!saved_domainname) 525 * "use_profile" and "use_group" settings for automatically created
526 * domains are inherited from current domain. These are 0 for manually
527 * created domains.
528 */
529 if (transit) {
530 const struct tomoyo_domain_info *domain = tomoyo_domain();
531 e.profile = domain->profile;
532 e.group = domain->group;
533 }
534 e.domainname = tomoyo_get_name(domainname);
535 if (!e.domainname)
377 return NULL; 536 return NULL;
378 entry = kzalloc(sizeof(*entry), GFP_NOFS);
379 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 537 if (mutex_lock_interruptible(&tomoyo_policy_lock))
380 goto out; 538 goto out;
381 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 539 entry = tomoyo_find_domain(domainname);
382 if (domain->is_deleted || 540 if (!entry) {
383 tomoyo_pathcmp(saved_domainname, domain->domainname)) 541 entry = tomoyo_commit_ok(&e, sizeof(e));
384 continue; 542 if (entry) {
385 found = true; 543 INIT_LIST_HEAD(&entry->acl_info_list);
386 break; 544 list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
387 } 545 created = true;
388 if (!found && tomoyo_memory_ok(entry)) { 546 }
389 INIT_LIST_HEAD(&entry->acl_info_list);
390 entry->domainname = saved_domainname;
391 saved_domainname = NULL;
392 entry->profile = profile;
393 list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
394 domain = entry;
395 entry = NULL;
396 found = true;
397 } 547 }
398 mutex_unlock(&tomoyo_policy_lock); 548 mutex_unlock(&tomoyo_policy_lock);
399 out: 549out:
400 tomoyo_put_name(saved_domainname); 550 tomoyo_put_name(e.domainname);
401 kfree(entry); 551 if (entry && transit) {
402 return found ? domain : NULL; 552 if (created) {
553 struct tomoyo_request_info r;
554 tomoyo_init_request_info(&r, entry,
555 TOMOYO_MAC_FILE_EXECUTE);
556 r.granted = false;
557 tomoyo_write_log(&r, "use_profile %u\n",
558 entry->profile);
559 tomoyo_write_log(&r, "use_group %u\n", entry->group);
560 }
561 }
562 return entry;
403} 563}
404 564
405/** 565/**
@@ -413,22 +573,27 @@ struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
413 */ 573 */
414int tomoyo_find_next_domain(struct linux_binprm *bprm) 574int tomoyo_find_next_domain(struct linux_binprm *bprm)
415{ 575{
416 struct tomoyo_request_info r;
417 char *tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
418 struct tomoyo_domain_info *old_domain = tomoyo_domain(); 576 struct tomoyo_domain_info *old_domain = tomoyo_domain();
419 struct tomoyo_domain_info *domain = NULL; 577 struct tomoyo_domain_info *domain = NULL;
420 const char *original_name = bprm->filename; 578 const char *original_name = bprm->filename;
421 u8 mode;
422 bool is_enforce;
423 int retval = -ENOMEM; 579 int retval = -ENOMEM;
424 bool need_kfree = false; 580 bool need_kfree = false;
581 bool reject_on_transition_failure = false;
425 struct tomoyo_path_info rn = { }; /* real name */ 582 struct tomoyo_path_info rn = { }; /* real name */
426 583 struct tomoyo_execve *ee = kzalloc(sizeof(*ee), GFP_NOFS);
427 mode = tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE); 584 if (!ee)
428 is_enforce = (mode == TOMOYO_CONFIG_ENFORCING); 585 return -ENOMEM;
429 if (!tmp) 586 ee->tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
430 goto out; 587 if (!ee->tmp) {
431 588 kfree(ee);
589 return -ENOMEM;
590 }
591 /* ee->dump->data is allocated by tomoyo_dump_page(). */
592 tomoyo_init_request_info(&ee->r, NULL, TOMOYO_MAC_FILE_EXECUTE);
593 ee->r.ee = ee;
594 ee->bprm = bprm;
595 ee->r.obj = &ee->obj;
596 ee->obj.path1 = bprm->file->f_path;
432 retry: 597 retry:
433 if (need_kfree) { 598 if (need_kfree) {
434 kfree(rn.name); 599 kfree(rn.name);
@@ -445,8 +610,10 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
445 /* Check 'aggregator' directive. */ 610 /* Check 'aggregator' directive. */
446 { 611 {
447 struct tomoyo_aggregator *ptr; 612 struct tomoyo_aggregator *ptr;
448 list_for_each_entry_rcu(ptr, &tomoyo_policy_list 613 struct list_head *list =
449 [TOMOYO_ID_AGGREGATOR], head.list) { 614 &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR];
615 /* Check 'aggregator' directive. */
616 list_for_each_entry_rcu(ptr, list, head.list) {
450 if (ptr->head.is_deleted || 617 if (ptr->head.is_deleted ||
451 !tomoyo_path_matches_pattern(&rn, 618 !tomoyo_path_matches_pattern(&rn,
452 ptr->original_name)) 619 ptr->original_name))
@@ -460,7 +627,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
460 } 627 }
461 628
462 /* Check execute permission. */ 629 /* Check execute permission. */
463 retval = tomoyo_path_permission(&r, TOMOYO_TYPE_EXECUTE, &rn); 630 retval = tomoyo_path_permission(&ee->r, TOMOYO_TYPE_EXECUTE, &rn);
464 if (retval == TOMOYO_RETRY_REQUEST) 631 if (retval == TOMOYO_RETRY_REQUEST)
465 goto retry; 632 goto retry;
466 if (retval < 0) 633 if (retval < 0)
@@ -471,20 +638,30 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
471 * wildcard) rather than the pathname passed to execve() 638 * wildcard) rather than the pathname passed to execve()
472 * (which never contains wildcard). 639 * (which never contains wildcard).
473 */ 640 */
474 if (r.param.path.matched_path) { 641 if (ee->r.param.path.matched_path) {
475 if (need_kfree) 642 if (need_kfree)
476 kfree(rn.name); 643 kfree(rn.name);
477 need_kfree = false; 644 need_kfree = false;
478 /* This is OK because it is read only. */ 645 /* This is OK because it is read only. */
479 rn = *r.param.path.matched_path; 646 rn = *ee->r.param.path.matched_path;
480 } 647 }
481 648
482 /* Calculate domain to transit to. */ 649 /* Calculate domain to transit to. */
483 switch (tomoyo_transition_type(old_domain->domainname, &rn)) { 650 switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname,
651 &rn)) {
652 case TOMOYO_TRANSITION_CONTROL_RESET:
653 /* Transit to the root of specified namespace. */
654 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>", rn.name);
655 /*
656 * Make do_execve() fail if domain transition across namespaces
657 * has failed.
658 */
659 reject_on_transition_failure = true;
660 break;
484 case TOMOYO_TRANSITION_CONTROL_INITIALIZE: 661 case TOMOYO_TRANSITION_CONTROL_INITIALIZE:
485 /* Transit to the child of tomoyo_kernel_domain domain. */ 662 /* Transit to the child of current namespace's root. */
486 snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, TOMOYO_ROOT_NAME " " 663 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
487 "%s", rn.name); 664 old_domain->ns->name, rn.name);
488 break; 665 break;
489 case TOMOYO_TRANSITION_CONTROL_KEEP: 666 case TOMOYO_TRANSITION_CONTROL_KEEP:
490 /* Keep current domain. */ 667 /* Keep current domain. */
@@ -502,33 +679,32 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
502 domain = old_domain; 679 domain = old_domain;
503 } else { 680 } else {
504 /* Normal domain transition. */ 681 /* Normal domain transition. */
505 snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", 682 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
506 old_domain->domainname->name, rn.name); 683 old_domain->domainname->name, rn.name);
507 } 684 }
508 break; 685 break;
509 } 686 }
510 if (domain || strlen(tmp) >= TOMOYO_EXEC_TMPSIZE - 10) 687 if (!domain)
511 goto done; 688 domain = tomoyo_assign_domain(ee->tmp, true);
512 domain = tomoyo_find_domain(tmp);
513 if (domain) 689 if (domain)
514 goto done; 690 retval = 0;
515 if (is_enforce) { 691 else if (reject_on_transition_failure) {
516 int error = tomoyo_supervisor(&r, "# wants to create domain\n" 692 printk(KERN_WARNING "ERROR: Domain '%s' not ready.\n",
517 "%s\n", tmp); 693 ee->tmp);
518 if (error == TOMOYO_RETRY_REQUEST) 694 retval = -ENOMEM;
519 goto retry; 695 } else if (ee->r.mode == TOMOYO_CONFIG_ENFORCING)
520 if (error < 0) 696 retval = -ENOMEM;
521 goto done; 697 else {
698 retval = 0;
699 if (!old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED]) {
700 old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED] = true;
701 ee->r.granted = false;
702 tomoyo_write_log(&ee->r, "%s", tomoyo_dif
703 [TOMOYO_DIF_TRANSITION_FAILED]);
704 printk(KERN_WARNING
705 "ERROR: Domain '%s' not defined.\n", ee->tmp);
706 }
522 } 707 }
523 domain = tomoyo_assign_domain(tmp, old_domain->profile);
524 done:
525 if (domain)
526 goto out;
527 printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n", tmp);
528 if (is_enforce)
529 retval = -EPERM;
530 else
531 old_domain->transition_failed = true;
532 out: 708 out:
533 if (!domain) 709 if (!domain)
534 domain = old_domain; 710 domain = old_domain;
@@ -537,6 +713,54 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
537 bprm->cred->security = domain; 713 bprm->cred->security = domain;
538 if (need_kfree) 714 if (need_kfree)
539 kfree(rn.name); 715 kfree(rn.name);
540 kfree(tmp); 716 kfree(ee->tmp);
717 kfree(ee->dump.data);
718 kfree(ee);
541 return retval; 719 return retval;
542} 720}
721
722/**
723 * tomoyo_dump_page - Dump a page to buffer.
724 *
725 * @bprm: Pointer to "struct linux_binprm".
726 * @pos: Location to dump.
727 * @dump: Poiner to "struct tomoyo_page_dump".
728 *
729 * Returns true on success, false otherwise.
730 */
731bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
732 struct tomoyo_page_dump *dump)
733{
734 struct page *page;
735 /* dump->data is released by tomoyo_finish_execve(). */
736 if (!dump->data) {
737 dump->data = kzalloc(PAGE_SIZE, GFP_NOFS);
738 if (!dump->data)
739 return false;
740 }
741 /* Same with get_arg_page(bprm, pos, 0) in fs/exec.c */
742#ifdef CONFIG_MMU
743 if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0)
744 return false;
745#else
746 page = bprm->page[pos / PAGE_SIZE];
747#endif
748 if (page != dump->page) {
749 const unsigned int offset = pos % PAGE_SIZE;
750 /*
751 * Maybe kmap()/kunmap() should be used here.
752 * But remove_arg_zero() uses kmap_atomic()/kunmap_atomic().
753 * So do I.
754 */
755 char *kaddr = kmap_atomic(page, KM_USER0);
756 dump->page = page;
757 memcpy(dump->data + offset, kaddr + offset,
758 PAGE_SIZE - offset);
759 kunmap_atomic(kaddr, KM_USER0);
760 }
761 /* Same with put_arg_page(page) in fs/exec.c */
762#ifdef CONFIG_MMU
763 put_page(page);
764#endif
765 return true;
766}
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index d64e8ecb6fb..743c35f5084 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -1,80 +1,51 @@
1/* 1/*
2 * security/tomoyo/file.c 2 * security/tomoyo/file.c
3 * 3 *
4 * Pathname restriction functions. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include "common.h" 7#include "common.h"
10#include <linux/slab.h> 8#include <linux/slab.h>
11 9
12/* Keyword array for operations with one pathname. */ 10/*
13const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = { 11 * Mapping table from "enum tomoyo_path_acl_index" to "enum tomoyo_mac_index".
14 [TOMOYO_TYPE_READ_WRITE] = "read/write", 12 */
15 [TOMOYO_TYPE_EXECUTE] = "execute",
16 [TOMOYO_TYPE_READ] = "read",
17 [TOMOYO_TYPE_WRITE] = "write",
18 [TOMOYO_TYPE_UNLINK] = "unlink",
19 [TOMOYO_TYPE_RMDIR] = "rmdir",
20 [TOMOYO_TYPE_TRUNCATE] = "truncate",
21 [TOMOYO_TYPE_SYMLINK] = "symlink",
22 [TOMOYO_TYPE_REWRITE] = "rewrite",
23 [TOMOYO_TYPE_CHROOT] = "chroot",
24 [TOMOYO_TYPE_UMOUNT] = "unmount",
25};
26
27/* Keyword array for operations with one pathname and three numbers. */
28const char *tomoyo_mkdev_keyword[TOMOYO_MAX_MKDEV_OPERATION] = {
29 [TOMOYO_TYPE_MKBLOCK] = "mkblock",
30 [TOMOYO_TYPE_MKCHAR] = "mkchar",
31};
32
33/* Keyword array for operations with two pathnames. */
34const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = {
35 [TOMOYO_TYPE_LINK] = "link",
36 [TOMOYO_TYPE_RENAME] = "rename",
37 [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root",
38};
39
40/* Keyword array for operations with one pathname and one number. */
41const char *tomoyo_path_number_keyword[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
42 [TOMOYO_TYPE_CREATE] = "create",
43 [TOMOYO_TYPE_MKDIR] = "mkdir",
44 [TOMOYO_TYPE_MKFIFO] = "mkfifo",
45 [TOMOYO_TYPE_MKSOCK] = "mksock",
46 [TOMOYO_TYPE_IOCTL] = "ioctl",
47 [TOMOYO_TYPE_CHMOD] = "chmod",
48 [TOMOYO_TYPE_CHOWN] = "chown",
49 [TOMOYO_TYPE_CHGRP] = "chgrp",
50};
51
52static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = { 13static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
53 [TOMOYO_TYPE_READ_WRITE] = TOMOYO_MAC_FILE_OPEN,
54 [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE, 14 [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE,
55 [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN, 15 [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN,
56 [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN, 16 [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN,
17 [TOMOYO_TYPE_APPEND] = TOMOYO_MAC_FILE_OPEN,
57 [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK, 18 [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK,
19 [TOMOYO_TYPE_GETATTR] = TOMOYO_MAC_FILE_GETATTR,
58 [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR, 20 [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR,
59 [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE, 21 [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE,
60 [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK, 22 [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK,
61 [TOMOYO_TYPE_REWRITE] = TOMOYO_MAC_FILE_REWRITE,
62 [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT, 23 [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT,
63 [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT, 24 [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT,
64}; 25};
65 26
66static const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = { 27/*
28 * Mapping table from "enum tomoyo_mkdev_acl_index" to "enum tomoyo_mac_index".
29 */
30const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = {
67 [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK, 31 [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK,
68 [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR, 32 [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR,
69}; 33};
70 34
71static const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = { 35/*
36 * Mapping table from "enum tomoyo_path2_acl_index" to "enum tomoyo_mac_index".
37 */
38const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = {
72 [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK, 39 [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK,
73 [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME, 40 [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME,
74 [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT, 41 [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT,
75}; 42};
76 43
77static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = { 44/*
45 * Mapping table from "enum tomoyo_path_number_acl_index" to
46 * "enum tomoyo_mac_index".
47 */
48const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
78 [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE, 49 [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE,
79 [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR, 50 [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR,
80 [TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO, 51 [TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO,
@@ -85,41 +56,76 @@ static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
85 [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP, 56 [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP,
86}; 57};
87 58
59/**
60 * tomoyo_put_name_union - Drop reference on "struct tomoyo_name_union".
61 *
62 * @ptr: Pointer to "struct tomoyo_name_union".
63 *
64 * Returns nothing.
65 */
88void tomoyo_put_name_union(struct tomoyo_name_union *ptr) 66void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
89{ 67{
90 if (!ptr) 68 tomoyo_put_group(ptr->group);
91 return; 69 tomoyo_put_name(ptr->filename);
92 if (ptr->is_group)
93 tomoyo_put_group(ptr->group);
94 else
95 tomoyo_put_name(ptr->filename);
96} 70}
97 71
72/**
73 * tomoyo_compare_name_union - Check whether a name matches "struct tomoyo_name_union" or not.
74 *
75 * @name: Pointer to "struct tomoyo_path_info".
76 * @ptr: Pointer to "struct tomoyo_name_union".
77 *
78 * Returns "struct tomoyo_path_info" if @name matches @ptr, NULL otherwise.
79 */
98const struct tomoyo_path_info * 80const struct tomoyo_path_info *
99tomoyo_compare_name_union(const struct tomoyo_path_info *name, 81tomoyo_compare_name_union(const struct tomoyo_path_info *name,
100 const struct tomoyo_name_union *ptr) 82 const struct tomoyo_name_union *ptr)
101{ 83{
102 if (ptr->is_group) 84 if (ptr->group)
103 return tomoyo_path_matches_group(name, ptr->group); 85 return tomoyo_path_matches_group(name, ptr->group);
104 if (tomoyo_path_matches_pattern(name, ptr->filename)) 86 if (tomoyo_path_matches_pattern(name, ptr->filename))
105 return ptr->filename; 87 return ptr->filename;
106 return NULL; 88 return NULL;
107} 89}
108 90
91/**
92 * tomoyo_put_number_union - Drop reference on "struct tomoyo_number_union".
93 *
94 * @ptr: Pointer to "struct tomoyo_number_union".
95 *
96 * Returns nothing.
97 */
109void tomoyo_put_number_union(struct tomoyo_number_union *ptr) 98void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
110{ 99{
111 if (ptr && ptr->is_group) 100 tomoyo_put_group(ptr->group);
112 tomoyo_put_group(ptr->group);
113} 101}
114 102
103/**
104 * tomoyo_compare_number_union - Check whether a value matches "struct tomoyo_number_union" or not.
105 *
106 * @value: Number to check.
107 * @ptr: Pointer to "struct tomoyo_number_union".
108 *
109 * Returns true if @value matches @ptr, false otherwise.
110 */
115bool tomoyo_compare_number_union(const unsigned long value, 111bool tomoyo_compare_number_union(const unsigned long value,
116 const struct tomoyo_number_union *ptr) 112 const struct tomoyo_number_union *ptr)
117{ 113{
118 if (ptr->is_group) 114 if (ptr->group)
119 return tomoyo_number_matches_group(value, value, ptr->group); 115 return tomoyo_number_matches_group(value, value, ptr->group);
120 return value >= ptr->values[0] && value <= ptr->values[1]; 116 return value >= ptr->values[0] && value <= ptr->values[1];
121} 117}
122 118
119/**
120 * tomoyo_add_slash - Add trailing '/' if needed.
121 *
122 * @buf: Pointer to "struct tomoyo_path_info".
123 *
124 * Returns nothing.
125 *
126 * @buf must be generated by tomoyo_encode() because this function does not
127 * allocate memory for adding '/'.
128 */
123static void tomoyo_add_slash(struct tomoyo_path_info *buf) 129static void tomoyo_add_slash(struct tomoyo_path_info *buf)
124{ 130{
125 if (buf->is_dir) 131 if (buf->is_dir)
@@ -132,24 +138,6 @@ static void tomoyo_add_slash(struct tomoyo_path_info *buf)
132} 138}
133 139
134/** 140/**
135 * tomoyo_strendswith - Check whether the token ends with the given token.
136 *
137 * @name: The token to check.
138 * @tail: The token to find.
139 *
140 * Returns true if @name ends with @tail, false otherwise.
141 */
142static bool tomoyo_strendswith(const char *name, const char *tail)
143{
144 int len;
145
146 if (!name || !tail)
147 return false;
148 len = strlen(name) - strlen(tail);
149 return len >= 0 && !strcmp(name + len, tail);
150}
151
152/**
153 * tomoyo_get_realpath - Get realpath. 141 * tomoyo_get_realpath - Get realpath.
154 * 142 *
155 * @buf: Pointer to "struct tomoyo_path_info". 143 * @buf: Pointer to "struct tomoyo_path_info".
@@ -164,7 +152,7 @@ static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path)
164 tomoyo_fill_path_info(buf); 152 tomoyo_fill_path_info(buf);
165 return true; 153 return true;
166 } 154 }
167 return false; 155 return false;
168} 156}
169 157
170/** 158/**
@@ -176,13 +164,9 @@ static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path)
176 */ 164 */
177static int tomoyo_audit_path_log(struct tomoyo_request_info *r) 165static int tomoyo_audit_path_log(struct tomoyo_request_info *r)
178{ 166{
179 const char *operation = tomoyo_path_keyword[r->param.path.operation]; 167 return tomoyo_supervisor(r, "file %s %s\n", tomoyo_path_keyword
180 const struct tomoyo_path_info *filename = r->param.path.filename; 168 [r->param.path.operation],
181 if (r->granted) 169 r->param.path.filename->name);
182 return 0;
183 tomoyo_warn_log(r, "%s %s", operation, filename->name);
184 return tomoyo_supervisor(r, "allow_%s %s\n", operation,
185 tomoyo_pattern(filename));
186} 170}
187 171
188/** 172/**
@@ -194,16 +178,10 @@ static int tomoyo_audit_path_log(struct tomoyo_request_info *r)
194 */ 178 */
195static int tomoyo_audit_path2_log(struct tomoyo_request_info *r) 179static int tomoyo_audit_path2_log(struct tomoyo_request_info *r)
196{ 180{
197 const char *operation = tomoyo_path2_keyword[r->param.path2.operation]; 181 return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords
198 const struct tomoyo_path_info *filename1 = r->param.path2.filename1; 182 [tomoyo_pp2mac[r->param.path2.operation]],
199 const struct tomoyo_path_info *filename2 = r->param.path2.filename2; 183 r->param.path2.filename1->name,
200 if (r->granted) 184 r->param.path2.filename2->name);
201 return 0;
202 tomoyo_warn_log(r, "%s %s %s", operation, filename1->name,
203 filename2->name);
204 return tomoyo_supervisor(r, "allow_%s %s %s\n", operation,
205 tomoyo_pattern(filename1),
206 tomoyo_pattern(filename2));
207} 185}
208 186
209/** 187/**
@@ -215,24 +193,18 @@ static int tomoyo_audit_path2_log(struct tomoyo_request_info *r)
215 */ 193 */
216static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r) 194static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r)
217{ 195{
218 const char *operation = tomoyo_mkdev_keyword[r->param.mkdev.operation]; 196 return tomoyo_supervisor(r, "file %s %s 0%o %u %u\n",
219 const struct tomoyo_path_info *filename = r->param.mkdev.filename; 197 tomoyo_mac_keywords
220 const unsigned int major = r->param.mkdev.major; 198 [tomoyo_pnnn2mac[r->param.mkdev.operation]],
221 const unsigned int minor = r->param.mkdev.minor; 199 r->param.mkdev.filename->name,
222 const unsigned int mode = r->param.mkdev.mode; 200 r->param.mkdev.mode, r->param.mkdev.major,
223 if (r->granted) 201 r->param.mkdev.minor);
224 return 0;
225 tomoyo_warn_log(r, "%s %s 0%o %u %u", operation, filename->name, mode,
226 major, minor);
227 return tomoyo_supervisor(r, "allow_%s %s 0%o %u %u\n", operation,
228 tomoyo_pattern(filename), mode, major, minor);
229} 202}
230 203
231/** 204/**
232 * tomoyo_audit_path_number_log - Audit path/number request log. 205 * tomoyo_audit_path_number_log - Audit path/number request log.
233 * 206 *
234 * @r: Pointer to "struct tomoyo_request_info". 207 * @r: Pointer to "struct tomoyo_request_info".
235 * @error: Error code.
236 * 208 *
237 * Returns 0 on success, negative value otherwise. 209 * Returns 0 on success, negative value otherwise.
238 */ 210 */
@@ -240,11 +212,7 @@ static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
240{ 212{
241 const u8 type = r->param.path_number.operation; 213 const u8 type = r->param.path_number.operation;
242 u8 radix; 214 u8 radix;
243 const struct tomoyo_path_info *filename = r->param.path_number.filename;
244 const char *operation = tomoyo_path_number_keyword[type];
245 char buffer[64]; 215 char buffer[64];
246 if (r->granted)
247 return 0;
248 switch (type) { 216 switch (type) {
249 case TOMOYO_TYPE_CREATE: 217 case TOMOYO_TYPE_CREATE:
250 case TOMOYO_TYPE_MKDIR: 218 case TOMOYO_TYPE_MKDIR:
@@ -262,251 +230,23 @@ static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
262 } 230 }
263 tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number, 231 tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number,
264 radix); 232 radix);
265 tomoyo_warn_log(r, "%s %s %s", operation, filename->name, buffer); 233 return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords
266 return tomoyo_supervisor(r, "allow_%s %s %s\n", operation, 234 [tomoyo_pn2mac[type]],
267 tomoyo_pattern(filename), buffer); 235 r->param.path_number.filename->name, buffer);
268}
269
270static bool tomoyo_same_globally_readable(const struct tomoyo_acl_head *a,
271 const struct tomoyo_acl_head *b)
272{
273 return container_of(a, struct tomoyo_readable_file,
274 head)->filename ==
275 container_of(b, struct tomoyo_readable_file,
276 head)->filename;
277}
278
279/**
280 * tomoyo_update_globally_readable_entry - Update "struct tomoyo_readable_file" list.
281 *
282 * @filename: Filename unconditionally permitted to open() for reading.
283 * @is_delete: True if it is a delete request.
284 *
285 * Returns 0 on success, negative value otherwise.
286 *
287 * Caller holds tomoyo_read_lock().
288 */
289static int tomoyo_update_globally_readable_entry(const char *filename,
290 const bool is_delete)
291{
292 struct tomoyo_readable_file e = { };
293 int error;
294
295 if (!tomoyo_correct_word(filename))
296 return -EINVAL;
297 e.filename = tomoyo_get_name(filename);
298 if (!e.filename)
299 return -ENOMEM;
300 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
301 &tomoyo_policy_list
302 [TOMOYO_ID_GLOBALLY_READABLE],
303 tomoyo_same_globally_readable);
304 tomoyo_put_name(e.filename);
305 return error;
306}
307
308/**
309 * tomoyo_globally_readable_file - Check if the file is unconditionnaly permitted to be open()ed for reading.
310 *
311 * @filename: The filename to check.
312 *
313 * Returns true if any domain can open @filename for reading, false otherwise.
314 *
315 * Caller holds tomoyo_read_lock().
316 */
317static bool tomoyo_globally_readable_file(const struct tomoyo_path_info *
318 filename)
319{
320 struct tomoyo_readable_file *ptr;
321 bool found = false;
322
323 list_for_each_entry_rcu(ptr, &tomoyo_policy_list
324 [TOMOYO_ID_GLOBALLY_READABLE], head.list) {
325 if (!ptr->head.is_deleted &&
326 tomoyo_path_matches_pattern(filename, ptr->filename)) {
327 found = true;
328 break;
329 }
330 }
331 return found;
332}
333
334/**
335 * tomoyo_write_globally_readable - Write "struct tomoyo_readable_file" list.
336 *
337 * @data: String to parse.
338 * @is_delete: True if it is a delete request.
339 *
340 * Returns 0 on success, negative value otherwise.
341 *
342 * Caller holds tomoyo_read_lock().
343 */
344int tomoyo_write_globally_readable(char *data, const bool is_delete)
345{
346 return tomoyo_update_globally_readable_entry(data, is_delete);
347}
348
349static bool tomoyo_same_pattern(const struct tomoyo_acl_head *a,
350 const struct tomoyo_acl_head *b)
351{
352 return container_of(a, struct tomoyo_no_pattern, head)->pattern ==
353 container_of(b, struct tomoyo_no_pattern, head)->pattern;
354}
355
356/**
357 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_no_pattern" list.
358 *
359 * @pattern: Pathname pattern.
360 * @is_delete: True if it is a delete request.
361 *
362 * Returns 0 on success, negative value otherwise.
363 *
364 * Caller holds tomoyo_read_lock().
365 */
366static int tomoyo_update_file_pattern_entry(const char *pattern,
367 const bool is_delete)
368{
369 struct tomoyo_no_pattern e = { };
370 int error;
371
372 if (!tomoyo_correct_word(pattern))
373 return -EINVAL;
374 e.pattern = tomoyo_get_name(pattern);
375 if (!e.pattern)
376 return -ENOMEM;
377 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
378 &tomoyo_policy_list[TOMOYO_ID_PATTERN],
379 tomoyo_same_pattern);
380 tomoyo_put_name(e.pattern);
381 return error;
382}
383
384/**
385 * tomoyo_pattern - Get patterned pathname.
386 *
387 * @filename: The filename to find patterned pathname.
388 *
389 * Returns pointer to pathname pattern if matched, @filename otherwise.
390 *
391 * Caller holds tomoyo_read_lock().
392 */
393const char *tomoyo_pattern(const struct tomoyo_path_info *filename)
394{
395 struct tomoyo_no_pattern *ptr;
396 const struct tomoyo_path_info *pattern = NULL;
397
398 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_PATTERN],
399 head.list) {
400 if (ptr->head.is_deleted)
401 continue;
402 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
403 continue;
404 pattern = ptr->pattern;
405 if (tomoyo_strendswith(pattern->name, "/\\*")) {
406 /* Do nothing. Try to find the better match. */
407 } else {
408 /* This would be the better match. Use this. */
409 break;
410 }
411 }
412 if (pattern)
413 filename = pattern;
414 return filename->name;
415}
416
417/**
418 * tomoyo_write_pattern - Write "struct tomoyo_no_pattern" list.
419 *
420 * @data: String to parse.
421 * @is_delete: True if it is a delete request.
422 *
423 * Returns 0 on success, negative value otherwise.
424 *
425 * Caller holds tomoyo_read_lock().
426 */
427int tomoyo_write_pattern(char *data, const bool is_delete)
428{
429 return tomoyo_update_file_pattern_entry(data, is_delete);
430}
431
432static bool tomoyo_same_no_rewrite(const struct tomoyo_acl_head *a,
433 const struct tomoyo_acl_head *b)
434{
435 return container_of(a, struct tomoyo_no_rewrite, head)->pattern
436 == container_of(b, struct tomoyo_no_rewrite, head)
437 ->pattern;
438}
439
440/**
441 * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite" list.
442 *
443 * @pattern: Pathname pattern that are not rewritable by default.
444 * @is_delete: True if it is a delete request.
445 *
446 * Returns 0 on success, negative value otherwise.
447 *
448 * Caller holds tomoyo_read_lock().
449 */
450static int tomoyo_update_no_rewrite_entry(const char *pattern,
451 const bool is_delete)
452{
453 struct tomoyo_no_rewrite e = { };
454 int error;
455
456 if (!tomoyo_correct_word(pattern))
457 return -EINVAL;
458 e.pattern = tomoyo_get_name(pattern);
459 if (!e.pattern)
460 return -ENOMEM;
461 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
462 &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE],
463 tomoyo_same_no_rewrite);
464 tomoyo_put_name(e.pattern);
465 return error;
466} 236}
467 237
468/** 238/**
469 * tomoyo_no_rewrite_file - Check if the given pathname is not permitted to be rewrited. 239 * tomoyo_check_path_acl - Check permission for path operation.
470 * 240 *
471 * @filename: Filename to check. 241 * @r: Pointer to "struct tomoyo_request_info".
242 * @ptr: Pointer to "struct tomoyo_acl_info".
472 * 243 *
473 * Returns true if @filename is specified by "deny_rewrite" directive, 244 * Returns true if granted, false otherwise.
474 * false otherwise.
475 * 245 *
476 * Caller holds tomoyo_read_lock(). 246 * To be able to use wildcard for domain transition, this function sets
247 * matching entry on success. Since the caller holds tomoyo_read_lock(),
248 * it is safe to set matching entry.
477 */ 249 */
478static bool tomoyo_no_rewrite_file(const struct tomoyo_path_info *filename)
479{
480 struct tomoyo_no_rewrite *ptr;
481 bool found = false;
482
483 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE],
484 head.list) {
485 if (ptr->head.is_deleted)
486 continue;
487 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
488 continue;
489 found = true;
490 break;
491 }
492 return found;
493}
494
495/**
496 * tomoyo_write_no_rewrite - Write "struct tomoyo_no_rewrite" list.
497 *
498 * @data: String to parse.
499 * @is_delete: True if it is a delete request.
500 *
501 * Returns 0 on success, negative value otherwise.
502 *
503 * Caller holds tomoyo_read_lock().
504 */
505int tomoyo_write_no_rewrite(char *data, const bool is_delete)
506{
507 return tomoyo_update_no_rewrite_entry(data, is_delete);
508}
509
510static bool tomoyo_check_path_acl(struct tomoyo_request_info *r, 250static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
511 const struct tomoyo_acl_info *ptr) 251 const struct tomoyo_acl_info *ptr)
512{ 252{
@@ -521,6 +261,14 @@ static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
521 return false; 261 return false;
522} 262}
523 263
264/**
265 * tomoyo_check_path_number_acl - Check permission for path number operation.
266 *
267 * @r: Pointer to "struct tomoyo_request_info".
268 * @ptr: Pointer to "struct tomoyo_acl_info".
269 *
270 * Returns true if granted, false otherwise.
271 */
524static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r, 272static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
525 const struct tomoyo_acl_info *ptr) 273 const struct tomoyo_acl_info *ptr)
526{ 274{
@@ -533,6 +281,14 @@ static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
533 &acl->name); 281 &acl->name);
534} 282}
535 283
284/**
285 * tomoyo_check_path2_acl - Check permission for path path operation.
286 *
287 * @r: Pointer to "struct tomoyo_request_info".
288 * @ptr: Pointer to "struct tomoyo_acl_info".
289 *
290 * Returns true if granted, false otherwise.
291 */
536static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r, 292static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
537 const struct tomoyo_acl_info *ptr) 293 const struct tomoyo_acl_info *ptr)
538{ 294{
@@ -544,8 +300,16 @@ static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
544 &acl->name2); 300 &acl->name2);
545} 301}
546 302
303/**
304 * tomoyo_check_mkdev_acl - Check permission for path number number number operation.
305 *
306 * @r: Pointer to "struct tomoyo_request_info".
307 * @ptr: Pointer to "struct tomoyo_acl_info".
308 *
309 * Returns true if granted, false otherwise.
310 */
547static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r, 311static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
548 const struct tomoyo_acl_info *ptr) 312 const struct tomoyo_acl_info *ptr)
549{ 313{
550 const struct tomoyo_mkdev_acl *acl = 314 const struct tomoyo_mkdev_acl *acl =
551 container_of(ptr, typeof(*acl), head); 315 container_of(ptr, typeof(*acl), head);
@@ -560,15 +324,31 @@ static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
560 &acl->name); 324 &acl->name);
561} 325}
562 326
327/**
328 * tomoyo_same_path_acl - Check for duplicated "struct tomoyo_path_acl" entry.
329 *
330 * @a: Pointer to "struct tomoyo_acl_info".
331 * @b: Pointer to "struct tomoyo_acl_info".
332 *
333 * Returns true if @a == @b except permission bits, false otherwise.
334 */
563static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a, 335static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a,
564 const struct tomoyo_acl_info *b) 336 const struct tomoyo_acl_info *b)
565{ 337{
566 const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head); 338 const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head);
567 const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head); 339 const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head);
568 return tomoyo_same_acl_head(&p1->head, &p2->head) && 340 return tomoyo_same_name_union(&p1->name, &p2->name);
569 tomoyo_same_name_union(&p1->name, &p2->name);
570} 341}
571 342
343/**
344 * tomoyo_merge_path_acl - Merge duplicated "struct tomoyo_path_acl" entry.
345 *
346 * @a: Pointer to "struct tomoyo_acl_info".
347 * @b: Pointer to "struct tomoyo_acl_info".
348 * @is_delete: True for @a &= ~@b, false for @a |= @b.
349 *
350 * Returns true if @a is empty, false otherwise.
351 */
572static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a, 352static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
573 struct tomoyo_acl_info *b, 353 struct tomoyo_acl_info *b,
574 const bool is_delete) 354 const bool is_delete)
@@ -577,19 +357,10 @@ static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
577 ->perm; 357 ->perm;
578 u16 perm = *a_perm; 358 u16 perm = *a_perm;
579 const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm; 359 const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm;
580 if (is_delete) { 360 if (is_delete)
581 perm &= ~b_perm; 361 perm &= ~b_perm;
582 if ((perm & TOMOYO_RW_MASK) != TOMOYO_RW_MASK) 362 else
583 perm &= ~(1 << TOMOYO_TYPE_READ_WRITE);
584 else if (!(perm & (1 << TOMOYO_TYPE_READ_WRITE)))
585 perm &= ~TOMOYO_RW_MASK;
586 } else {
587 perm |= b_perm; 363 perm |= b_perm;
588 if ((perm & TOMOYO_RW_MASK) == TOMOYO_RW_MASK)
589 perm |= (1 << TOMOYO_TYPE_READ_WRITE);
590 else if (perm & (1 << TOMOYO_TYPE_READ_WRITE))
591 perm |= TOMOYO_RW_MASK;
592 }
593 *a_perm = perm; 364 *a_perm = perm;
594 return !perm; 365 return !perm;
595} 366}
@@ -597,52 +368,62 @@ static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
597/** 368/**
598 * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list. 369 * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list.
599 * 370 *
600 * @type: Type of operation. 371 * @perm: Permission.
601 * @filename: Filename. 372 * @param: Pointer to "struct tomoyo_acl_param".
602 * @domain: Pointer to "struct tomoyo_domain_info".
603 * @is_delete: True if it is a delete request.
604 * 373 *
605 * Returns 0 on success, negative value otherwise. 374 * Returns 0 on success, negative value otherwise.
606 * 375 *
607 * Caller holds tomoyo_read_lock(). 376 * Caller holds tomoyo_read_lock().
608 */ 377 */
609static int tomoyo_update_path_acl(const u8 type, const char *filename, 378static int tomoyo_update_path_acl(const u16 perm,
610 struct tomoyo_domain_info * const domain, 379 struct tomoyo_acl_param *param)
611 const bool is_delete)
612{ 380{
613 struct tomoyo_path_acl e = { 381 struct tomoyo_path_acl e = {
614 .head.type = TOMOYO_TYPE_PATH_ACL, 382 .head.type = TOMOYO_TYPE_PATH_ACL,
615 .perm = 1 << type 383 .perm = perm
616 }; 384 };
617 int error; 385 int error;
618 if (e.perm == (1 << TOMOYO_TYPE_READ_WRITE)) 386 if (!tomoyo_parse_name_union(param, &e.name))
619 e.perm |= TOMOYO_RW_MASK; 387 error = -EINVAL;
620 if (!tomoyo_parse_name_union(filename, &e.name)) 388 else
621 return -EINVAL; 389 error = tomoyo_update_domain(&e.head, sizeof(e), param,
622 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 390 tomoyo_same_path_acl,
623 tomoyo_same_path_acl, 391 tomoyo_merge_path_acl);
624 tomoyo_merge_path_acl);
625 tomoyo_put_name_union(&e.name); 392 tomoyo_put_name_union(&e.name);
626 return error; 393 return error;
627} 394}
628 395
396/**
397 * tomoyo_same_mkdev_acl - Check for duplicated "struct tomoyo_mkdev_acl" entry.
398 *
399 * @a: Pointer to "struct tomoyo_acl_info".
400 * @b: Pointer to "struct tomoyo_acl_info".
401 *
402 * Returns true if @a == @b except permission bits, false otherwise.
403 */
629static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a, 404static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a,
630 const struct tomoyo_acl_info *b) 405 const struct tomoyo_acl_info *b)
631{ 406{
632 const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), 407 const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), head);
633 head); 408 const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), head);
634 const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), 409 return tomoyo_same_name_union(&p1->name, &p2->name) &&
635 head); 410 tomoyo_same_number_union(&p1->mode, &p2->mode) &&
636 return tomoyo_same_acl_head(&p1->head, &p2->head) 411 tomoyo_same_number_union(&p1->major, &p2->major) &&
637 && tomoyo_same_name_union(&p1->name, &p2->name) 412 tomoyo_same_number_union(&p1->minor, &p2->minor);
638 && tomoyo_same_number_union(&p1->mode, &p2->mode)
639 && tomoyo_same_number_union(&p1->major, &p2->major)
640 && tomoyo_same_number_union(&p1->minor, &p2->minor);
641} 413}
642 414
415/**
416 * tomoyo_merge_mkdev_acl - Merge duplicated "struct tomoyo_mkdev_acl" entry.
417 *
418 * @a: Pointer to "struct tomoyo_acl_info".
419 * @b: Pointer to "struct tomoyo_acl_info".
420 * @is_delete: True for @a &= ~@b, false for @a |= @b.
421 *
422 * Returns true if @a is empty, false otherwise.
423 */
643static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a, 424static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
644 struct tomoyo_acl_info *b, 425 struct tomoyo_acl_info *b,
645 const bool is_delete) 426 const bool is_delete)
646{ 427{
647 u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl, 428 u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl,
648 head)->perm; 429 head)->perm;
@@ -660,37 +441,30 @@ static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
660/** 441/**
661 * tomoyo_update_mkdev_acl - Update "struct tomoyo_mkdev_acl" list. 442 * tomoyo_update_mkdev_acl - Update "struct tomoyo_mkdev_acl" list.
662 * 443 *
663 * @type: Type of operation. 444 * @perm: Permission.
664 * @filename: Filename. 445 * @param: Pointer to "struct tomoyo_acl_param".
665 * @mode: Create mode.
666 * @major: Device major number.
667 * @minor: Device minor number.
668 * @domain: Pointer to "struct tomoyo_domain_info".
669 * @is_delete: True if it is a delete request.
670 * 446 *
671 * Returns 0 on success, negative value otherwise. 447 * Returns 0 on success, negative value otherwise.
672 * 448 *
673 * Caller holds tomoyo_read_lock(). 449 * Caller holds tomoyo_read_lock().
674 */ 450 */
675static int tomoyo_update_mkdev_acl(const u8 type, const char *filename, 451static int tomoyo_update_mkdev_acl(const u8 perm,
676 char *mode, char *major, char *minor, 452 struct tomoyo_acl_param *param)
677 struct tomoyo_domain_info * const
678 domain, const bool is_delete)
679{ 453{
680 struct tomoyo_mkdev_acl e = { 454 struct tomoyo_mkdev_acl e = {
681 .head.type = TOMOYO_TYPE_MKDEV_ACL, 455 .head.type = TOMOYO_TYPE_MKDEV_ACL,
682 .perm = 1 << type 456 .perm = perm
683 }; 457 };
684 int error = is_delete ? -ENOENT : -ENOMEM; 458 int error;
685 if (!tomoyo_parse_name_union(filename, &e.name) || 459 if (!tomoyo_parse_name_union(param, &e.name) ||
686 !tomoyo_parse_number_union(mode, &e.mode) || 460 !tomoyo_parse_number_union(param, &e.mode) ||
687 !tomoyo_parse_number_union(major, &e.major) || 461 !tomoyo_parse_number_union(param, &e.major) ||
688 !tomoyo_parse_number_union(minor, &e.minor)) 462 !tomoyo_parse_number_union(param, &e.minor))
689 goto out; 463 error = -EINVAL;
690 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 464 else
691 tomoyo_same_mkdev_acl, 465 error = tomoyo_update_domain(&e.head, sizeof(e), param,
692 tomoyo_merge_mkdev_acl); 466 tomoyo_same_mkdev_acl,
693 out: 467 tomoyo_merge_mkdev_acl);
694 tomoyo_put_name_union(&e.name); 468 tomoyo_put_name_union(&e.name);
695 tomoyo_put_number_union(&e.mode); 469 tomoyo_put_number_union(&e.mode);
696 tomoyo_put_number_union(&e.major); 470 tomoyo_put_number_union(&e.major);
@@ -698,16 +472,32 @@ static int tomoyo_update_mkdev_acl(const u8 type, const char *filename,
698 return error; 472 return error;
699} 473}
700 474
475/**
476 * tomoyo_same_path2_acl - Check for duplicated "struct tomoyo_path2_acl" entry.
477 *
478 * @a: Pointer to "struct tomoyo_acl_info".
479 * @b: Pointer to "struct tomoyo_acl_info".
480 *
481 * Returns true if @a == @b except permission bits, false otherwise.
482 */
701static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a, 483static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a,
702 const struct tomoyo_acl_info *b) 484 const struct tomoyo_acl_info *b)
703{ 485{
704 const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head); 486 const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head);
705 const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head); 487 const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head);
706 return tomoyo_same_acl_head(&p1->head, &p2->head) 488 return tomoyo_same_name_union(&p1->name1, &p2->name1) &&
707 && tomoyo_same_name_union(&p1->name1, &p2->name1) 489 tomoyo_same_name_union(&p1->name2, &p2->name2);
708 && tomoyo_same_name_union(&p1->name2, &p2->name2);
709} 490}
710 491
492/**
493 * tomoyo_merge_path2_acl - Merge duplicated "struct tomoyo_path2_acl" entry.
494 *
495 * @a: Pointer to "struct tomoyo_acl_info".
496 * @b: Pointer to "struct tomoyo_acl_info".
497 * @is_delete: True for @a &= ~@b, false for @a |= @b.
498 *
499 * Returns true if @a is empty, false otherwise.
500 */
711static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a, 501static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a,
712 struct tomoyo_acl_info *b, 502 struct tomoyo_acl_info *b,
713 const bool is_delete) 503 const bool is_delete)
@@ -727,33 +517,28 @@ static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a,
727/** 517/**
728 * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list. 518 * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list.
729 * 519 *
730 * @type: Type of operation. 520 * @perm: Permission.
731 * @filename1: First filename. 521 * @param: Pointer to "struct tomoyo_acl_param".
732 * @filename2: Second filename.
733 * @domain: Pointer to "struct tomoyo_domain_info".
734 * @is_delete: True if it is a delete request.
735 * 522 *
736 * Returns 0 on success, negative value otherwise. 523 * Returns 0 on success, negative value otherwise.
737 * 524 *
738 * Caller holds tomoyo_read_lock(). 525 * Caller holds tomoyo_read_lock().
739 */ 526 */
740static int tomoyo_update_path2_acl(const u8 type, const char *filename1, 527static int tomoyo_update_path2_acl(const u8 perm,
741 const char *filename2, 528 struct tomoyo_acl_param *param)
742 struct tomoyo_domain_info * const domain,
743 const bool is_delete)
744{ 529{
745 struct tomoyo_path2_acl e = { 530 struct tomoyo_path2_acl e = {
746 .head.type = TOMOYO_TYPE_PATH2_ACL, 531 .head.type = TOMOYO_TYPE_PATH2_ACL,
747 .perm = 1 << type 532 .perm = perm
748 }; 533 };
749 int error = is_delete ? -ENOENT : -ENOMEM; 534 int error;
750 if (!tomoyo_parse_name_union(filename1, &e.name1) || 535 if (!tomoyo_parse_name_union(param, &e.name1) ||
751 !tomoyo_parse_name_union(filename2, &e.name2)) 536 !tomoyo_parse_name_union(param, &e.name2))
752 goto out; 537 error = -EINVAL;
753 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 538 else
754 tomoyo_same_path2_acl, 539 error = tomoyo_update_domain(&e.head, sizeof(e), param,
755 tomoyo_merge_path2_acl); 540 tomoyo_same_path2_acl,
756 out: 541 tomoyo_merge_path2_acl);
757 tomoyo_put_name_union(&e.name1); 542 tomoyo_put_name_union(&e.name1);
758 tomoyo_put_name_union(&e.name2); 543 tomoyo_put_name_union(&e.name2);
759 return error; 544 return error;
@@ -775,9 +560,8 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
775{ 560{
776 int error; 561 int error;
777 562
778 next:
779 r->type = tomoyo_p2mac[operation]; 563 r->type = tomoyo_p2mac[operation];
780 r->mode = tomoyo_get_mode(r->profile, r->type); 564 r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
781 if (r->mode == TOMOYO_CONFIG_DISABLED) 565 if (r->mode == TOMOYO_CONFIG_DISABLED)
782 return 0; 566 return 0;
783 r->param_type = TOMOYO_TYPE_PATH_ACL; 567 r->param_type = TOMOYO_TYPE_PATH_ACL;
@@ -785,10 +569,6 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
785 r->param.path.operation = operation; 569 r->param.path.operation = operation;
786 do { 570 do {
787 tomoyo_check_acl(r, tomoyo_check_path_acl); 571 tomoyo_check_acl(r, tomoyo_check_path_acl);
788 if (!r->granted && operation == TOMOYO_TYPE_READ &&
789 !r->domain->ignore_global_allow_read &&
790 tomoyo_globally_readable_file(filename))
791 r->granted = true;
792 error = tomoyo_audit_path_log(r); 572 error = tomoyo_audit_path_log(r);
793 /* 573 /*
794 * Do not retry for execute request, for alias may have 574 * Do not retry for execute request, for alias may have
@@ -796,19 +576,17 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
796 */ 576 */
797 } while (error == TOMOYO_RETRY_REQUEST && 577 } while (error == TOMOYO_RETRY_REQUEST &&
798 operation != TOMOYO_TYPE_EXECUTE); 578 operation != TOMOYO_TYPE_EXECUTE);
799 /*
800 * Since "allow_truncate" doesn't imply "allow_rewrite" permission,
801 * we need to check "allow_rewrite" permission if the filename is
802 * specified by "deny_rewrite" keyword.
803 */
804 if (!error && operation == TOMOYO_TYPE_TRUNCATE &&
805 tomoyo_no_rewrite_file(filename)) {
806 operation = TOMOYO_TYPE_REWRITE;
807 goto next;
808 }
809 return error; 579 return error;
810} 580}
811 581
582/**
583 * tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry.
584 *
585 * @a: Pointer to "struct tomoyo_acl_info".
586 * @b: Pointer to "struct tomoyo_acl_info".
587 *
588 * Returns true if @a == @b except permission bits, false otherwise.
589 */
812static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a, 590static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
813 const struct tomoyo_acl_info *b) 591 const struct tomoyo_acl_info *b)
814{ 592{
@@ -816,11 +594,19 @@ static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
816 head); 594 head);
817 const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2), 595 const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2),
818 head); 596 head);
819 return tomoyo_same_acl_head(&p1->head, &p2->head) 597 return tomoyo_same_name_union(&p1->name, &p2->name) &&
820 && tomoyo_same_name_union(&p1->name, &p2->name) 598 tomoyo_same_number_union(&p1->number, &p2->number);
821 && tomoyo_same_number_union(&p1->number, &p2->number);
822} 599}
823 600
601/**
602 * tomoyo_merge_path_number_acl - Merge duplicated "struct tomoyo_path_number_acl" entry.
603 *
604 * @a: Pointer to "struct tomoyo_acl_info".
605 * @b: Pointer to "struct tomoyo_acl_info".
606 * @is_delete: True for @a &= ~@b, false for @a |= @b.
607 *
608 * Returns true if @a is empty, false otherwise.
609 */
824static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a, 610static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
825 struct tomoyo_acl_info *b, 611 struct tomoyo_acl_info *b,
826 const bool is_delete) 612 const bool is_delete)
@@ -841,33 +627,26 @@ static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
841/** 627/**
842 * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL. 628 * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL.
843 * 629 *
844 * @type: Type of operation. 630 * @perm: Permission.
845 * @filename: Filename. 631 * @param: Pointer to "struct tomoyo_acl_param".
846 * @number: Number.
847 * @domain: Pointer to "struct tomoyo_domain_info".
848 * @is_delete: True if it is a delete request.
849 * 632 *
850 * Returns 0 on success, negative value otherwise. 633 * Returns 0 on success, negative value otherwise.
851 */ 634 */
852static int tomoyo_update_path_number_acl(const u8 type, const char *filename, 635static int tomoyo_update_path_number_acl(const u8 perm,
853 char *number, 636 struct tomoyo_acl_param *param)
854 struct tomoyo_domain_info * const
855 domain,
856 const bool is_delete)
857{ 637{
858 struct tomoyo_path_number_acl e = { 638 struct tomoyo_path_number_acl e = {
859 .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL, 639 .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL,
860 .perm = 1 << type 640 .perm = perm
861 }; 641 };
862 int error = is_delete ? -ENOENT : -ENOMEM; 642 int error;
863 if (!tomoyo_parse_name_union(filename, &e.name)) 643 if (!tomoyo_parse_name_union(param, &e.name) ||
864 return -EINVAL; 644 !tomoyo_parse_number_union(param, &e.number))
865 if (!tomoyo_parse_number_union(number, &e.number)) 645 error = -EINVAL;
866 goto out; 646 else
867 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 647 error = tomoyo_update_domain(&e.head, sizeof(e), param,
868 tomoyo_same_path_number_acl, 648 tomoyo_same_path_number_acl,
869 tomoyo_merge_path_number_acl); 649 tomoyo_merge_path_number_acl);
870 out:
871 tomoyo_put_name_union(&e.name); 650 tomoyo_put_name_union(&e.name);
872 tomoyo_put_number_union(&e.number); 651 tomoyo_put_number_union(&e.number);
873 return error; 652 return error;
@@ -886,16 +665,20 @@ int tomoyo_path_number_perm(const u8 type, struct path *path,
886 unsigned long number) 665 unsigned long number)
887{ 666{
888 struct tomoyo_request_info r; 667 struct tomoyo_request_info r;
668 struct tomoyo_obj_info obj = {
669 .path1 = *path,
670 };
889 int error = -ENOMEM; 671 int error = -ENOMEM;
890 struct tomoyo_path_info buf; 672 struct tomoyo_path_info buf;
891 int idx; 673 int idx;
892 674
893 if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type]) 675 if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type])
894 == TOMOYO_CONFIG_DISABLED || !path->mnt || !path->dentry) 676 == TOMOYO_CONFIG_DISABLED || !path->dentry)
895 return 0; 677 return 0;
896 idx = tomoyo_read_lock(); 678 idx = tomoyo_read_lock();
897 if (!tomoyo_get_realpath(&buf, path)) 679 if (!tomoyo_get_realpath(&buf, path))
898 goto out; 680 goto out;
681 r.obj = &obj;
899 if (type == TOMOYO_TYPE_MKDIR) 682 if (type == TOMOYO_TYPE_MKDIR)
900 tomoyo_add_slash(&buf); 683 tomoyo_add_slash(&buf);
901 r.param_type = TOMOYO_TYPE_PATH_NUMBER_ACL; 684 r.param_type = TOMOYO_TYPE_PATH_NUMBER_ACL;
@@ -930,45 +713,30 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
930 int error = 0; 713 int error = 0;
931 struct tomoyo_path_info buf; 714 struct tomoyo_path_info buf;
932 struct tomoyo_request_info r; 715 struct tomoyo_request_info r;
716 struct tomoyo_obj_info obj = {
717 .path1 = *path,
718 };
933 int idx; 719 int idx;
934 720
935 if (!path->mnt ||
936 (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode)))
937 return 0;
938 buf.name = NULL; 721 buf.name = NULL;
939 r.mode = TOMOYO_CONFIG_DISABLED; 722 r.mode = TOMOYO_CONFIG_DISABLED;
940 idx = tomoyo_read_lock(); 723 idx = tomoyo_read_lock();
941 /* 724 if (acc_mode &&
942 * If the filename is specified by "deny_rewrite" keyword, 725 tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
943 * we need to check "allow_rewrite" permission when the filename is not
944 * opened for append mode or the filename is truncated at open time.
945 */
946 if ((acc_mode & MAY_WRITE) && !(flag & O_APPEND)
947 && tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_REWRITE)
948 != TOMOYO_CONFIG_DISABLED) { 726 != TOMOYO_CONFIG_DISABLED) {
949 if (!tomoyo_get_realpath(&buf, path)) { 727 if (!tomoyo_get_realpath(&buf, path)) {
950 error = -ENOMEM; 728 error = -ENOMEM;
951 goto out; 729 goto out;
952 } 730 }
953 if (tomoyo_no_rewrite_file(&buf)) 731 r.obj = &obj;
954 error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, 732 if (acc_mode & MAY_READ)
733 error = tomoyo_path_permission(&r, TOMOYO_TYPE_READ,
734 &buf);
735 if (!error && (acc_mode & MAY_WRITE))
736 error = tomoyo_path_permission(&r, (flag & O_APPEND) ?
737 TOMOYO_TYPE_APPEND :
738 TOMOYO_TYPE_WRITE,
955 &buf); 739 &buf);
956 }
957 if (!error && acc_mode &&
958 tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
959 != TOMOYO_CONFIG_DISABLED) {
960 u8 operation;
961 if (!buf.name && !tomoyo_get_realpath(&buf, path)) {
962 error = -ENOMEM;
963 goto out;
964 }
965 if (acc_mode == (MAY_READ | MAY_WRITE))
966 operation = TOMOYO_TYPE_READ_WRITE;
967 else if (acc_mode == MAY_READ)
968 operation = TOMOYO_TYPE_READ;
969 else
970 operation = TOMOYO_TYPE_WRITE;
971 error = tomoyo_path_permission(&r, operation, &buf);
972 } 740 }
973 out: 741 out:
974 kfree(buf.name); 742 kfree(buf.name);
@@ -979,46 +747,57 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
979} 747}
980 748
981/** 749/**
982 * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "rewrite", "chroot" and "unmount". 750 * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "chroot" and "unmount".
983 * 751 *
984 * @operation: Type of operation. 752 * @operation: Type of operation.
985 * @path: Pointer to "struct path". 753 * @path: Pointer to "struct path".
754 * @target: Symlink's target if @operation is TOMOYO_TYPE_SYMLINK,
755 * NULL otherwise.
986 * 756 *
987 * Returns 0 on success, negative value otherwise. 757 * Returns 0 on success, negative value otherwise.
988 */ 758 */
989int tomoyo_path_perm(const u8 operation, struct path *path) 759int tomoyo_path_perm(const u8 operation, struct path *path, const char *target)
990{ 760{
991 int error = -ENOMEM;
992 struct tomoyo_path_info buf;
993 struct tomoyo_request_info r; 761 struct tomoyo_request_info r;
762 struct tomoyo_obj_info obj = {
763 .path1 = *path,
764 };
765 int error;
766 struct tomoyo_path_info buf;
767 bool is_enforce;
768 struct tomoyo_path_info symlink_target;
994 int idx; 769 int idx;
995 770
996 if (!path->mnt)
997 return 0;
998 if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation]) 771 if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation])
999 == TOMOYO_CONFIG_DISABLED) 772 == TOMOYO_CONFIG_DISABLED)
1000 return 0; 773 return 0;
774 is_enforce = (r.mode == TOMOYO_CONFIG_ENFORCING);
775 error = -ENOMEM;
1001 buf.name = NULL; 776 buf.name = NULL;
1002 idx = tomoyo_read_lock(); 777 idx = tomoyo_read_lock();
1003 if (!tomoyo_get_realpath(&buf, path)) 778 if (!tomoyo_get_realpath(&buf, path))
1004 goto out; 779 goto out;
780 r.obj = &obj;
1005 switch (operation) { 781 switch (operation) {
1006 case TOMOYO_TYPE_REWRITE:
1007 if (!tomoyo_no_rewrite_file(&buf)) {
1008 error = 0;
1009 goto out;
1010 }
1011 break;
1012 case TOMOYO_TYPE_RMDIR: 782 case TOMOYO_TYPE_RMDIR:
1013 case TOMOYO_TYPE_CHROOT: 783 case TOMOYO_TYPE_CHROOT:
1014 tomoyo_add_slash(&buf); 784 tomoyo_add_slash(&buf);
1015 break; 785 break;
786 case TOMOYO_TYPE_SYMLINK:
787 symlink_target.name = tomoyo_encode(target);
788 if (!symlink_target.name)
789 goto out;
790 tomoyo_fill_path_info(&symlink_target);
791 obj.symlink_target = &symlink_target;
792 break;
1016 } 793 }
1017 error = tomoyo_path_permission(&r, operation, &buf); 794 error = tomoyo_path_permission(&r, operation, &buf);
795 if (operation == TOMOYO_TYPE_SYMLINK)
796 kfree(symlink_target.name);
1018 out: 797 out:
1019 kfree(buf.name); 798 kfree(buf.name);
1020 tomoyo_read_unlock(idx); 799 tomoyo_read_unlock(idx);
1021 if (r.mode != TOMOYO_CONFIG_ENFORCING) 800 if (!is_enforce)
1022 error = 0; 801 error = 0;
1023 return error; 802 return error;
1024} 803}
@@ -1034,20 +813,23 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
1034 * Returns 0 on success, negative value otherwise. 813 * Returns 0 on success, negative value otherwise.
1035 */ 814 */
1036int tomoyo_mkdev_perm(const u8 operation, struct path *path, 815int tomoyo_mkdev_perm(const u8 operation, struct path *path,
1037 const unsigned int mode, unsigned int dev) 816 const unsigned int mode, unsigned int dev)
1038{ 817{
1039 struct tomoyo_request_info r; 818 struct tomoyo_request_info r;
819 struct tomoyo_obj_info obj = {
820 .path1 = *path,
821 };
1040 int error = -ENOMEM; 822 int error = -ENOMEM;
1041 struct tomoyo_path_info buf; 823 struct tomoyo_path_info buf;
1042 int idx; 824 int idx;
1043 825
1044 if (!path->mnt || 826 if (tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation])
1045 tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation])
1046 == TOMOYO_CONFIG_DISABLED) 827 == TOMOYO_CONFIG_DISABLED)
1047 return 0; 828 return 0;
1048 idx = tomoyo_read_lock(); 829 idx = tomoyo_read_lock();
1049 error = -ENOMEM; 830 error = -ENOMEM;
1050 if (tomoyo_get_realpath(&buf, path)) { 831 if (tomoyo_get_realpath(&buf, path)) {
832 r.obj = &obj;
1051 dev = new_decode_dev(dev); 833 dev = new_decode_dev(dev);
1052 r.param_type = TOMOYO_TYPE_MKDEV_ACL; 834 r.param_type = TOMOYO_TYPE_MKDEV_ACL;
1053 r.param.mkdev.filename = &buf; 835 r.param.mkdev.filename = &buf;
@@ -1081,10 +863,13 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1081 struct tomoyo_path_info buf1; 863 struct tomoyo_path_info buf1;
1082 struct tomoyo_path_info buf2; 864 struct tomoyo_path_info buf2;
1083 struct tomoyo_request_info r; 865 struct tomoyo_request_info r;
866 struct tomoyo_obj_info obj = {
867 .path1 = *path1,
868 .path2 = *path2,
869 };
1084 int idx; 870 int idx;
1085 871
1086 if (!path1->mnt || !path2->mnt || 872 if (tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation])
1087 tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation])
1088 == TOMOYO_CONFIG_DISABLED) 873 == TOMOYO_CONFIG_DISABLED)
1089 return 0; 874 return 0;
1090 buf1.name = NULL; 875 buf1.name = NULL;
@@ -1096,16 +881,17 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1096 switch (operation) { 881 switch (operation) {
1097 struct dentry *dentry; 882 struct dentry *dentry;
1098 case TOMOYO_TYPE_RENAME: 883 case TOMOYO_TYPE_RENAME:
1099 case TOMOYO_TYPE_LINK: 884 case TOMOYO_TYPE_LINK:
1100 dentry = path1->dentry; 885 dentry = path1->dentry;
1101 if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode)) 886 if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode))
1102 break; 887 break;
1103 /* fall through */ 888 /* fall through */
1104 case TOMOYO_TYPE_PIVOT_ROOT: 889 case TOMOYO_TYPE_PIVOT_ROOT:
1105 tomoyo_add_slash(&buf1); 890 tomoyo_add_slash(&buf1);
1106 tomoyo_add_slash(&buf2); 891 tomoyo_add_slash(&buf2);
1107 break; 892 break;
1108 } 893 }
894 r.obj = &obj;
1109 r.param_type = TOMOYO_TYPE_PATH2_ACL; 895 r.param_type = TOMOYO_TYPE_PATH2_ACL;
1110 r.param.path2.operation = operation; 896 r.param.path2.operation = operation;
1111 r.param.path2.filename1 = &buf1; 897 r.param.path2.filename1 = &buf1;
@@ -1124,53 +910,91 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1124} 910}
1125 911
1126/** 912/**
913 * tomoyo_same_mount_acl - Check for duplicated "struct tomoyo_mount_acl" entry.
914 *
915 * @a: Pointer to "struct tomoyo_acl_info".
916 * @b: Pointer to "struct tomoyo_acl_info".
917 *
918 * Returns true if @a == @b, false otherwise.
919 */
920static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a,
921 const struct tomoyo_acl_info *b)
922{
923 const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head);
924 const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head);
925 return tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
926 tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) &&
927 tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) &&
928 tomoyo_same_number_union(&p1->flags, &p2->flags);
929}
930
931/**
932 * tomoyo_update_mount_acl - Write "struct tomoyo_mount_acl" list.
933 *
934 * @param: Pointer to "struct tomoyo_acl_param".
935 *
936 * Returns 0 on success, negative value otherwise.
937 *
938 * Caller holds tomoyo_read_lock().
939 */
940static int tomoyo_update_mount_acl(struct tomoyo_acl_param *param)
941{
942 struct tomoyo_mount_acl e = { .head.type = TOMOYO_TYPE_MOUNT_ACL };
943 int error;
944 if (!tomoyo_parse_name_union(param, &e.dev_name) ||
945 !tomoyo_parse_name_union(param, &e.dir_name) ||
946 !tomoyo_parse_name_union(param, &e.fs_type) ||
947 !tomoyo_parse_number_union(param, &e.flags))
948 error = -EINVAL;
949 else
950 error = tomoyo_update_domain(&e.head, sizeof(e), param,
951 tomoyo_same_mount_acl, NULL);
952 tomoyo_put_name_union(&e.dev_name);
953 tomoyo_put_name_union(&e.dir_name);
954 tomoyo_put_name_union(&e.fs_type);
955 tomoyo_put_number_union(&e.flags);
956 return error;
957}
958
959/**
1127 * tomoyo_write_file - Update file related list. 960 * tomoyo_write_file - Update file related list.
1128 * 961 *
1129 * @data: String to parse. 962 * @param: Pointer to "struct tomoyo_acl_param".
1130 * @domain: Pointer to "struct tomoyo_domain_info".
1131 * @is_delete: True if it is a delete request.
1132 * 963 *
1133 * Returns 0 on success, negative value otherwise. 964 * Returns 0 on success, negative value otherwise.
1134 * 965 *
1135 * Caller holds tomoyo_read_lock(). 966 * Caller holds tomoyo_read_lock().
1136 */ 967 */
1137int tomoyo_write_file(char *data, struct tomoyo_domain_info *domain, 968int tomoyo_write_file(struct tomoyo_acl_param *param)
1138 const bool is_delete)
1139{ 969{
1140 char *w[5]; 970 u16 perm = 0;
1141 u8 type; 971 u8 type;
1142 if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0]) 972 const char *operation = tomoyo_read_token(param);
1143 return -EINVAL; 973 for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++)
1144 if (strncmp(w[0], "allow_", 6)) 974 if (tomoyo_permstr(operation, tomoyo_path_keyword[type]))
1145 goto out; 975 perm |= 1 << type;
1146 w[0] += 6; 976 if (perm)
1147 for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) { 977 return tomoyo_update_path_acl(perm, param);
1148 if (strcmp(w[0], tomoyo_path_keyword[type])) 978 for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++)
1149 continue; 979 if (tomoyo_permstr(operation,
1150 return tomoyo_update_path_acl(type, w[1], domain, is_delete); 980 tomoyo_mac_keywords[tomoyo_pp2mac[type]]))
1151 } 981 perm |= 1 << type;
1152 if (!w[2][0]) 982 if (perm)
1153 goto out; 983 return tomoyo_update_path2_acl(perm, param);
1154 for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) { 984 for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++)
1155 if (strcmp(w[0], tomoyo_path2_keyword[type])) 985 if (tomoyo_permstr(operation,
1156 continue; 986 tomoyo_mac_keywords[tomoyo_pn2mac[type]]))
1157 return tomoyo_update_path2_acl(type, w[1], w[2], domain, 987 perm |= 1 << type;
1158 is_delete); 988 if (perm)
1159 } 989 return tomoyo_update_path_number_acl(perm, param);
1160 for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++) { 990 for (type = 0; type < TOMOYO_MAX_MKDEV_OPERATION; type++)
1161 if (strcmp(w[0], tomoyo_path_number_keyword[type])) 991 if (tomoyo_permstr(operation,
1162 continue; 992 tomoyo_mac_keywords[tomoyo_pnnn2mac[type]]))
1163 return tomoyo_update_path_number_acl(type, w[1], w[2], domain, 993 perm |= 1 << type;
1164 is_delete); 994 if (perm)
1165 } 995 return tomoyo_update_mkdev_acl(perm, param);
1166 if (!w[3][0] || !w[4][0]) 996 if (tomoyo_permstr(operation,
1167 goto out; 997 tomoyo_mac_keywords[TOMOYO_MAC_FILE_MOUNT]))
1168 for (type = 0; type < TOMOYO_MAX_MKDEV_OPERATION; type++) { 998 return tomoyo_update_mount_acl(param);
1169 if (strcmp(w[0], tomoyo_mkdev_keyword[type]))
1170 continue;
1171 return tomoyo_update_mkdev_acl(type, w[1], w[2], w[3],
1172 w[4], domain, is_delete);
1173 }
1174 out:
1175 return -EINVAL; 999 return -EINVAL;
1176} 1000}
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index a877e4c3b10..ae135fbbbe9 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -1,58 +1,205 @@
1/* 1/*
2 * security/tomoyo/gc.c 2 * security/tomoyo/gc.c
3 * 3 *
4 * Implementation of the Domain-Based Mandatory Access Control. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 *
8 */ 5 */
9 6
10#include "common.h" 7#include "common.h"
11#include <linux/kthread.h> 8#include <linux/kthread.h>
12#include <linux/slab.h> 9#include <linux/slab.h>
13 10
11/* The list for "struct tomoyo_io_buffer". */
12static LIST_HEAD(tomoyo_io_buffer_list);
13/* Lock for protecting tomoyo_io_buffer_list. */
14static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
15
16/* Size of an element. */
17static const u8 tomoyo_element_size[TOMOYO_MAX_POLICY] = {
18 [TOMOYO_ID_GROUP] = sizeof(struct tomoyo_group),
19 [TOMOYO_ID_PATH_GROUP] = sizeof(struct tomoyo_path_group),
20 [TOMOYO_ID_NUMBER_GROUP] = sizeof(struct tomoyo_number_group),
21 [TOMOYO_ID_AGGREGATOR] = sizeof(struct tomoyo_aggregator),
22 [TOMOYO_ID_TRANSITION_CONTROL] =
23 sizeof(struct tomoyo_transition_control),
24 [TOMOYO_ID_MANAGER] = sizeof(struct tomoyo_manager),
25 /* [TOMOYO_ID_CONDITION] = "struct tomoyo_condition"->size, */
26 /* [TOMOYO_ID_NAME] = "struct tomoyo_name"->size, */
27 /* [TOMOYO_ID_ACL] =
28 tomoyo_acl_size["struct tomoyo_acl_info"->type], */
29 [TOMOYO_ID_DOMAIN] = sizeof(struct tomoyo_domain_info),
30};
31
32/* Size of a domain ACL element. */
33static const u8 tomoyo_acl_size[] = {
34 [TOMOYO_TYPE_PATH_ACL] = sizeof(struct tomoyo_path_acl),
35 [TOMOYO_TYPE_PATH2_ACL] = sizeof(struct tomoyo_path2_acl),
36 [TOMOYO_TYPE_PATH_NUMBER_ACL] = sizeof(struct tomoyo_path_number_acl),
37 [TOMOYO_TYPE_MKDEV_ACL] = sizeof(struct tomoyo_mkdev_acl),
38 [TOMOYO_TYPE_MOUNT_ACL] = sizeof(struct tomoyo_mount_acl),
39};
40
41/**
42 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not.
43 *
44 * @element: Pointer to "struct list_head".
45 *
46 * Returns true if @element is used by /sys/kernel/security/tomoyo/ users,
47 * false otherwise.
48 */
49static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element)
50{
51 struct tomoyo_io_buffer *head;
52 bool in_use = false;
53
54 spin_lock(&tomoyo_io_buffer_list_lock);
55 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
56 head->users++;
57 spin_unlock(&tomoyo_io_buffer_list_lock);
58 if (mutex_lock_interruptible(&head->io_sem)) {
59 in_use = true;
60 goto out;
61 }
62 if (head->r.domain == element || head->r.group == element ||
63 head->r.acl == element || &head->w.domain->list == element)
64 in_use = true;
65 mutex_unlock(&head->io_sem);
66out:
67 spin_lock(&tomoyo_io_buffer_list_lock);
68 head->users--;
69 if (in_use)
70 break;
71 }
72 spin_unlock(&tomoyo_io_buffer_list_lock);
73 return in_use;
74}
75
76/**
77 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not.
78 *
79 * @string: String to check.
80 * @size: Memory allocated for @string .
81 *
82 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users,
83 * false otherwise.
84 */
85static bool tomoyo_name_used_by_io_buffer(const char *string,
86 const size_t size)
87{
88 struct tomoyo_io_buffer *head;
89 bool in_use = false;
90
91 spin_lock(&tomoyo_io_buffer_list_lock);
92 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
93 int i;
94 head->users++;
95 spin_unlock(&tomoyo_io_buffer_list_lock);
96 if (mutex_lock_interruptible(&head->io_sem)) {
97 in_use = true;
98 goto out;
99 }
100 for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
101 const char *w = head->r.w[i];
102 if (w < string || w > string + size)
103 continue;
104 in_use = true;
105 break;
106 }
107 mutex_unlock(&head->io_sem);
108out:
109 spin_lock(&tomoyo_io_buffer_list_lock);
110 head->users--;
111 if (in_use)
112 break;
113 }
114 spin_unlock(&tomoyo_io_buffer_list_lock);
115 return in_use;
116}
117
118/* Structure for garbage collection. */
14struct tomoyo_gc { 119struct tomoyo_gc {
15 struct list_head list; 120 struct list_head list;
16 int type; 121 enum tomoyo_policy_id type;
122 size_t size;
17 struct list_head *element; 123 struct list_head *element;
18}; 124};
19static LIST_HEAD(tomoyo_gc_queue); 125/* List of entries to be deleted. */
20static DEFINE_MUTEX(tomoyo_gc_mutex); 126static LIST_HEAD(tomoyo_gc_list);
127/* Length of tomoyo_gc_list. */
128static int tomoyo_gc_list_len;
21 129
22/* Caller holds tomoyo_policy_lock mutex. */ 130/**
131 * tomoyo_add_to_gc - Add an entry to to be deleted list.
132 *
133 * @type: One of values in "enum tomoyo_policy_id".
134 * @element: Pointer to "struct list_head".
135 *
136 * Returns true on success, false otherwise.
137 *
138 * Caller holds tomoyo_policy_lock mutex.
139 *
140 * Adding an entry needs kmalloc(). Thus, if we try to add thousands of
141 * entries at once, it will take too long time. Thus, do not add more than 128
142 * entries per a scan. But to be able to handle worst case where all entries
143 * are in-use, we accept one more entry per a scan.
144 *
145 * If we use singly linked list using "struct list_head"->prev (which is
146 * LIST_POISON2), we can avoid kmalloc().
147 */
23static bool tomoyo_add_to_gc(const int type, struct list_head *element) 148static bool tomoyo_add_to_gc(const int type, struct list_head *element)
24{ 149{
25 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 150 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
26 if (!entry) 151 if (!entry)
27 return false; 152 return false;
28 entry->type = type; 153 entry->type = type;
154 if (type == TOMOYO_ID_ACL)
155 entry->size = tomoyo_acl_size[
156 container_of(element,
157 typeof(struct tomoyo_acl_info),
158 list)->type];
159 else if (type == TOMOYO_ID_NAME)
160 entry->size = strlen(container_of(element,
161 typeof(struct tomoyo_name),
162 head.list)->entry.name) + 1;
163 else if (type == TOMOYO_ID_CONDITION)
164 entry->size =
165 container_of(element, typeof(struct tomoyo_condition),
166 head.list)->size;
167 else
168 entry->size = tomoyo_element_size[type];
29 entry->element = element; 169 entry->element = element;
30 list_add(&entry->list, &tomoyo_gc_queue); 170 list_add(&entry->list, &tomoyo_gc_list);
31 list_del_rcu(element); 171 list_del_rcu(element);
32 return true; 172 return tomoyo_gc_list_len++ < 128;
33} 173}
34 174
35static void tomoyo_del_allow_read(struct list_head *element) 175/**
36{ 176 * tomoyo_element_linked_by_gc - Validate next element of an entry.
37 struct tomoyo_readable_file *ptr = 177 *
38 container_of(element, typeof(*ptr), head.list); 178 * @element: Pointer to an element.
39 tomoyo_put_name(ptr->filename); 179 * @size: Size of @element in byte.
40} 180 *
41 181 * Returns true if @element is linked by other elements in the garbage
42static void tomoyo_del_file_pattern(struct list_head *element) 182 * collector's queue, false otherwise.
43{ 183 */
44 struct tomoyo_no_pattern *ptr = 184static bool tomoyo_element_linked_by_gc(const u8 *element, const size_t size)
45 container_of(element, typeof(*ptr), head.list);
46 tomoyo_put_name(ptr->pattern);
47}
48
49static void tomoyo_del_no_rewrite(struct list_head *element)
50{ 185{
51 struct tomoyo_no_rewrite *ptr = 186 struct tomoyo_gc *p;
52 container_of(element, typeof(*ptr), head.list); 187 list_for_each_entry(p, &tomoyo_gc_list, list) {
53 tomoyo_put_name(ptr->pattern); 188 const u8 *ptr = (const u8 *) p->element->next;
189 if (ptr < element || element + size < ptr)
190 continue;
191 return true;
192 }
193 return false;
54} 194}
55 195
196/**
197 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
198 *
199 * @element: Pointer to "struct list_head".
200 *
201 * Returns nothing.
202 */
56static void tomoyo_del_transition_control(struct list_head *element) 203static void tomoyo_del_transition_control(struct list_head *element)
57{ 204{
58 struct tomoyo_transition_control *ptr = 205 struct tomoyo_transition_control *ptr =
@@ -61,6 +208,13 @@ static void tomoyo_del_transition_control(struct list_head *element)
61 tomoyo_put_name(ptr->program); 208 tomoyo_put_name(ptr->program);
62} 209}
63 210
211/**
212 * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator".
213 *
214 * @element: Pointer to "struct list_head".
215 *
216 * Returns nothing.
217 */
64static void tomoyo_del_aggregator(struct list_head *element) 218static void tomoyo_del_aggregator(struct list_head *element)
65{ 219{
66 struct tomoyo_aggregator *ptr = 220 struct tomoyo_aggregator *ptr =
@@ -69,6 +223,13 @@ static void tomoyo_del_aggregator(struct list_head *element)
69 tomoyo_put_name(ptr->aggregated_name); 223 tomoyo_put_name(ptr->aggregated_name);
70} 224}
71 225
226/**
227 * tomoyo_del_manager - Delete members in "struct tomoyo_manager".
228 *
229 * @element: Pointer to "struct list_head".
230 *
231 * Returns nothing.
232 */
72static void tomoyo_del_manager(struct list_head *element) 233static void tomoyo_del_manager(struct list_head *element)
73{ 234{
74 struct tomoyo_manager *ptr = 235 struct tomoyo_manager *ptr =
@@ -76,10 +237,18 @@ static void tomoyo_del_manager(struct list_head *element)
76 tomoyo_put_name(ptr->manager); 237 tomoyo_put_name(ptr->manager);
77} 238}
78 239
240/**
241 * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info".
242 *
243 * @element: Pointer to "struct list_head".
244 *
245 * Returns nothing.
246 */
79static void tomoyo_del_acl(struct list_head *element) 247static void tomoyo_del_acl(struct list_head *element)
80{ 248{
81 struct tomoyo_acl_info *acl = 249 struct tomoyo_acl_info *acl =
82 container_of(element, typeof(*acl), list); 250 container_of(element, typeof(*acl), list);
251 tomoyo_put_condition(acl->cond);
83 switch (acl->type) { 252 switch (acl->type) {
84 case TOMOYO_TYPE_PATH_ACL: 253 case TOMOYO_TYPE_PATH_ACL:
85 { 254 {
@@ -127,6 +296,13 @@ static void tomoyo_del_acl(struct list_head *element)
127 } 296 }
128} 297}
129 298
299/**
300 * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info".
301 *
302 * @element: Pointer to "struct list_head".
303 *
304 * Returns true if deleted, false otherwise.
305 */
130static bool tomoyo_del_domain(struct list_head *element) 306static bool tomoyo_del_domain(struct list_head *element)
131{ 307{
132 struct tomoyo_domain_info *domain = 308 struct tomoyo_domain_info *domain =
@@ -165,13 +341,65 @@ static bool tomoyo_del_domain(struct list_head *element)
165 return true; 341 return true;
166} 342}
167 343
344/**
345 * tomoyo_del_condition - Delete members in "struct tomoyo_condition".
346 *
347 * @element: Pointer to "struct list_head".
348 *
349 * Returns nothing.
350 */
351void tomoyo_del_condition(struct list_head *element)
352{
353 struct tomoyo_condition *cond = container_of(element, typeof(*cond),
354 head.list);
355 const u16 condc = cond->condc;
356 const u16 numbers_count = cond->numbers_count;
357 const u16 names_count = cond->names_count;
358 const u16 argc = cond->argc;
359 const u16 envc = cond->envc;
360 unsigned int i;
361 const struct tomoyo_condition_element *condp
362 = (const struct tomoyo_condition_element *) (cond + 1);
363 struct tomoyo_number_union *numbers_p
364 = (struct tomoyo_number_union *) (condp + condc);
365 struct tomoyo_name_union *names_p
366 = (struct tomoyo_name_union *) (numbers_p + numbers_count);
367 const struct tomoyo_argv *argv
368 = (const struct tomoyo_argv *) (names_p + names_count);
369 const struct tomoyo_envp *envp
370 = (const struct tomoyo_envp *) (argv + argc);
371 for (i = 0; i < numbers_count; i++)
372 tomoyo_put_number_union(numbers_p++);
373 for (i = 0; i < names_count; i++)
374 tomoyo_put_name_union(names_p++);
375 for (i = 0; i < argc; argv++, i++)
376 tomoyo_put_name(argv->value);
377 for (i = 0; i < envc; envp++, i++) {
378 tomoyo_put_name(envp->name);
379 tomoyo_put_name(envp->value);
380 }
381}
168 382
383/**
384 * tomoyo_del_name - Delete members in "struct tomoyo_name".
385 *
386 * @element: Pointer to "struct list_head".
387 *
388 * Returns nothing.
389 */
169static void tomoyo_del_name(struct list_head *element) 390static void tomoyo_del_name(struct list_head *element)
170{ 391{
171 const struct tomoyo_name *ptr = 392 const struct tomoyo_name *ptr =
172 container_of(element, typeof(*ptr), list); 393 container_of(element, typeof(*ptr), head.list);
173} 394}
174 395
396/**
397 * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group".
398 *
399 * @element: Pointer to "struct list_head".
400 *
401 * Returns nothing.
402 */
175static void tomoyo_del_path_group(struct list_head *element) 403static void tomoyo_del_path_group(struct list_head *element)
176{ 404{
177 struct tomoyo_path_group *member = 405 struct tomoyo_path_group *member =
@@ -179,20 +407,43 @@ static void tomoyo_del_path_group(struct list_head *element)
179 tomoyo_put_name(member->member_name); 407 tomoyo_put_name(member->member_name);
180} 408}
181 409
410/**
411 * tomoyo_del_group - Delete "struct tomoyo_group".
412 *
413 * @element: Pointer to "struct list_head".
414 *
415 * Returns nothing.
416 */
182static void tomoyo_del_group(struct list_head *element) 417static void tomoyo_del_group(struct list_head *element)
183{ 418{
184 struct tomoyo_group *group = 419 struct tomoyo_group *group =
185 container_of(element, typeof(*group), list); 420 container_of(element, typeof(*group), head.list);
186 tomoyo_put_name(group->group_name); 421 tomoyo_put_name(group->group_name);
187} 422}
188 423
424/**
425 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
426 *
427 * @element: Pointer to "struct list_head".
428 *
429 * Returns nothing.
430 */
189static void tomoyo_del_number_group(struct list_head *element) 431static void tomoyo_del_number_group(struct list_head *element)
190{ 432{
191 struct tomoyo_number_group *member = 433 struct tomoyo_number_group *member =
192 container_of(element, typeof(*member), head.list); 434 container_of(element, typeof(*member), head.list);
193} 435}
194 436
195static bool tomoyo_collect_member(struct list_head *member_list, int id) 437/**
438 * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head".
439 *
440 * @id: One of values in "enum tomoyo_policy_id".
441 * @member_list: Pointer to "struct list_head".
442 *
443 * Returns true if some elements are deleted, false otherwise.
444 */
445static bool tomoyo_collect_member(const enum tomoyo_policy_id id,
446 struct list_head *member_list)
196{ 447{
197 struct tomoyo_acl_head *member; 448 struct tomoyo_acl_head *member;
198 list_for_each_entry(member, member_list, list) { 449 list_for_each_entry(member, member_list, list) {
@@ -201,13 +452,20 @@ static bool tomoyo_collect_member(struct list_head *member_list, int id)
201 if (!tomoyo_add_to_gc(id, &member->list)) 452 if (!tomoyo_add_to_gc(id, &member->list))
202 return false; 453 return false;
203 } 454 }
204 return true; 455 return true;
205} 456}
206 457
207static bool tomoyo_collect_acl(struct tomoyo_domain_info *domain) 458/**
459 * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info".
460 *
461 * @list: Pointer to "struct list_head".
462 *
463 * Returns true if some elements are deleted, false otherwise.
464 */
465static bool tomoyo_collect_acl(struct list_head *list)
208{ 466{
209 struct tomoyo_acl_info *acl; 467 struct tomoyo_acl_info *acl;
210 list_for_each_entry(acl, &domain->acl_info_list, list) { 468 list_for_each_entry(acl, list, list) {
211 if (!acl->is_deleted) 469 if (!acl->is_deleted)
212 continue; 470 continue;
213 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list)) 471 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list))
@@ -216,19 +474,24 @@ static bool tomoyo_collect_acl(struct tomoyo_domain_info *domain)
216 return true; 474 return true;
217} 475}
218 476
477/**
478 * tomoyo_collect_entry - Scan lists for deleted elements.
479 *
480 * Returns nothing.
481 */
219static void tomoyo_collect_entry(void) 482static void tomoyo_collect_entry(void)
220{ 483{
221 int i; 484 int i;
485 enum tomoyo_policy_id id;
486 struct tomoyo_policy_namespace *ns;
487 int idx;
222 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 488 if (mutex_lock_interruptible(&tomoyo_policy_lock))
223 return; 489 return;
224 for (i = 0; i < TOMOYO_MAX_POLICY; i++) { 490 idx = tomoyo_read_lock();
225 if (!tomoyo_collect_member(&tomoyo_policy_list[i], i))
226 goto unlock;
227 }
228 { 491 {
229 struct tomoyo_domain_info *domain; 492 struct tomoyo_domain_info *domain;
230 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 493 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
231 if (!tomoyo_collect_acl(domain)) 494 if (!tomoyo_collect_acl(&domain->acl_info_list))
232 goto unlock; 495 goto unlock;
233 if (!domain->is_deleted || atomic_read(&domain->users)) 496 if (!domain->is_deleted || atomic_read(&domain->users))
234 continue; 497 continue;
@@ -241,48 +504,93 @@ static void tomoyo_collect_entry(void)
241 goto unlock; 504 goto unlock;
242 } 505 }
243 } 506 }
244 for (i = 0; i < TOMOYO_MAX_HASH; i++) { 507 list_for_each_entry_rcu(ns, &tomoyo_namespace_list, namespace_list) {
245 struct tomoyo_name *ptr; 508 for (id = 0; id < TOMOYO_MAX_POLICY; id++)
246 list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], list) { 509 if (!tomoyo_collect_member(id, &ns->policy_list[id]))
247 if (atomic_read(&ptr->users))
248 continue;
249 if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->list))
250 goto unlock; 510 goto unlock;
511 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
512 if (!tomoyo_collect_acl(&ns->acl_group[i]))
513 goto unlock;
514 for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
515 struct list_head *list = &ns->group_list[i];
516 struct tomoyo_group *group;
517 switch (i) {
518 case 0:
519 id = TOMOYO_ID_PATH_GROUP;
520 break;
521 default:
522 id = TOMOYO_ID_NUMBER_GROUP;
523 break;
524 }
525 list_for_each_entry(group, list, head.list) {
526 if (!tomoyo_collect_member
527 (id, &group->member_list))
528 goto unlock;
529 if (!list_empty(&group->member_list) ||
530 atomic_read(&group->head.users))
531 continue;
532 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP,
533 &group->head.list))
534 goto unlock;
535 }
251 } 536 }
252 } 537 }
253 for (i = 0; i < TOMOYO_MAX_GROUP; i++) { 538 id = TOMOYO_ID_CONDITION;
254 struct list_head *list = &tomoyo_group_list[i]; 539 for (i = 0; i < TOMOYO_MAX_HASH + 1; i++) {
255 int id; 540 struct list_head *list = !i ?
256 struct tomoyo_group *group; 541 &tomoyo_condition_list : &tomoyo_name_list[i - 1];
257 switch (i) { 542 struct tomoyo_shared_acl_head *ptr;
258 case 0: 543 list_for_each_entry(ptr, list, list) {
259 id = TOMOYO_ID_PATH_GROUP; 544 if (atomic_read(&ptr->users))
260 break;
261 default:
262 id = TOMOYO_ID_NUMBER_GROUP;
263 break;
264 }
265 list_for_each_entry(group, list, list) {
266 if (!tomoyo_collect_member(&group->member_list, id))
267 goto unlock;
268 if (!list_empty(&group->member_list) ||
269 atomic_read(&group->users))
270 continue; 545 continue;
271 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP, &group->list)) 546 if (!tomoyo_add_to_gc(id, &ptr->list))
272 goto unlock; 547 goto unlock;
273 } 548 }
549 id = TOMOYO_ID_NAME;
274 } 550 }
275 unlock: 551unlock:
552 tomoyo_read_unlock(idx);
276 mutex_unlock(&tomoyo_policy_lock); 553 mutex_unlock(&tomoyo_policy_lock);
277} 554}
278 555
279static void tomoyo_kfree_entry(void) 556/**
557 * tomoyo_kfree_entry - Delete entries in tomoyo_gc_list.
558 *
559 * Returns true if some entries were kfree()d, false otherwise.
560 */
561static bool tomoyo_kfree_entry(void)
280{ 562{
281 struct tomoyo_gc *p; 563 struct tomoyo_gc *p;
282 struct tomoyo_gc *tmp; 564 struct tomoyo_gc *tmp;
565 bool result = false;
283 566
284 list_for_each_entry_safe(p, tmp, &tomoyo_gc_queue, list) { 567 list_for_each_entry_safe(p, tmp, &tomoyo_gc_list, list) {
285 struct list_head *element = p->element; 568 struct list_head *element = p->element;
569
570 /*
571 * list_del_rcu() in tomoyo_add_to_gc() guarantees that the
572 * list element became no longer reachable from the list which
573 * the element was originally on (e.g. tomoyo_domain_list).
574 * Also, synchronize_srcu() in tomoyo_gc_thread() guarantees
575 * that the list element became no longer referenced by syscall
576 * users.
577 *
578 * However, there are three users which may still be using the
579 * list element. We need to defer until all of these users
580 * forget the list element.
581 *
582 * Firstly, defer until "struct tomoyo_io_buffer"->r.{domain,
583 * group,acl} and "struct tomoyo_io_buffer"->w.domain forget
584 * the list element.
585 */
586 if (tomoyo_struct_used_by_io_buffer(element))
587 continue;
588 /*
589 * Secondly, defer until all other elements in the
590 * tomoyo_gc_list list forget the list element.
591 */
592 if (tomoyo_element_linked_by_gc((const u8 *) element, p->size))
593 continue;
286 switch (p->type) { 594 switch (p->type) {
287 case TOMOYO_ID_TRANSITION_CONTROL: 595 case TOMOYO_ID_TRANSITION_CONTROL:
288 tomoyo_del_transition_control(element); 596 tomoyo_del_transition_control(element);
@@ -290,19 +598,21 @@ static void tomoyo_kfree_entry(void)
290 case TOMOYO_ID_AGGREGATOR: 598 case TOMOYO_ID_AGGREGATOR:
291 tomoyo_del_aggregator(element); 599 tomoyo_del_aggregator(element);
292 break; 600 break;
293 case TOMOYO_ID_GLOBALLY_READABLE:
294 tomoyo_del_allow_read(element);
295 break;
296 case TOMOYO_ID_PATTERN:
297 tomoyo_del_file_pattern(element);
298 break;
299 case TOMOYO_ID_NO_REWRITE:
300 tomoyo_del_no_rewrite(element);
301 break;
302 case TOMOYO_ID_MANAGER: 601 case TOMOYO_ID_MANAGER:
303 tomoyo_del_manager(element); 602 tomoyo_del_manager(element);
304 break; 603 break;
604 case TOMOYO_ID_CONDITION:
605 tomoyo_del_condition(element);
606 break;
305 case TOMOYO_ID_NAME: 607 case TOMOYO_ID_NAME:
608 /*
609 * Thirdly, defer until all "struct tomoyo_io_buffer"
610 * ->r.w[] forget the list element.
611 */
612 if (tomoyo_name_used_by_io_buffer(
613 container_of(element, typeof(struct tomoyo_name),
614 head.list)->entry.name, p->size))
615 continue;
306 tomoyo_del_name(element); 616 tomoyo_del_name(element);
307 break; 617 break;
308 case TOMOYO_ID_ACL: 618 case TOMOYO_ID_ACL:
@@ -321,34 +631,95 @@ static void tomoyo_kfree_entry(void)
321 case TOMOYO_ID_NUMBER_GROUP: 631 case TOMOYO_ID_NUMBER_GROUP:
322 tomoyo_del_number_group(element); 632 tomoyo_del_number_group(element);
323 break; 633 break;
634 case TOMOYO_MAX_POLICY:
635 break;
324 } 636 }
325 tomoyo_memory_free(element); 637 tomoyo_memory_free(element);
326 list_del(&p->list); 638 list_del(&p->list);
327 kfree(p); 639 kfree(p);
640 tomoyo_gc_list_len--;
641 result = true;
328 } 642 }
643 return result;
329} 644}
330 645
646/**
647 * tomoyo_gc_thread - Garbage collector thread function.
648 *
649 * @unused: Unused.
650 *
651 * In case OOM-killer choose this thread for termination, we create this thread
652 * as a short live thread whenever /sys/kernel/security/tomoyo/ interface was
653 * close()d.
654 *
655 * Returns 0.
656 */
331static int tomoyo_gc_thread(void *unused) 657static int tomoyo_gc_thread(void *unused)
332{ 658{
659 /* Garbage collector thread is exclusive. */
660 static DEFINE_MUTEX(tomoyo_gc_mutex);
661 if (!mutex_trylock(&tomoyo_gc_mutex))
662 goto out;
333 daemonize("GC for TOMOYO"); 663 daemonize("GC for TOMOYO");
334 if (mutex_trylock(&tomoyo_gc_mutex)) { 664 do {
335 int i; 665 tomoyo_collect_entry();
336 for (i = 0; i < 10; i++) { 666 if (list_empty(&tomoyo_gc_list))
337 tomoyo_collect_entry(); 667 break;
338 if (list_empty(&tomoyo_gc_queue)) 668 synchronize_srcu(&tomoyo_ss);
339 break; 669 } while (tomoyo_kfree_entry());
340 synchronize_srcu(&tomoyo_ss); 670 {
341 tomoyo_kfree_entry(); 671 struct tomoyo_io_buffer *head;
672 struct tomoyo_io_buffer *tmp;
673
674 spin_lock(&tomoyo_io_buffer_list_lock);
675 list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list,
676 list) {
677 if (head->users)
678 continue;
679 list_del(&head->list);
680 kfree(head->read_buf);
681 kfree(head->write_buf);
682 kfree(head);
342 } 683 }
343 mutex_unlock(&tomoyo_gc_mutex); 684 spin_unlock(&tomoyo_io_buffer_list_lock);
344 } 685 }
345 do_exit(0); 686 mutex_unlock(&tomoyo_gc_mutex);
687out:
688 /* This acts as do_exit(0). */
689 return 0;
346} 690}
347 691
348void tomoyo_run_gc(void) 692/**
693 * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users.
694 *
695 * @head: Pointer to "struct tomoyo_io_buffer".
696 * @is_register: True if register, false if unregister.
697 *
698 * Returns nothing.
699 */
700void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register)
349{ 701{
350 struct task_struct *task = kthread_create(tomoyo_gc_thread, NULL, 702 bool is_write = false;
351 "GC for TOMOYO"); 703
352 if (!IS_ERR(task)) 704 spin_lock(&tomoyo_io_buffer_list_lock);
353 wake_up_process(task); 705 if (is_register) {
706 head->users = 1;
707 list_add(&head->list, &tomoyo_io_buffer_list);
708 } else {
709 is_write = head->write_buf != NULL;
710 if (!--head->users) {
711 list_del(&head->list);
712 kfree(head->read_buf);
713 kfree(head->write_buf);
714 kfree(head);
715 }
716 }
717 spin_unlock(&tomoyo_io_buffer_list_lock);
718 if (is_write) {
719 struct task_struct *task = kthread_create(tomoyo_gc_thread,
720 NULL,
721 "GC for TOMOYO");
722 if (!IS_ERR(task))
723 wake_up_process(task);
724 }
354} 725}
diff --git a/security/tomoyo/group.c b/security/tomoyo/group.c
index e94352ce723..5fb0e129840 100644
--- a/security/tomoyo/group.c
+++ b/security/tomoyo/group.c
@@ -1,21 +1,37 @@
1/* 1/*
2 * security/tomoyo/group.c 2 * security/tomoyo/group.c
3 * 3 *
4 * Copyright (C) 2005-2010 NTT DATA CORPORATION 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */ 5 */
6 6
7#include <linux/slab.h> 7#include <linux/slab.h>
8#include "common.h" 8#include "common.h"
9 9
10/**
11 * tomoyo_same_path_group - Check for duplicated "struct tomoyo_path_group" entry.
12 *
13 * @a: Pointer to "struct tomoyo_acl_head".
14 * @b: Pointer to "struct tomoyo_acl_head".
15 *
16 * Returns true if @a == @b, false otherwise.
17 */
10static bool tomoyo_same_path_group(const struct tomoyo_acl_head *a, 18static bool tomoyo_same_path_group(const struct tomoyo_acl_head *a,
11 const struct tomoyo_acl_head *b) 19 const struct tomoyo_acl_head *b)
12{ 20{
13 return container_of(a, struct tomoyo_path_group, head)->member_name == 21 return container_of(a, struct tomoyo_path_group, head)->member_name ==
14 container_of(b, struct tomoyo_path_group, head)->member_name; 22 container_of(b, struct tomoyo_path_group, head)->member_name;
15} 23}
16 24
25/**
26 * tomoyo_same_number_group - Check for duplicated "struct tomoyo_number_group" entry.
27 *
28 * @a: Pointer to "struct tomoyo_acl_head".
29 * @b: Pointer to "struct tomoyo_acl_head".
30 *
31 * Returns true if @a == @b, false otherwise.
32 */
17static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a, 33static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a,
18 const struct tomoyo_acl_head *b) 34 const struct tomoyo_acl_head *b)
19{ 35{
20 return !memcmp(&container_of(a, struct tomoyo_number_group, head) 36 return !memcmp(&container_of(a, struct tomoyo_number_group, head)
21 ->number, 37 ->number,
@@ -28,48 +44,41 @@ static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a,
28/** 44/**
29 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list. 45 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list.
30 * 46 *
31 * @data: String to parse. 47 * @param: Pointer to "struct tomoyo_acl_param".
32 * @is_delete: True if it is a delete request. 48 * @type: Type of this group.
33 * @type: Type of this group.
34 * 49 *
35 * Returns 0 on success, negative value otherwise. 50 * Returns 0 on success, negative value otherwise.
36 */ 51 */
37int tomoyo_write_group(char *data, const bool is_delete, const u8 type) 52int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type)
38{ 53{
39 struct tomoyo_group *group; 54 struct tomoyo_group *group = tomoyo_get_group(param, type);
40 struct list_head *member;
41 char *w[2];
42 int error = -EINVAL; 55 int error = -EINVAL;
43 if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0])
44 return -EINVAL;
45 group = tomoyo_get_group(w[0], type);
46 if (!group) 56 if (!group)
47 return -ENOMEM; 57 return -ENOMEM;
48 member = &group->member_list; 58 param->list = &group->member_list;
49 if (type == TOMOYO_PATH_GROUP) { 59 if (type == TOMOYO_PATH_GROUP) {
50 struct tomoyo_path_group e = { }; 60 struct tomoyo_path_group e = { };
51 e.member_name = tomoyo_get_name(w[1]); 61 e.member_name = tomoyo_get_name(tomoyo_read_token(param));
52 if (!e.member_name) { 62 if (!e.member_name) {
53 error = -ENOMEM; 63 error = -ENOMEM;
54 goto out; 64 goto out;
55 } 65 }
56 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 66 error = tomoyo_update_policy(&e.head, sizeof(e), param,
57 member, tomoyo_same_path_group); 67 tomoyo_same_path_group);
58 tomoyo_put_name(e.member_name); 68 tomoyo_put_name(e.member_name);
59 } else if (type == TOMOYO_NUMBER_GROUP) { 69 } else if (type == TOMOYO_NUMBER_GROUP) {
60 struct tomoyo_number_group e = { }; 70 struct tomoyo_number_group e = { };
61 if (w[1][0] == '@' 71 if (param->data[0] == '@' ||
62 || !tomoyo_parse_number_union(w[1], &e.number) 72 !tomoyo_parse_number_union(param, &e.number))
63 || e.number.values[0] > e.number.values[1])
64 goto out; 73 goto out;
65 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 74 error = tomoyo_update_policy(&e.head, sizeof(e), param,
66 member, tomoyo_same_number_group); 75 tomoyo_same_number_group);
67 /* 76 /*
68 * tomoyo_put_number_union() is not needed because 77 * tomoyo_put_number_union() is not needed because
69 * w[1][0] != '@'. 78 * param->data[0] != '@'.
70 */ 79 */
71 } 80 }
72 out: 81out:
73 tomoyo_put_group(group); 82 tomoyo_put_group(group);
74 return error; 83 return error;
75} 84}
@@ -77,8 +86,8 @@ int tomoyo_write_group(char *data, const bool is_delete, const u8 type)
77/** 86/**
78 * tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group. 87 * tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group.
79 * 88 *
80 * @pathname: The name of pathname. 89 * @pathname: The name of pathname.
81 * @group: Pointer to "struct tomoyo_path_group". 90 * @group: Pointer to "struct tomoyo_path_group".
82 * 91 *
83 * Returns matched member's pathname if @pathname matches pathnames in @group, 92 * Returns matched member's pathname if @pathname matches pathnames in @group,
84 * NULL otherwise. 93 * NULL otherwise.
diff --git a/security/tomoyo/load_policy.c b/security/tomoyo/load_policy.c
index 3312e5624f2..67975405140 100644
--- a/security/tomoyo/load_policy.c
+++ b/security/tomoyo/load_policy.c
@@ -1,15 +1,32 @@
1/* 1/*
2 * security/tomoyo/load_policy.c 2 * security/tomoyo/load_policy.c
3 * 3 *
4 * Policy loader launcher for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include "common.h" 7#include "common.h"
10 8
11/* path to policy loader */ 9#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
12static const char *tomoyo_loader = "/sbin/tomoyo-init"; 10
11/*
12 * Path to the policy loader. (default = CONFIG_SECURITY_TOMOYO_POLICY_LOADER)
13 */
14static const char *tomoyo_loader;
15
16/**
17 * tomoyo_loader_setup - Set policy loader.
18 *
19 * @str: Program to use as a policy loader (e.g. /sbin/tomoyo-init ).
20 *
21 * Returns 0.
22 */
23static int __init tomoyo_loader_setup(char *str)
24{
25 tomoyo_loader = str;
26 return 0;
27}
28
29__setup("TOMOYO_loader=", tomoyo_loader_setup);
13 30
14/** 31/**
15 * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists. 32 * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists.
@@ -18,24 +35,38 @@ static const char *tomoyo_loader = "/sbin/tomoyo-init";
18 */ 35 */
19static bool tomoyo_policy_loader_exists(void) 36static bool tomoyo_policy_loader_exists(void)
20{ 37{
21 /*
22 * Don't activate MAC if the policy loader doesn't exist.
23 * If the initrd includes /sbin/init but real-root-dev has not
24 * mounted on / yet, activating MAC will block the system since
25 * policies are not loaded yet.
26 * Thus, let do_execve() call this function every time.
27 */
28 struct path path; 38 struct path path;
29 39 if (!tomoyo_loader)
40 tomoyo_loader = CONFIG_SECURITY_TOMOYO_POLICY_LOADER;
30 if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) { 41 if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
31 printk(KERN_INFO "Not activating Mandatory Access Control now " 42 printk(KERN_INFO "Not activating Mandatory Access Control "
32 "since %s doesn't exist.\n", tomoyo_loader); 43 "as %s does not exist.\n", tomoyo_loader);
33 return false; 44 return false;
34 } 45 }
35 path_put(&path); 46 path_put(&path);
36 return true; 47 return true;
37} 48}
38 49
50/*
51 * Path to the trigger. (default = CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER)
52 */
53static const char *tomoyo_trigger;
54
55/**
56 * tomoyo_trigger_setup - Set trigger for activation.
57 *
58 * @str: Program to use as an activation trigger (e.g. /sbin/init ).
59 *
60 * Returns 0.
61 */
62static int __init tomoyo_trigger_setup(char *str)
63{
64 tomoyo_trigger = str;
65 return 0;
66}
67
68__setup("TOMOYO_trigger=", tomoyo_trigger_setup);
69
39/** 70/**
40 * tomoyo_load_policy - Run external policy loader to load policy. 71 * tomoyo_load_policy - Run external policy loader to load policy.
41 * 72 *
@@ -51,24 +82,19 @@ static bool tomoyo_policy_loader_exists(void)
51 */ 82 */
52void tomoyo_load_policy(const char *filename) 83void tomoyo_load_policy(const char *filename)
53{ 84{
85 static bool done;
54 char *argv[2]; 86 char *argv[2];
55 char *envp[3]; 87 char *envp[3];
56 88
57 if (tomoyo_policy_loaded) 89 if (tomoyo_policy_loaded || done)
58 return; 90 return;
59 /* 91 if (!tomoyo_trigger)
60 * Check filename is /sbin/init or /sbin/tomoyo-start. 92 tomoyo_trigger = CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER;
61 * /sbin/tomoyo-start is a dummy filename in case where /sbin/init can't 93 if (strcmp(filename, tomoyo_trigger))
62 * be passed.
63 * You can create /sbin/tomoyo-start by
64 * "ln -s /bin/true /sbin/tomoyo-start".
65 */
66 if (strcmp(filename, "/sbin/init") &&
67 strcmp(filename, "/sbin/tomoyo-start"))
68 return; 94 return;
69 if (!tomoyo_policy_loader_exists()) 95 if (!tomoyo_policy_loader_exists())
70 return; 96 return;
71 97 done = true;
72 printk(KERN_INFO "Calling %s to load policy. Please wait.\n", 98 printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
73 tomoyo_loader); 99 tomoyo_loader);
74 argv[0] = (char *) tomoyo_loader; 100 argv[0] = (char *) tomoyo_loader;
@@ -79,3 +105,5 @@ void tomoyo_load_policy(const char *filename)
79 call_usermodehelper(argv[0], argv, envp, 1); 105 call_usermodehelper(argv[0], argv, envp, 1);
80 tomoyo_check_profile(); 106 tomoyo_check_profile();
81} 107}
108
109#endif
diff --git a/security/tomoyo/memory.c b/security/tomoyo/memory.c
index 42a7b1ba8cb..7a56051146c 100644
--- a/security/tomoyo/memory.c
+++ b/security/tomoyo/memory.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * security/tomoyo/memory.c 2 * security/tomoyo/memory.c
3 * 3 *
4 * Memory management functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include <linux/hash.h> 7#include <linux/hash.h>
@@ -29,10 +27,12 @@ void tomoyo_warn_oom(const char *function)
29 panic("MAC Initialization failed.\n"); 27 panic("MAC Initialization failed.\n");
30} 28}
31 29
32/* Memory allocated for policy. */ 30/* Lock for protecting tomoyo_memory_used. */
33static atomic_t tomoyo_policy_memory_size; 31static DEFINE_SPINLOCK(tomoyo_policy_memory_lock);
34/* Quota for holding policy. */ 32/* Memoy currently used by policy/audit log/query. */
35static unsigned int tomoyo_quota_for_policy; 33unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
34/* Memory quota for "policy"/"audit log"/"query". */
35unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
36 36
37/** 37/**
38 * tomoyo_memory_ok - Check memory quota. 38 * tomoyo_memory_ok - Check memory quota.
@@ -45,15 +45,20 @@ static unsigned int tomoyo_quota_for_policy;
45 */ 45 */
46bool tomoyo_memory_ok(void *ptr) 46bool tomoyo_memory_ok(void *ptr)
47{ 47{
48 size_t s = ptr ? ksize(ptr) : 0; 48 if (ptr) {
49 atomic_add(s, &tomoyo_policy_memory_size); 49 const size_t s = ksize(ptr);
50 if (ptr && (!tomoyo_quota_for_policy || 50 bool result;
51 atomic_read(&tomoyo_policy_memory_size) 51 spin_lock(&tomoyo_policy_memory_lock);
52 <= tomoyo_quota_for_policy)) { 52 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s;
53 memset(ptr, 0, s); 53 result = !tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] ||
54 return true; 54 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] <=
55 tomoyo_memory_quota[TOMOYO_MEMORY_POLICY];
56 if (!result)
57 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
58 spin_unlock(&tomoyo_policy_memory_lock);
59 if (result)
60 return true;
55 } 61 }
56 atomic_sub(s, &tomoyo_policy_memory_size);
57 tomoyo_warn_oom(__func__); 62 tomoyo_warn_oom(__func__);
58 return false; 63 return false;
59} 64}
@@ -86,22 +91,28 @@ void *tomoyo_commit_ok(void *data, const unsigned int size)
86 */ 91 */
87void tomoyo_memory_free(void *ptr) 92void tomoyo_memory_free(void *ptr)
88{ 93{
89 atomic_sub(ksize(ptr), &tomoyo_policy_memory_size); 94 size_t s = ksize(ptr);
95 spin_lock(&tomoyo_policy_memory_lock);
96 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
97 spin_unlock(&tomoyo_policy_memory_lock);
90 kfree(ptr); 98 kfree(ptr);
91} 99}
92 100
93/** 101/**
94 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group". 102 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group".
95 * 103 *
96 * @group_name: The name of address group. 104 * @param: Pointer to "struct tomoyo_acl_param".
97 * @idx: Index number. 105 * @idx: Index number.
98 * 106 *
99 * Returns pointer to "struct tomoyo_group" on success, NULL otherwise. 107 * Returns pointer to "struct tomoyo_group" on success, NULL otherwise.
100 */ 108 */
101struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 idx) 109struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
110 const u8 idx)
102{ 111{
103 struct tomoyo_group e = { }; 112 struct tomoyo_group e = { };
104 struct tomoyo_group *group = NULL; 113 struct tomoyo_group *group = NULL;
114 struct list_head *list;
115 const char *group_name = tomoyo_read_token(param);
105 bool found = false; 116 bool found = false;
106 if (!tomoyo_correct_word(group_name) || idx >= TOMOYO_MAX_GROUP) 117 if (!tomoyo_correct_word(group_name) || idx >= TOMOYO_MAX_GROUP)
107 return NULL; 118 return NULL;
@@ -110,10 +121,11 @@ struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 idx)
110 return NULL; 121 return NULL;
111 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 122 if (mutex_lock_interruptible(&tomoyo_policy_lock))
112 goto out; 123 goto out;
113 list_for_each_entry(group, &tomoyo_group_list[idx], list) { 124 list = &param->ns->group_list[idx];
125 list_for_each_entry(group, list, head.list) {
114 if (e.group_name != group->group_name) 126 if (e.group_name != group->group_name)
115 continue; 127 continue;
116 atomic_inc(&group->users); 128 atomic_inc(&group->head.users);
117 found = true; 129 found = true;
118 break; 130 break;
119 } 131 }
@@ -121,15 +133,14 @@ struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 idx)
121 struct tomoyo_group *entry = tomoyo_commit_ok(&e, sizeof(e)); 133 struct tomoyo_group *entry = tomoyo_commit_ok(&e, sizeof(e));
122 if (entry) { 134 if (entry) {
123 INIT_LIST_HEAD(&entry->member_list); 135 INIT_LIST_HEAD(&entry->member_list);
124 atomic_set(&entry->users, 1); 136 atomic_set(&entry->head.users, 1);
125 list_add_tail_rcu(&entry->list, 137 list_add_tail_rcu(&entry->head.list, list);
126 &tomoyo_group_list[idx]);
127 group = entry; 138 group = entry;
128 found = true; 139 found = true;
129 } 140 }
130 } 141 }
131 mutex_unlock(&tomoyo_policy_lock); 142 mutex_unlock(&tomoyo_policy_lock);
132 out: 143out:
133 tomoyo_put_name(e.group_name); 144 tomoyo_put_name(e.group_name);
134 return found ? group : NULL; 145 return found ? group : NULL;
135} 146}
@@ -154,7 +165,6 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
154 struct tomoyo_name *ptr; 165 struct tomoyo_name *ptr;
155 unsigned int hash; 166 unsigned int hash;
156 int len; 167 int len;
157 int allocated_len;
158 struct list_head *head; 168 struct list_head *head;
159 169
160 if (!name) 170 if (!name)
@@ -164,120 +174,43 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
164 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; 174 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
165 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 175 if (mutex_lock_interruptible(&tomoyo_policy_lock))
166 return NULL; 176 return NULL;
167 list_for_each_entry(ptr, head, list) { 177 list_for_each_entry(ptr, head, head.list) {
168 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) 178 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
169 continue; 179 continue;
170 atomic_inc(&ptr->users); 180 atomic_inc(&ptr->head.users);
171 goto out; 181 goto out;
172 } 182 }
173 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS); 183 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS);
174 allocated_len = ptr ? ksize(ptr) : 0; 184 if (tomoyo_memory_ok(ptr)) {
175 if (!ptr || (tomoyo_quota_for_policy && 185 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
176 atomic_read(&tomoyo_policy_memory_size) + allocated_len 186 memmove((char *) ptr->entry.name, name, len);
177 > tomoyo_quota_for_policy)) { 187 atomic_set(&ptr->head.users, 1);
188 tomoyo_fill_path_info(&ptr->entry);
189 list_add_tail(&ptr->head.list, head);
190 } else {
178 kfree(ptr); 191 kfree(ptr);
179 ptr = NULL; 192 ptr = NULL;
180 tomoyo_warn_oom(__func__);
181 goto out;
182 } 193 }
183 atomic_add(allocated_len, &tomoyo_policy_memory_size); 194out:
184 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
185 memmove((char *) ptr->entry.name, name, len);
186 atomic_set(&ptr->users, 1);
187 tomoyo_fill_path_info(&ptr->entry);
188 list_add_tail(&ptr->list, head);
189 out:
190 mutex_unlock(&tomoyo_policy_lock); 195 mutex_unlock(&tomoyo_policy_lock);
191 return ptr ? &ptr->entry : NULL; 196 return ptr ? &ptr->entry : NULL;
192} 197}
193 198
199/* Initial namespace.*/
200struct tomoyo_policy_namespace tomoyo_kernel_namespace;
201
194/** 202/**
195 * tomoyo_mm_init - Initialize mm related code. 203 * tomoyo_mm_init - Initialize mm related code.
196 */ 204 */
197void __init tomoyo_mm_init(void) 205void __init tomoyo_mm_init(void)
198{ 206{
199 int idx; 207 int idx;
200
201 for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++)
202 INIT_LIST_HEAD(&tomoyo_policy_list[idx]);
203 for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++)
204 INIT_LIST_HEAD(&tomoyo_group_list[idx]);
205 for (idx = 0; idx < TOMOYO_MAX_HASH; idx++) 208 for (idx = 0; idx < TOMOYO_MAX_HASH; idx++)
206 INIT_LIST_HEAD(&tomoyo_name_list[idx]); 209 INIT_LIST_HEAD(&tomoyo_name_list[idx]);
210 tomoyo_kernel_namespace.name = "<kernel>";
211 tomoyo_init_policy_namespace(&tomoyo_kernel_namespace);
212 tomoyo_kernel_domain.ns = &tomoyo_kernel_namespace;
207 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); 213 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
208 tomoyo_kernel_domain.domainname = tomoyo_get_name(TOMOYO_ROOT_NAME); 214 tomoyo_kernel_domain.domainname = tomoyo_get_name("<kernel>");
209 list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list); 215 list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list);
210 idx = tomoyo_read_lock();
211 if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain)
212 panic("Can't register tomoyo_kernel_domain");
213 {
214 /* Load built-in policy. */
215 tomoyo_write_transition_control("/sbin/hotplug", false,
216 TOMOYO_TRANSITION_CONTROL_INITIALIZE);
217 tomoyo_write_transition_control("/sbin/modprobe", false,
218 TOMOYO_TRANSITION_CONTROL_INITIALIZE);
219 }
220 tomoyo_read_unlock(idx);
221}
222
223
224/* Memory allocated for query lists. */
225unsigned int tomoyo_query_memory_size;
226/* Quota for holding query lists. */
227unsigned int tomoyo_quota_for_query;
228
229/**
230 * tomoyo_read_memory_counter - Check for memory usage in bytes.
231 *
232 * @head: Pointer to "struct tomoyo_io_buffer".
233 *
234 * Returns memory usage.
235 */
236void tomoyo_read_memory_counter(struct tomoyo_io_buffer *head)
237{
238 if (!head->r.eof) {
239 const unsigned int policy
240 = atomic_read(&tomoyo_policy_memory_size);
241 const unsigned int query = tomoyo_query_memory_size;
242 char buffer[64];
243
244 memset(buffer, 0, sizeof(buffer));
245 if (tomoyo_quota_for_policy)
246 snprintf(buffer, sizeof(buffer) - 1,
247 " (Quota: %10u)",
248 tomoyo_quota_for_policy);
249 else
250 buffer[0] = '\0';
251 tomoyo_io_printf(head, "Policy: %10u%s\n", policy,
252 buffer);
253 if (tomoyo_quota_for_query)
254 snprintf(buffer, sizeof(buffer) - 1,
255 " (Quota: %10u)",
256 tomoyo_quota_for_query);
257 else
258 buffer[0] = '\0';
259 tomoyo_io_printf(head, "Query lists: %10u%s\n", query,
260 buffer);
261 tomoyo_io_printf(head, "Total: %10u\n", policy + query);
262 head->r.eof = true;
263 }
264}
265
266/**
267 * tomoyo_write_memory_quota - Set memory quota.
268 *
269 * @head: Pointer to "struct tomoyo_io_buffer".
270 *
271 * Returns 0.
272 */
273int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head)
274{
275 char *data = head->write_buf;
276 unsigned int size;
277
278 if (sscanf(data, "Policy: %u", &size) == 1)
279 tomoyo_quota_for_policy = size;
280 else if (sscanf(data, "Query lists: %u", &size) == 1)
281 tomoyo_quota_for_query = size;
282 return 0;
283} 216}
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index 9fc2e15841c..bee09d06205 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -1,28 +1,22 @@
1/* 1/*
2 * security/tomoyo/mount.c 2 * security/tomoyo/mount.c
3 * 3 *
4 * Copyright (C) 2005-2010 NTT DATA CORPORATION 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */ 5 */
6 6
7#include <linux/slab.h> 7#include <linux/slab.h>
8#include "common.h" 8#include "common.h"
9 9
10/* Keywords for mount restrictions. */ 10/* String table for special mount operations. */
11 11static const char * const tomoyo_mounts[TOMOYO_MAX_SPECIAL_MOUNT] = {
12/* Allow to call 'mount --bind /source_dir /dest_dir' */ 12 [TOMOYO_MOUNT_BIND] = "--bind",
13#define TOMOYO_MOUNT_BIND_KEYWORD "--bind" 13 [TOMOYO_MOUNT_MOVE] = "--move",
14/* Allow to call 'mount --move /old_dir /new_dir ' */ 14 [TOMOYO_MOUNT_REMOUNT] = "--remount",
15#define TOMOYO_MOUNT_MOVE_KEYWORD "--move" 15 [TOMOYO_MOUNT_MAKE_UNBINDABLE] = "--make-unbindable",
16/* Allow to call 'mount -o remount /dir ' */ 16 [TOMOYO_MOUNT_MAKE_PRIVATE] = "--make-private",
17#define TOMOYO_MOUNT_REMOUNT_KEYWORD "--remount" 17 [TOMOYO_MOUNT_MAKE_SLAVE] = "--make-slave",
18/* Allow to call 'mount --make-unbindable /dir' */ 18 [TOMOYO_MOUNT_MAKE_SHARED] = "--make-shared",
19#define TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD "--make-unbindable" 19};
20/* Allow to call 'mount --make-private /dir' */
21#define TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD "--make-private"
22/* Allow to call 'mount --make-slave /dir' */
23#define TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD "--make-slave"
24/* Allow to call 'mount --make-shared /dir' */
25#define TOMOYO_MOUNT_MAKE_SHARED_KEYWORD "--make-shared"
26 20
27/** 21/**
28 * tomoyo_audit_mount_log - Audit mount log. 22 * tomoyo_audit_mount_log - Audit mount log.
@@ -33,50 +27,42 @@
33 */ 27 */
34static int tomoyo_audit_mount_log(struct tomoyo_request_info *r) 28static int tomoyo_audit_mount_log(struct tomoyo_request_info *r)
35{ 29{
36 const char *dev = r->param.mount.dev->name; 30 return tomoyo_supervisor(r, "file mount %s %s %s 0x%lX\n",
37 const char *dir = r->param.mount.dir->name; 31 r->param.mount.dev->name,
38 const char *type = r->param.mount.type->name; 32 r->param.mount.dir->name,
39 const unsigned long flags = r->param.mount.flags; 33 r->param.mount.type->name,
40 if (r->granted) 34 r->param.mount.flags);
41 return 0;
42 if (!strcmp(type, TOMOYO_MOUNT_REMOUNT_KEYWORD))
43 tomoyo_warn_log(r, "mount -o remount %s 0x%lX", dir, flags);
44 else if (!strcmp(type, TOMOYO_MOUNT_BIND_KEYWORD)
45 || !strcmp(type, TOMOYO_MOUNT_MOVE_KEYWORD))
46 tomoyo_warn_log(r, "mount %s %s %s 0x%lX", type, dev, dir,
47 flags);
48 else if (!strcmp(type, TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD) ||
49 !strcmp(type, TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD) ||
50 !strcmp(type, TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD) ||
51 !strcmp(type, TOMOYO_MOUNT_MAKE_SHARED_KEYWORD))
52 tomoyo_warn_log(r, "mount %s %s 0x%lX", type, dir, flags);
53 else
54 tomoyo_warn_log(r, "mount -t %s %s %s 0x%lX", type, dev, dir,
55 flags);
56 return tomoyo_supervisor(r,
57 TOMOYO_KEYWORD_ALLOW_MOUNT "%s %s %s 0x%lX\n",
58 tomoyo_pattern(r->param.mount.dev),
59 tomoyo_pattern(r->param.mount.dir), type,
60 flags);
61} 35}
62 36
37/**
38 * tomoyo_check_mount_acl - Check permission for path path path number operation.
39 *
40 * @r: Pointer to "struct tomoyo_request_info".
41 * @ptr: Pointer to "struct tomoyo_acl_info".
42 *
43 * Returns true if granted, false otherwise.
44 */
63static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r, 45static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
64 const struct tomoyo_acl_info *ptr) 46 const struct tomoyo_acl_info *ptr)
65{ 47{
66 const struct tomoyo_mount_acl *acl = 48 const struct tomoyo_mount_acl *acl =
67 container_of(ptr, typeof(*acl), head); 49 container_of(ptr, typeof(*acl), head);
68 return tomoyo_compare_number_union(r->param.mount.flags, &acl->flags) && 50 return tomoyo_compare_number_union(r->param.mount.flags,
69 tomoyo_compare_name_union(r->param.mount.type, &acl->fs_type) && 51 &acl->flags) &&
70 tomoyo_compare_name_union(r->param.mount.dir, &acl->dir_name) && 52 tomoyo_compare_name_union(r->param.mount.type,
53 &acl->fs_type) &&
54 tomoyo_compare_name_union(r->param.mount.dir,
55 &acl->dir_name) &&
71 (!r->param.mount.need_dev || 56 (!r->param.mount.need_dev ||
72 tomoyo_compare_name_union(r->param.mount.dev, &acl->dev_name)); 57 tomoyo_compare_name_union(r->param.mount.dev,
58 &acl->dev_name));
73} 59}
74 60
75/** 61/**
76 * tomoyo_mount_acl - Check permission for mount() operation. 62 * tomoyo_mount_acl - Check permission for mount() operation.
77 * 63 *
78 * @r: Pointer to "struct tomoyo_request_info". 64 * @r: Pointer to "struct tomoyo_request_info".
79 * @dev_name: Name of device file. 65 * @dev_name: Name of device file. Maybe NULL.
80 * @dir: Pointer to "struct path". 66 * @dir: Pointer to "struct path".
81 * @type: Name of filesystem type. 67 * @type: Name of filesystem type.
82 * @flags: Mount options. 68 * @flags: Mount options.
@@ -86,8 +72,10 @@ static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
86 * Caller holds tomoyo_read_lock(). 72 * Caller holds tomoyo_read_lock().
87 */ 73 */
88static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name, 74static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
89 struct path *dir, char *type, unsigned long flags) 75 struct path *dir, const char *type,
76 unsigned long flags)
90{ 77{
78 struct tomoyo_obj_info obj = { };
91 struct path path; 79 struct path path;
92 struct file_system_type *fstype = NULL; 80 struct file_system_type *fstype = NULL;
93 const char *requested_type = NULL; 81 const char *requested_type = NULL;
@@ -98,6 +86,7 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
98 struct tomoyo_path_info rdir; 86 struct tomoyo_path_info rdir;
99 int need_dev = 0; 87 int need_dev = 0;
100 int error = -ENOMEM; 88 int error = -ENOMEM;
89 r->obj = &obj;
101 90
102 /* Get fstype. */ 91 /* Get fstype. */
103 requested_type = tomoyo_encode(type); 92 requested_type = tomoyo_encode(type);
@@ -107,6 +96,7 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
107 tomoyo_fill_path_info(&rtype); 96 tomoyo_fill_path_info(&rtype);
108 97
109 /* Get mount point. */ 98 /* Get mount point. */
99 obj.path2 = *dir;
110 requested_dir_name = tomoyo_realpath_from_path(dir); 100 requested_dir_name = tomoyo_realpath_from_path(dir);
111 if (!requested_dir_name) { 101 if (!requested_dir_name) {
112 error = -ENOMEM; 102 error = -ENOMEM;
@@ -116,15 +106,15 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
116 tomoyo_fill_path_info(&rdir); 106 tomoyo_fill_path_info(&rdir);
117 107
118 /* Compare fs name. */ 108 /* Compare fs name. */
119 if (!strcmp(type, TOMOYO_MOUNT_REMOUNT_KEYWORD)) { 109 if (type == tomoyo_mounts[TOMOYO_MOUNT_REMOUNT]) {
120 /* dev_name is ignored. */ 110 /* dev_name is ignored. */
121 } else if (!strcmp(type, TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD) || 111 } else if (type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE] ||
122 !strcmp(type, TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD) || 112 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE] ||
123 !strcmp(type, TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD) || 113 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE] ||
124 !strcmp(type, TOMOYO_MOUNT_MAKE_SHARED_KEYWORD)) { 114 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED]) {
125 /* dev_name is ignored. */ 115 /* dev_name is ignored. */
126 } else if (!strcmp(type, TOMOYO_MOUNT_BIND_KEYWORD) || 116 } else if (type == tomoyo_mounts[TOMOYO_MOUNT_BIND] ||
127 !strcmp(type, TOMOYO_MOUNT_MOVE_KEYWORD)) { 117 type == tomoyo_mounts[TOMOYO_MOUNT_MOVE]) {
128 need_dev = -1; /* dev_name is a directory */ 118 need_dev = -1; /* dev_name is a directory */
129 } else { 119 } else {
130 fstype = get_fs_type(type); 120 fstype = get_fs_type(type);
@@ -142,8 +132,8 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
142 error = -ENOENT; 132 error = -ENOENT;
143 goto out; 133 goto out;
144 } 134 }
135 obj.path1 = path;
145 requested_dev_name = tomoyo_realpath_from_path(&path); 136 requested_dev_name = tomoyo_realpath_from_path(&path);
146 path_put(&path);
147 if (!requested_dev_name) { 137 if (!requested_dev_name) {
148 error = -ENOENT; 138 error = -ENOENT;
149 goto out; 139 goto out;
@@ -176,22 +166,26 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
176 if (fstype) 166 if (fstype)
177 put_filesystem(fstype); 167 put_filesystem(fstype);
178 kfree(requested_type); 168 kfree(requested_type);
169 /* Drop refcount obtained by kern_path(). */
170 if (obj.path1.dentry)
171 path_put(&obj.path1);
179 return error; 172 return error;
180} 173}
181 174
182/** 175/**
183 * tomoyo_mount_permission - Check permission for mount() operation. 176 * tomoyo_mount_permission - Check permission for mount() operation.
184 * 177 *
185 * @dev_name: Name of device file. 178 * @dev_name: Name of device file. Maybe NULL.
186 * @path: Pointer to "struct path". 179 * @path: Pointer to "struct path".
187 * @type: Name of filesystem type. May be NULL. 180 * @type: Name of filesystem type. Maybe NULL.
188 * @flags: Mount options. 181 * @flags: Mount options.
189 * @data_page: Optional data. May be NULL. 182 * @data_page: Optional data. Maybe NULL.
190 * 183 *
191 * Returns 0 on success, negative value otherwise. 184 * Returns 0 on success, negative value otherwise.
192 */ 185 */
193int tomoyo_mount_permission(char *dev_name, struct path *path, char *type, 186int tomoyo_mount_permission(char *dev_name, struct path *path,
194 unsigned long flags, void *data_page) 187 const char *type, unsigned long flags,
188 void *data_page)
195{ 189{
196 struct tomoyo_request_info r; 190 struct tomoyo_request_info r;
197 int error; 191 int error;
@@ -203,31 +197,31 @@ int tomoyo_mount_permission(char *dev_name, struct path *path, char *type,
203 if ((flags & MS_MGC_MSK) == MS_MGC_VAL) 197 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
204 flags &= ~MS_MGC_MSK; 198 flags &= ~MS_MGC_MSK;
205 if (flags & MS_REMOUNT) { 199 if (flags & MS_REMOUNT) {
206 type = TOMOYO_MOUNT_REMOUNT_KEYWORD; 200 type = tomoyo_mounts[TOMOYO_MOUNT_REMOUNT];
207 flags &= ~MS_REMOUNT; 201 flags &= ~MS_REMOUNT;
208 } 202 }
209 if (flags & MS_MOVE) { 203 if (flags & MS_MOVE) {
210 type = TOMOYO_MOUNT_MOVE_KEYWORD; 204 type = tomoyo_mounts[TOMOYO_MOUNT_MOVE];
211 flags &= ~MS_MOVE; 205 flags &= ~MS_MOVE;
212 } 206 }
213 if (flags & MS_BIND) { 207 if (flags & MS_BIND) {
214 type = TOMOYO_MOUNT_BIND_KEYWORD; 208 type = tomoyo_mounts[TOMOYO_MOUNT_BIND];
215 flags &= ~MS_BIND; 209 flags &= ~MS_BIND;
216 } 210 }
217 if (flags & MS_UNBINDABLE) { 211 if (flags & MS_UNBINDABLE) {
218 type = TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD; 212 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE];
219 flags &= ~MS_UNBINDABLE; 213 flags &= ~MS_UNBINDABLE;
220 } 214 }
221 if (flags & MS_PRIVATE) { 215 if (flags & MS_PRIVATE) {
222 type = TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD; 216 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE];
223 flags &= ~MS_PRIVATE; 217 flags &= ~MS_PRIVATE;
224 } 218 }
225 if (flags & MS_SLAVE) { 219 if (flags & MS_SLAVE) {
226 type = TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD; 220 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE];
227 flags &= ~MS_SLAVE; 221 flags &= ~MS_SLAVE;
228 } 222 }
229 if (flags & MS_SHARED) { 223 if (flags & MS_SHARED) {
230 type = TOMOYO_MOUNT_MAKE_SHARED_KEYWORD; 224 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED];
231 flags &= ~MS_SHARED; 225 flags &= ~MS_SHARED;
232 } 226 }
233 if (!type) 227 if (!type)
@@ -237,49 +231,3 @@ int tomoyo_mount_permission(char *dev_name, struct path *path, char *type,
237 tomoyo_read_unlock(idx); 231 tomoyo_read_unlock(idx);
238 return error; 232 return error;
239} 233}
240
241static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a,
242 const struct tomoyo_acl_info *b)
243{
244 const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head);
245 const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head);
246 return tomoyo_same_acl_head(&p1->head, &p2->head) &&
247 tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
248 tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) &&
249 tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) &&
250 tomoyo_same_number_union(&p1->flags, &p2->flags);
251}
252
253/**
254 * tomoyo_write_mount - Write "struct tomoyo_mount_acl" list.
255 *
256 * @data: String to parse.
257 * @domain: Pointer to "struct tomoyo_domain_info".
258 * @is_delete: True if it is a delete request.
259 *
260 * Returns 0 on success, negative value otherwise.
261 *
262 * Caller holds tomoyo_read_lock().
263 */
264int tomoyo_write_mount(char *data, struct tomoyo_domain_info *domain,
265 const bool is_delete)
266{
267 struct tomoyo_mount_acl e = { .head.type = TOMOYO_TYPE_MOUNT_ACL };
268 int error = is_delete ? -ENOENT : -ENOMEM;
269 char *w[4];
270 if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[3][0])
271 return -EINVAL;
272 if (!tomoyo_parse_name_union(w[0], &e.dev_name) ||
273 !tomoyo_parse_name_union(w[1], &e.dir_name) ||
274 !tomoyo_parse_name_union(w[2], &e.fs_type) ||
275 !tomoyo_parse_number_union(w[3], &e.flags))
276 goto out;
277 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain,
278 tomoyo_same_mount_acl, NULL);
279 out:
280 tomoyo_put_name_union(&e.dev_name);
281 tomoyo_put_name_union(&e.dir_name);
282 tomoyo_put_name_union(&e.fs_type);
283 tomoyo_put_number_union(&e.flags);
284 return error;
285}
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index d1e05b04771..d46922db054 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * security/tomoyo/realpath.c 2 * security/tomoyo/realpath.c
3 * 3 *
4 * Pathname calculation functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include <linux/types.h> 7#include <linux/types.h>
@@ -70,6 +68,160 @@ char *tomoyo_encode(const char *str)
70} 68}
71 69
72/** 70/**
71 * tomoyo_get_absolute_path - Get the path of a dentry but ignores chroot'ed root.
72 *
73 * @path: Pointer to "struct path".
74 * @buffer: Pointer to buffer to return value in.
75 * @buflen: Sizeof @buffer.
76 *
77 * Returns the buffer on success, an error code otherwise.
78 *
79 * If dentry is a directory, trailing '/' is appended.
80 */
81static char *tomoyo_get_absolute_path(struct path *path, char * const buffer,
82 const int buflen)
83{
84 char *pos = ERR_PTR(-ENOMEM);
85 if (buflen >= 256) {
86 /* go to whatever namespace root we are under */
87 pos = d_absolute_path(path, buffer, buflen - 1);
88 if (!IS_ERR(pos) && *pos == '/' && pos[1]) {
89 struct inode *inode = path->dentry->d_inode;
90 if (inode && S_ISDIR(inode->i_mode)) {
91 buffer[buflen - 2] = '/';
92 buffer[buflen - 1] = '\0';
93 }
94 }
95 }
96 return pos;
97}
98
99/**
100 * tomoyo_get_dentry_path - Get the path of a dentry.
101 *
102 * @dentry: Pointer to "struct dentry".
103 * @buffer: Pointer to buffer to return value in.
104 * @buflen: Sizeof @buffer.
105 *
106 * Returns the buffer on success, an error code otherwise.
107 *
108 * If dentry is a directory, trailing '/' is appended.
109 */
110static char *tomoyo_get_dentry_path(struct dentry *dentry, char * const buffer,
111 const int buflen)
112{
113 char *pos = ERR_PTR(-ENOMEM);
114 if (buflen >= 256) {
115 pos = dentry_path_raw(dentry, buffer, buflen - 1);
116 if (!IS_ERR(pos) && *pos == '/' && pos[1]) {
117 struct inode *inode = dentry->d_inode;
118 if (inode && S_ISDIR(inode->i_mode)) {
119 buffer[buflen - 2] = '/';
120 buffer[buflen - 1] = '\0';
121 }
122 }
123 }
124 return pos;
125}
126
127/**
128 * tomoyo_get_local_path - Get the path of a dentry.
129 *
130 * @dentry: Pointer to "struct dentry".
131 * @buffer: Pointer to buffer to return value in.
132 * @buflen: Sizeof @buffer.
133 *
134 * Returns the buffer on success, an error code otherwise.
135 */
136static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer,
137 const int buflen)
138{
139 struct super_block *sb = dentry->d_sb;
140 char *pos = tomoyo_get_dentry_path(dentry, buffer, buflen);
141 if (IS_ERR(pos))
142 return pos;
143 /* Convert from $PID to self if $PID is current thread. */
144 if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/') {
145 char *ep;
146 const pid_t pid = (pid_t) simple_strtoul(pos + 1, &ep, 10);
147 if (*ep == '/' && pid && pid ==
148 task_tgid_nr_ns(current, sb->s_fs_info)) {
149 pos = ep - 5;
150 if (pos < buffer)
151 goto out;
152 memmove(pos, "/self", 5);
153 }
154 goto prepend_filesystem_name;
155 }
156 /* Use filesystem name for unnamed devices. */
157 if (!MAJOR(sb->s_dev))
158 goto prepend_filesystem_name;
159 {
160 struct inode *inode = sb->s_root->d_inode;
161 /*
162 * Use filesystem name if filesystem does not support rename()
163 * operation.
164 */
165 if (inode->i_op && !inode->i_op->rename)
166 goto prepend_filesystem_name;
167 }
168 /* Prepend device name. */
169 {
170 char name[64];
171 int name_len;
172 const dev_t dev = sb->s_dev;
173 name[sizeof(name) - 1] = '\0';
174 snprintf(name, sizeof(name) - 1, "dev(%u,%u):", MAJOR(dev),
175 MINOR(dev));
176 name_len = strlen(name);
177 pos -= name_len;
178 if (pos < buffer)
179 goto out;
180 memmove(pos, name, name_len);
181 return pos;
182 }
183 /* Prepend filesystem name. */
184prepend_filesystem_name:
185 {
186 const char *name = sb->s_type->name;
187 const int name_len = strlen(name);
188 pos -= name_len + 1;
189 if (pos < buffer)
190 goto out;
191 memmove(pos, name, name_len);
192 pos[name_len] = ':';
193 }
194 return pos;
195out:
196 return ERR_PTR(-ENOMEM);
197}
198
199/**
200 * tomoyo_get_socket_name - Get the name of a socket.
201 *
202 * @path: Pointer to "struct path".
203 * @buffer: Pointer to buffer to return value in.
204 * @buflen: Sizeof @buffer.
205 *
206 * Returns the buffer.
207 */
208static char *tomoyo_get_socket_name(struct path *path, char * const buffer,
209 const int buflen)
210{
211 struct inode *inode = path->dentry->d_inode;
212 struct socket *sock = inode ? SOCKET_I(inode) : NULL;
213 struct sock *sk = sock ? sock->sk : NULL;
214 if (sk) {
215 snprintf(buffer, buflen, "socket:[family=%u:type=%u:"
216 "protocol=%u]", sk->sk_family, sk->sk_type,
217 sk->sk_protocol);
218 } else {
219 snprintf(buffer, buflen, "socket:[unknown]");
220 }
221 return buffer;
222}
223
224/**
73 * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root. 225 * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root.
74 * 226 *
75 * @path: Pointer to "struct path". 227 * @path: Pointer to "struct path".
@@ -90,55 +242,50 @@ char *tomoyo_realpath_from_path(struct path *path)
90 char *name = NULL; 242 char *name = NULL;
91 unsigned int buf_len = PAGE_SIZE / 2; 243 unsigned int buf_len = PAGE_SIZE / 2;
92 struct dentry *dentry = path->dentry; 244 struct dentry *dentry = path->dentry;
93 bool is_dir; 245 struct super_block *sb;
94 if (!dentry) 246 if (!dentry)
95 return NULL; 247 return NULL;
96 is_dir = dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode); 248 sb = dentry->d_sb;
97 while (1) { 249 while (1) {
98 struct path ns_root = { .mnt = NULL, .dentry = NULL };
99 char *pos; 250 char *pos;
251 struct inode *inode;
100 buf_len <<= 1; 252 buf_len <<= 1;
101 kfree(buf); 253 kfree(buf);
102 buf = kmalloc(buf_len, GFP_NOFS); 254 buf = kmalloc(buf_len, GFP_NOFS);
103 if (!buf) 255 if (!buf)
104 break; 256 break;
257 /* To make sure that pos is '\0' terminated. */
258 buf[buf_len - 1] = '\0';
105 /* Get better name for socket. */ 259 /* Get better name for socket. */
106 if (dentry->d_sb && dentry->d_sb->s_magic == SOCKFS_MAGIC) { 260 if (sb->s_magic == SOCKFS_MAGIC) {
107 struct inode *inode = dentry->d_inode; 261 pos = tomoyo_get_socket_name(path, buf, buf_len - 1);
108 struct socket *sock = inode ? SOCKET_I(inode) : NULL; 262 goto encode;
109 struct sock *sk = sock ? sock->sk : NULL;
110 if (sk) {
111 snprintf(buf, buf_len - 1, "socket:[family=%u:"
112 "type=%u:protocol=%u]", sk->sk_family,
113 sk->sk_type, sk->sk_protocol);
114 } else {
115 snprintf(buf, buf_len - 1, "socket:[unknown]");
116 }
117 name = tomoyo_encode(buf);
118 break;
119 } 263 }
120 /* For "socket:[\$]" and "pipe:[\$]". */ 264 /* For "pipe:[\$]". */
121 if (dentry->d_op && dentry->d_op->d_dname) { 265 if (dentry->d_op && dentry->d_op->d_dname) {
122 pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1); 266 pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1);
123 if (IS_ERR(pos)) 267 goto encode;
124 continue;
125 name = tomoyo_encode(pos);
126 break;
127 } 268 }
128 /* If we don't have a vfsmount, we can't calculate. */ 269 inode = sb->s_root->d_inode;
129 if (!path->mnt) 270 /*
130 break; 271 * Get local name for filesystems without rename() operation
131 /* go to whatever namespace root we are under */ 272 * or dentry without vfsmount.
132 pos = __d_path(path, &ns_root, buf, buf_len); 273 */
133 /* Prepend "/proc" prefix if using internal proc vfs mount. */ 274 if (!path->mnt || (inode->i_op && !inode->i_op->rename))
134 if (!IS_ERR(pos) && (path->mnt->mnt_flags & MNT_INTERNAL) && 275 pos = tomoyo_get_local_path(path->dentry, buf,
135 (path->mnt->mnt_sb->s_magic == PROC_SUPER_MAGIC)) { 276 buf_len - 1);
136 pos -= 5; 277 /* Get absolute name for the rest. */
137 if (pos >= buf) 278 else {
138 memcpy(pos, "/proc", 5); 279 pos = tomoyo_get_absolute_path(path, buf, buf_len - 1);
139 else 280 /*
140 pos = ERR_PTR(-ENOMEM); 281 * Fall back to local name if absolute name is not
282 * available.
283 */
284 if (pos == ERR_PTR(-EINVAL))
285 pos = tomoyo_get_local_path(path->dentry, buf,
286 buf_len - 1);
141 } 287 }
288encode:
142 if (IS_ERR(pos)) 289 if (IS_ERR(pos))
143 continue; 290 continue;
144 name = tomoyo_encode(pos); 291 name = tomoyo_encode(pos);
@@ -147,16 +294,6 @@ char *tomoyo_realpath_from_path(struct path *path)
147 kfree(buf); 294 kfree(buf);
148 if (!name) 295 if (!name)
149 tomoyo_warn_oom(__func__); 296 tomoyo_warn_oom(__func__);
150 else if (is_dir && *name) {
151 /* Append trailing '/' if dentry is a directory. */
152 char *pos = name + strlen(name) - 1;
153 if (*pos != '/')
154 /*
155 * This is OK because tomoyo_encode() reserves space
156 * for appending "/".
157 */
158 *++pos = '/';
159 }
160 return name; 297 return name;
161} 298}
162 299
diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c
index e43d5554b50..a49c3bfd4dd 100644
--- a/security/tomoyo/securityfs_if.c
+++ b/security/tomoyo/securityfs_if.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * security/tomoyo/common.c 2 * security/tomoyo/securityfs_if.c
3 * 3 *
4 * Securityfs interface for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include <linux/security.h> 7#include <linux/security.h>
@@ -34,11 +32,11 @@ static int tomoyo_open(struct inode *inode, struct file *file)
34 */ 32 */
35static int tomoyo_release(struct inode *inode, struct file *file) 33static int tomoyo_release(struct inode *inode, struct file *file)
36{ 34{
37 return tomoyo_close_control(file); 35 return tomoyo_close_control(file->private_data);
38} 36}
39 37
40/** 38/**
41 * tomoyo_poll - poll() for /proc/ccs/ interface. 39 * tomoyo_poll - poll() for /sys/kernel/security/tomoyo/ interface.
42 * 40 *
43 * @file: Pointer to "struct file". 41 * @file: Pointer to "struct file".
44 * @wait: Pointer to "poll_table". 42 * @wait: Pointer to "poll_table".
@@ -63,7 +61,7 @@ static unsigned int tomoyo_poll(struct file *file, poll_table *wait)
63static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count, 61static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
64 loff_t *ppos) 62 loff_t *ppos)
65{ 63{
66 return tomoyo_read_control(file, buf, count); 64 return tomoyo_read_control(file->private_data, buf, count);
67} 65}
68 66
69/** 67/**
@@ -79,7 +77,7 @@ static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
79static ssize_t tomoyo_write(struct file *file, const char __user *buf, 77static ssize_t tomoyo_write(struct file *file, const char __user *buf,
80 size_t count, loff_t *ppos) 78 size_t count, loff_t *ppos)
81{ 79{
82 return tomoyo_write_control(file, buf, count); 80 return tomoyo_write_control(file->private_data, buf, count);
83} 81}
84 82
85/* 83/*
@@ -135,14 +133,14 @@ static int __init tomoyo_initerface_init(void)
135 TOMOYO_DOMAINPOLICY); 133 TOMOYO_DOMAINPOLICY);
136 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir, 134 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir,
137 TOMOYO_EXCEPTIONPOLICY); 135 TOMOYO_EXCEPTIONPOLICY);
136 tomoyo_create_entry("audit", 0400, tomoyo_dir,
137 TOMOYO_AUDIT);
138 tomoyo_create_entry("self_domain", 0400, tomoyo_dir, 138 tomoyo_create_entry("self_domain", 0400, tomoyo_dir,
139 TOMOYO_SELFDOMAIN); 139 TOMOYO_SELFDOMAIN);
140 tomoyo_create_entry(".domain_status", 0600, tomoyo_dir,
141 TOMOYO_DOMAIN_STATUS);
142 tomoyo_create_entry(".process_status", 0600, tomoyo_dir, 140 tomoyo_create_entry(".process_status", 0600, tomoyo_dir,
143 TOMOYO_PROCESS_STATUS); 141 TOMOYO_PROCESS_STATUS);
144 tomoyo_create_entry("meminfo", 0600, tomoyo_dir, 142 tomoyo_create_entry("stat", 0644, tomoyo_dir,
145 TOMOYO_MEMINFO); 143 TOMOYO_STAT);
146 tomoyo_create_entry("profile", 0600, tomoyo_dir, 144 tomoyo_create_entry("profile", 0600, tomoyo_dir,
147 TOMOYO_PROFILE); 145 TOMOYO_PROFILE);
148 tomoyo_create_entry("manager", 0600, tomoyo_dir, 146 tomoyo_create_entry("manager", 0600, tomoyo_dir,
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index 95d3f957223..f776400a8f3 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -1,20 +1,35 @@
1/* 1/*
2 * security/tomoyo/tomoyo.c 2 * security/tomoyo/tomoyo.c
3 * 3 *
4 * LSM hooks for TOMOYO Linux. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include <linux/security.h> 7#include <linux/security.h>
10#include "common.h" 8#include "common.h"
11 9
10/**
11 * tomoyo_cred_alloc_blank - Target for security_cred_alloc_blank().
12 *
13 * @new: Pointer to "struct cred".
14 * @gfp: Memory allocation flags.
15 *
16 * Returns 0.
17 */
12static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp) 18static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
13{ 19{
14 new->security = NULL; 20 new->security = NULL;
15 return 0; 21 return 0;
16} 22}
17 23
24/**
25 * tomoyo_cred_prepare - Target for security_prepare_creds().
26 *
27 * @new: Pointer to "struct cred".
28 * @old: Pointer to "struct cred".
29 * @gfp: Memory allocation flags.
30 *
31 * Returns 0.
32 */
18static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, 33static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
19 gfp_t gfp) 34 gfp_t gfp)
20{ 35{
@@ -25,11 +40,22 @@ static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
25 return 0; 40 return 0;
26} 41}
27 42
43/**
44 * tomoyo_cred_transfer - Target for security_transfer_creds().
45 *
46 * @new: Pointer to "struct cred".
47 * @old: Pointer to "struct cred".
48 */
28static void tomoyo_cred_transfer(struct cred *new, const struct cred *old) 49static void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
29{ 50{
30 tomoyo_cred_prepare(new, old, 0); 51 tomoyo_cred_prepare(new, old, 0);
31} 52}
32 53
54/**
55 * tomoyo_cred_free - Target for security_cred_free().
56 *
57 * @cred: Pointer to "struct cred".
58 */
33static void tomoyo_cred_free(struct cred *cred) 59static void tomoyo_cred_free(struct cred *cred)
34{ 60{
35 struct tomoyo_domain_info *domain = cred->security; 61 struct tomoyo_domain_info *domain = cred->security;
@@ -37,6 +63,13 @@ static void tomoyo_cred_free(struct cred *cred)
37 atomic_dec(&domain->users); 63 atomic_dec(&domain->users);
38} 64}
39 65
66/**
67 * tomoyo_bprm_set_creds - Target for security_bprm_set_creds().
68 *
69 * @bprm: Pointer to "struct linux_binprm".
70 *
71 * Returns 0 on success, negative value otherwise.
72 */
40static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) 73static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
41{ 74{
42 int rc; 75 int rc;
@@ -51,12 +84,14 @@ static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
51 */ 84 */
52 if (bprm->cred_prepared) 85 if (bprm->cred_prepared)
53 return 0; 86 return 0;
87#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
54 /* 88 /*
55 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested 89 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
56 * for the first time. 90 * for the first time.
57 */ 91 */
58 if (!tomoyo_policy_loaded) 92 if (!tomoyo_policy_loaded)
59 tomoyo_load_policy(bprm->filename); 93 tomoyo_load_policy(bprm->filename);
94#endif
60 /* 95 /*
61 * Release reference to "struct tomoyo_domain_info" stored inside 96 * Release reference to "struct tomoyo_domain_info" stored inside
62 * "bprm->cred->security". New reference to "struct tomoyo_domain_info" 97 * "bprm->cred->security". New reference to "struct tomoyo_domain_info"
@@ -73,6 +108,13 @@ static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
73 return 0; 108 return 0;
74} 109}
75 110
111/**
112 * tomoyo_bprm_check_security - Target for security_bprm_check().
113 *
114 * @bprm: Pointer to "struct linux_binprm".
115 *
116 * Returns 0 on success, negative value otherwise.
117 */
76static int tomoyo_bprm_check_security(struct linux_binprm *bprm) 118static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
77{ 119{
78 struct tomoyo_domain_info *domain = bprm->cred->security; 120 struct tomoyo_domain_info *domain = bprm->cred->security;
@@ -90,20 +132,59 @@ static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
90 /* 132 /*
91 * Read permission is checked against interpreters using next domain. 133 * Read permission is checked against interpreters using next domain.
92 */ 134 */
93 return tomoyo_check_open_permission(domain, &bprm->file->f_path, O_RDONLY); 135 return tomoyo_check_open_permission(domain, &bprm->file->f_path,
136 O_RDONLY);
137}
138
139/**
140 * tomoyo_inode_getattr - Target for security_inode_getattr().
141 *
142 * @mnt: Pointer to "struct vfsmount".
143 * @dentry: Pointer to "struct dentry".
144 *
145 * Returns 0 on success, negative value otherwise.
146 */
147static int tomoyo_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
148{
149 struct path path = { mnt, dentry };
150 return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, &path, NULL);
94} 151}
95 152
153/**
154 * tomoyo_path_truncate - Target for security_path_truncate().
155 *
156 * @path: Pointer to "struct path".
157 *
158 * Returns 0 on success, negative value otherwise.
159 */
96static int tomoyo_path_truncate(struct path *path) 160static int tomoyo_path_truncate(struct path *path)
97{ 161{
98 return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path); 162 return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path, NULL);
99} 163}
100 164
165/**
166 * tomoyo_path_unlink - Target for security_path_unlink().
167 *
168 * @parent: Pointer to "struct path".
169 * @dentry: Pointer to "struct dentry".
170 *
171 * Returns 0 on success, negative value otherwise.
172 */
101static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) 173static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry)
102{ 174{
103 struct path path = { parent->mnt, dentry }; 175 struct path path = { parent->mnt, dentry };
104 return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path); 176 return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL);
105} 177}
106 178
179/**
180 * tomoyo_path_mkdir - Target for security_path_mkdir().
181 *
182 * @parent: Pointer to "struct path".
183 * @dentry: Pointer to "struct dentry".
184 * @mode: DAC permission mode.
185 *
186 * Returns 0 on success, negative value otherwise.
187 */
107static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, 188static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry,
108 int mode) 189 int mode)
109{ 190{
@@ -112,19 +193,46 @@ static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry,
112 mode & S_IALLUGO); 193 mode & S_IALLUGO);
113} 194}
114 195
196/**
197 * tomoyo_path_rmdir - Target for security_path_rmdir().
198 *
199 * @parent: Pointer to "struct path".
200 * @dentry: Pointer to "struct dentry".
201 *
202 * Returns 0 on success, negative value otherwise.
203 */
115static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) 204static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry)
116{ 205{
117 struct path path = { parent->mnt, dentry }; 206 struct path path = { parent->mnt, dentry };
118 return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path); 207 return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL);
119} 208}
120 209
210/**
211 * tomoyo_path_symlink - Target for security_path_symlink().
212 *
213 * @parent: Pointer to "struct path".
214 * @dentry: Pointer to "struct dentry".
215 * @old_name: Symlink's content.
216 *
217 * Returns 0 on success, negative value otherwise.
218 */
121static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, 219static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry,
122 const char *old_name) 220 const char *old_name)
123{ 221{
124 struct path path = { parent->mnt, dentry }; 222 struct path path = { parent->mnt, dentry };
125 return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path); 223 return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name);
126} 224}
127 225
226/**
227 * tomoyo_path_mknod - Target for security_path_mknod().
228 *
229 * @parent: Pointer to "struct path".
230 * @dentry: Pointer to "struct dentry".
231 * @mode: DAC permission mode.
232 * @dev: Device attributes.
233 *
234 * Returns 0 on success, negative value otherwise.
235 */
128static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, 236static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry,
129 int mode, unsigned int dev) 237 int mode, unsigned int dev)
130{ 238{
@@ -155,6 +263,15 @@ static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry,
155 return tomoyo_path_number_perm(type, &path, perm); 263 return tomoyo_path_number_perm(type, &path, perm);
156} 264}
157 265
266/**
267 * tomoyo_path_link - Target for security_path_link().
268 *
269 * @old_dentry: Pointer to "struct dentry".
270 * @new_dir: Pointer to "struct path".
271 * @new_dentry: Pointer to "struct dentry".
272 *
273 * Returns 0 on success, negative value otherwise.
274 */
158static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir, 275static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
159 struct dentry *new_dentry) 276 struct dentry *new_dentry)
160{ 277{
@@ -163,6 +280,16 @@ static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
163 return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2); 280 return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
164} 281}
165 282
283/**
284 * tomoyo_path_rename - Target for security_path_rename().
285 *
286 * @old_parent: Pointer to "struct path".
287 * @old_dentry: Pointer to "struct dentry".
288 * @new_parent: Pointer to "struct path".
289 * @new_dentry: Pointer to "struct dentry".
290 *
291 * Returns 0 on success, negative value otherwise.
292 */
166static int tomoyo_path_rename(struct path *old_parent, 293static int tomoyo_path_rename(struct path *old_parent,
167 struct dentry *old_dentry, 294 struct dentry *old_dentry,
168 struct path *new_parent, 295 struct path *new_parent,
@@ -173,14 +300,32 @@ static int tomoyo_path_rename(struct path *old_parent,
173 return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2); 300 return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
174} 301}
175 302
303/**
304 * tomoyo_file_fcntl - Target for security_file_fcntl().
305 *
306 * @file: Pointer to "struct file".
307 * @cmd: Command for fcntl().
308 * @arg: Argument for @cmd.
309 *
310 * Returns 0 on success, negative value otherwise.
311 */
176static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, 312static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
177 unsigned long arg) 313 unsigned long arg)
178{ 314{
179 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)) 315 if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
180 return tomoyo_path_perm(TOMOYO_TYPE_REWRITE, &file->f_path); 316 return 0;
181 return 0; 317 return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path,
318 O_WRONLY | (arg & O_APPEND));
182} 319}
183 320
321/**
322 * tomoyo_dentry_open - Target for security_dentry_open().
323 *
324 * @f: Pointer to "struct file".
325 * @cred: Pointer to "struct cred".
326 *
327 * Returns 0 on success, negative value otherwise.
328 */
184static int tomoyo_dentry_open(struct file *f, const struct cred *cred) 329static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
185{ 330{
186 int flags = f->f_flags; 331 int flags = f->f_flags;
@@ -190,12 +335,30 @@ static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
190 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 335 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
191} 336}
192 337
338/**
339 * tomoyo_file_ioctl - Target for security_file_ioctl().
340 *
341 * @file: Pointer to "struct file".
342 * @cmd: Command for ioctl().
343 * @arg: Argument for @cmd.
344 *
345 * Returns 0 on success, negative value otherwise.
346 */
193static int tomoyo_file_ioctl(struct file *file, unsigned int cmd, 347static int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
194 unsigned long arg) 348 unsigned long arg)
195{ 349{
196 return tomoyo_path_number_perm(TOMOYO_TYPE_IOCTL, &file->f_path, cmd); 350 return tomoyo_path_number_perm(TOMOYO_TYPE_IOCTL, &file->f_path, cmd);
197} 351}
198 352
353/**
354 * tomoyo_path_chmod - Target for security_path_chmod().
355 *
356 * @dentry: Pointer to "struct dentry".
357 * @mnt: Pointer to "struct vfsmount".
358 * @mode: DAC permission mode.
359 *
360 * Returns 0 on success, negative value otherwise.
361 */
199static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt, 362static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
200 mode_t mode) 363 mode_t mode)
201{ 364{
@@ -204,6 +367,15 @@ static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
204 mode & S_IALLUGO); 367 mode & S_IALLUGO);
205} 368}
206 369
370/**
371 * tomoyo_path_chown - Target for security_path_chown().
372 *
373 * @path: Pointer to "struct path".
374 * @uid: Owner ID.
375 * @gid: Group ID.
376 *
377 * Returns 0 on success, negative value otherwise.
378 */
207static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid) 379static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid)
208{ 380{
209 int error = 0; 381 int error = 0;
@@ -214,23 +386,57 @@ static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid)
214 return error; 386 return error;
215} 387}
216 388
389/**
390 * tomoyo_path_chroot - Target for security_path_chroot().
391 *
392 * @path: Pointer to "struct path".
393 *
394 * Returns 0 on success, negative value otherwise.
395 */
217static int tomoyo_path_chroot(struct path *path) 396static int tomoyo_path_chroot(struct path *path)
218{ 397{
219 return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path); 398 return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path, NULL);
220} 399}
221 400
401/**
402 * tomoyo_sb_mount - Target for security_sb_mount().
403 *
404 * @dev_name: Name of device file. Maybe NULL.
405 * @path: Pointer to "struct path".
406 * @type: Name of filesystem type. Maybe NULL.
407 * @flags: Mount options.
408 * @data: Optional data. Maybe NULL.
409 *
410 * Returns 0 on success, negative value otherwise.
411 */
222static int tomoyo_sb_mount(char *dev_name, struct path *path, 412static int tomoyo_sb_mount(char *dev_name, struct path *path,
223 char *type, unsigned long flags, void *data) 413 char *type, unsigned long flags, void *data)
224{ 414{
225 return tomoyo_mount_permission(dev_name, path, type, flags, data); 415 return tomoyo_mount_permission(dev_name, path, type, flags, data);
226} 416}
227 417
418/**
419 * tomoyo_sb_umount - Target for security_sb_umount().
420 *
421 * @mnt: Pointer to "struct vfsmount".
422 * @flags: Unmount options.
423 *
424 * Returns 0 on success, negative value otherwise.
425 */
228static int tomoyo_sb_umount(struct vfsmount *mnt, int flags) 426static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
229{ 427{
230 struct path path = { mnt, mnt->mnt_root }; 428 struct path path = { mnt, mnt->mnt_root };
231 return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path); 429 return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL);
232} 430}
233 431
432/**
433 * tomoyo_sb_pivotroot - Target for security_sb_pivotroot().
434 *
435 * @old_path: Pointer to "struct path".
436 * @new_path: Pointer to "struct path".
437 *
438 * Returns 0 on success, negative value otherwise.
439 */
234static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path) 440static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path)
235{ 441{
236 return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path); 442 return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
@@ -258,6 +464,7 @@ static struct security_operations tomoyo_security_ops = {
258 .path_mknod = tomoyo_path_mknod, 464 .path_mknod = tomoyo_path_mknod,
259 .path_link = tomoyo_path_link, 465 .path_link = tomoyo_path_link,
260 .path_rename = tomoyo_path_rename, 466 .path_rename = tomoyo_path_rename,
467 .inode_getattr = tomoyo_inode_getattr,
261 .file_ioctl = tomoyo_file_ioctl, 468 .file_ioctl = tomoyo_file_ioctl,
262 .path_chmod = tomoyo_path_chmod, 469 .path_chmod = tomoyo_path_chmod,
263 .path_chown = tomoyo_path_chown, 470 .path_chown = tomoyo_path_chown,
@@ -270,6 +477,11 @@ static struct security_operations tomoyo_security_ops = {
270/* Lock for GC. */ 477/* Lock for GC. */
271struct srcu_struct tomoyo_ss; 478struct srcu_struct tomoyo_ss;
272 479
480/**
481 * tomoyo_init - Register TOMOYO Linux as a LSM module.
482 *
483 * Returns 0.
484 */
273static int __init tomoyo_init(void) 485static int __init tomoyo_init(void)
274{ 486{
275 struct cred *cred = (struct cred *) current_cred(); 487 struct cred *cred = (struct cred *) current_cred();
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 6d5393204d9..c36bd1107fc 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * security/tomoyo/util.c 2 * security/tomoyo/util.c
3 * 3 *
4 * Utility functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include <linux/slab.h> 7#include <linux/slab.h>
@@ -15,18 +13,130 @@ DEFINE_MUTEX(tomoyo_policy_lock);
15/* Has /sbin/init started? */ 13/* Has /sbin/init started? */
16bool tomoyo_policy_loaded; 14bool tomoyo_policy_loaded;
17 15
16/*
17 * Mapping table from "enum tomoyo_mac_index" to
18 * "enum tomoyo_mac_category_index".
19 */
20const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX] = {
21 /* CONFIG::file group */
22 [TOMOYO_MAC_FILE_EXECUTE] = TOMOYO_MAC_CATEGORY_FILE,
23 [TOMOYO_MAC_FILE_OPEN] = TOMOYO_MAC_CATEGORY_FILE,
24 [TOMOYO_MAC_FILE_CREATE] = TOMOYO_MAC_CATEGORY_FILE,
25 [TOMOYO_MAC_FILE_UNLINK] = TOMOYO_MAC_CATEGORY_FILE,
26 [TOMOYO_MAC_FILE_GETATTR] = TOMOYO_MAC_CATEGORY_FILE,
27 [TOMOYO_MAC_FILE_MKDIR] = TOMOYO_MAC_CATEGORY_FILE,
28 [TOMOYO_MAC_FILE_RMDIR] = TOMOYO_MAC_CATEGORY_FILE,
29 [TOMOYO_MAC_FILE_MKFIFO] = TOMOYO_MAC_CATEGORY_FILE,
30 [TOMOYO_MAC_FILE_MKSOCK] = TOMOYO_MAC_CATEGORY_FILE,
31 [TOMOYO_MAC_FILE_TRUNCATE] = TOMOYO_MAC_CATEGORY_FILE,
32 [TOMOYO_MAC_FILE_SYMLINK] = TOMOYO_MAC_CATEGORY_FILE,
33 [TOMOYO_MAC_FILE_MKBLOCK] = TOMOYO_MAC_CATEGORY_FILE,
34 [TOMOYO_MAC_FILE_MKCHAR] = TOMOYO_MAC_CATEGORY_FILE,
35 [TOMOYO_MAC_FILE_LINK] = TOMOYO_MAC_CATEGORY_FILE,
36 [TOMOYO_MAC_FILE_RENAME] = TOMOYO_MAC_CATEGORY_FILE,
37 [TOMOYO_MAC_FILE_CHMOD] = TOMOYO_MAC_CATEGORY_FILE,
38 [TOMOYO_MAC_FILE_CHOWN] = TOMOYO_MAC_CATEGORY_FILE,
39 [TOMOYO_MAC_FILE_CHGRP] = TOMOYO_MAC_CATEGORY_FILE,
40 [TOMOYO_MAC_FILE_IOCTL] = TOMOYO_MAC_CATEGORY_FILE,
41 [TOMOYO_MAC_FILE_CHROOT] = TOMOYO_MAC_CATEGORY_FILE,
42 [TOMOYO_MAC_FILE_MOUNT] = TOMOYO_MAC_CATEGORY_FILE,
43 [TOMOYO_MAC_FILE_UMOUNT] = TOMOYO_MAC_CATEGORY_FILE,
44 [TOMOYO_MAC_FILE_PIVOT_ROOT] = TOMOYO_MAC_CATEGORY_FILE,
45};
46
47/**
48 * tomoyo_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss.
49 *
50 * @time: Seconds since 1970/01/01 00:00:00.
51 * @stamp: Pointer to "struct tomoyo_time".
52 *
53 * Returns nothing.
54 *
55 * This function does not handle Y2038 problem.
56 */
57void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp)
58{
59 static const u16 tomoyo_eom[2][12] = {
60 { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
61 { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
62 };
63 u16 y;
64 u8 m;
65 bool r;
66 stamp->sec = time % 60;
67 time /= 60;
68 stamp->min = time % 60;
69 time /= 60;
70 stamp->hour = time % 24;
71 time /= 24;
72 for (y = 1970; ; y++) {
73 const unsigned short days = (y & 3) ? 365 : 366;
74 if (time < days)
75 break;
76 time -= days;
77 }
78 r = (y & 3) == 0;
79 for (m = 0; m < 11 && time >= tomoyo_eom[r][m]; m++)
80 ;
81 if (m)
82 time -= tomoyo_eom[r][m - 1];
83 stamp->year = y;
84 stamp->month = ++m;
85 stamp->day = ++time;
86}
87
88/**
89 * tomoyo_permstr - Find permission keywords.
90 *
91 * @string: String representation for permissions in foo/bar/buz format.
92 * @keyword: Keyword to find from @string/
93 *
94 * Returns ture if @keyword was found in @string, false otherwise.
95 *
96 * This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2.
97 */
98bool tomoyo_permstr(const char *string, const char *keyword)
99{
100 const char *cp = strstr(string, keyword);
101 if (cp)
102 return cp == string || *(cp - 1) == '/';
103 return false;
104}
105
106/**
107 * tomoyo_read_token - Read a word from a line.
108 *
109 * @param: Pointer to "struct tomoyo_acl_param".
110 *
111 * Returns a word on success, "" otherwise.
112 *
113 * To allow the caller to skip NULL check, this function returns "" rather than
114 * NULL if there is no more words to read.
115 */
116char *tomoyo_read_token(struct tomoyo_acl_param *param)
117{
118 char *pos = param->data;
119 char *del = strchr(pos, ' ');
120 if (del)
121 *del++ = '\0';
122 else
123 del = pos + strlen(pos);
124 param->data = del;
125 return pos;
126}
127
18/** 128/**
19 * tomoyo_parse_ulong - Parse an "unsigned long" value. 129 * tomoyo_parse_ulong - Parse an "unsigned long" value.
20 * 130 *
21 * @result: Pointer to "unsigned long". 131 * @result: Pointer to "unsigned long".
22 * @str: Pointer to string to parse. 132 * @str: Pointer to string to parse.
23 * 133 *
24 * Returns value type on success, 0 otherwise. 134 * Returns one of values in "enum tomoyo_value_type".
25 * 135 *
26 * The @src is updated to point the first character after the value 136 * The @src is updated to point the first character after the value
27 * on success. 137 * on success.
28 */ 138 */
29static u8 tomoyo_parse_ulong(unsigned long *result, char **str) 139u8 tomoyo_parse_ulong(unsigned long *result, char **str)
30{ 140{
31 const char *cp = *str; 141 const char *cp = *str;
32 char *ep; 142 char *ep;
@@ -43,7 +153,7 @@ static u8 tomoyo_parse_ulong(unsigned long *result, char **str)
43 } 153 }
44 *result = simple_strtoul(cp, &ep, base); 154 *result = simple_strtoul(cp, &ep, base);
45 if (cp == ep) 155 if (cp == ep)
46 return 0; 156 return TOMOYO_VALUE_TYPE_INVALID;
47 *str = ep; 157 *str = ep;
48 switch (base) { 158 switch (base) {
49 case 16: 159 case 16:
@@ -81,63 +191,65 @@ void tomoyo_print_ulong(char *buffer, const int buffer_len,
81/** 191/**
82 * tomoyo_parse_name_union - Parse a tomoyo_name_union. 192 * tomoyo_parse_name_union - Parse a tomoyo_name_union.
83 * 193 *
84 * @filename: Name or name group. 194 * @param: Pointer to "struct tomoyo_acl_param".
85 * @ptr: Pointer to "struct tomoyo_name_union". 195 * @ptr: Pointer to "struct tomoyo_name_union".
86 * 196 *
87 * Returns true on success, false otherwise. 197 * Returns true on success, false otherwise.
88 */ 198 */
89bool tomoyo_parse_name_union(const char *filename, 199bool tomoyo_parse_name_union(struct tomoyo_acl_param *param,
90 struct tomoyo_name_union *ptr) 200 struct tomoyo_name_union *ptr)
91{ 201{
92 if (!tomoyo_correct_word(filename)) 202 char *filename;
93 return false; 203 if (param->data[0] == '@') {
94 if (filename[0] == '@') { 204 param->data++;
95 ptr->group = tomoyo_get_group(filename + 1, TOMOYO_PATH_GROUP); 205 ptr->group = tomoyo_get_group(param, TOMOYO_PATH_GROUP);
96 ptr->is_group = true;
97 return ptr->group != NULL; 206 return ptr->group != NULL;
98 } 207 }
208 filename = tomoyo_read_token(param);
209 if (!tomoyo_correct_word(filename))
210 return false;
99 ptr->filename = tomoyo_get_name(filename); 211 ptr->filename = tomoyo_get_name(filename);
100 ptr->is_group = false;
101 return ptr->filename != NULL; 212 return ptr->filename != NULL;
102} 213}
103 214
104/** 215/**
105 * tomoyo_parse_number_union - Parse a tomoyo_number_union. 216 * tomoyo_parse_number_union - Parse a tomoyo_number_union.
106 * 217 *
107 * @data: Number or number range or number group. 218 * @param: Pointer to "struct tomoyo_acl_param".
108 * @ptr: Pointer to "struct tomoyo_number_union". 219 * @ptr: Pointer to "struct tomoyo_number_union".
109 * 220 *
110 * Returns true on success, false otherwise. 221 * Returns true on success, false otherwise.
111 */ 222 */
112bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num) 223bool tomoyo_parse_number_union(struct tomoyo_acl_param *param,
224 struct tomoyo_number_union *ptr)
113{ 225{
226 char *data;
114 u8 type; 227 u8 type;
115 unsigned long v; 228 unsigned long v;
116 memset(num, 0, sizeof(*num)); 229 memset(ptr, 0, sizeof(*ptr));
117 if (data[0] == '@') { 230 if (param->data[0] == '@') {
118 if (!tomoyo_correct_word(data)) 231 param->data++;
119 return false; 232 ptr->group = tomoyo_get_group(param, TOMOYO_NUMBER_GROUP);
120 num->group = tomoyo_get_group(data + 1, TOMOYO_NUMBER_GROUP); 233 return ptr->group != NULL;
121 num->is_group = true;
122 return num->group != NULL;
123 } 234 }
235 data = tomoyo_read_token(param);
124 type = tomoyo_parse_ulong(&v, &data); 236 type = tomoyo_parse_ulong(&v, &data);
125 if (!type) 237 if (type == TOMOYO_VALUE_TYPE_INVALID)
126 return false; 238 return false;
127 num->values[0] = v; 239 ptr->values[0] = v;
128 num->min_type = type; 240 ptr->value_type[0] = type;
129 if (!*data) { 241 if (!*data) {
130 num->values[1] = v; 242 ptr->values[1] = v;
131 num->max_type = type; 243 ptr->value_type[1] = type;
132 return true; 244 return true;
133 } 245 }
134 if (*data++ != '-') 246 if (*data++ != '-')
135 return false; 247 return false;
136 type = tomoyo_parse_ulong(&v, &data); 248 type = tomoyo_parse_ulong(&v, &data);
137 if (!type || *data) 249 if (type == TOMOYO_VALUE_TYPE_INVALID || *data || ptr->values[0] > v)
138 return false; 250 return false;
139 num->values[1] = v; 251 ptr->values[1] = v;
140 num->max_type = type; 252 ptr->value_type[1] = type;
141 return true; 253 return true;
142} 254}
143 255
@@ -185,6 +297,30 @@ static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3)
185} 297}
186 298
187/** 299/**
300 * tomoyo_valid - Check whether the character is a valid char.
301 *
302 * @c: The character to check.
303 *
304 * Returns true if @c is a valid character, false otherwise.
305 */
306static inline bool tomoyo_valid(const unsigned char c)
307{
308 return c > ' ' && c < 127;
309}
310
311/**
312 * tomoyo_invalid - Check whether the character is an invalid char.
313 *
314 * @c: The character to check.
315 *
316 * Returns true if @c is an invalid character, false otherwise.
317 */
318static inline bool tomoyo_invalid(const unsigned char c)
319{
320 return c && (c <= ' ' || c >= 127);
321}
322
323/**
188 * tomoyo_str_starts - Check whether the given string starts with the given keyword. 324 * tomoyo_str_starts - Check whether the given string starts with the given keyword.
189 * 325 *
190 * @src: Pointer to pointer to the string. 326 * @src: Pointer to pointer to the string.
@@ -238,36 +374,9 @@ void tomoyo_normalize_line(unsigned char *buffer)
238} 374}
239 375
240/** 376/**
241 * tomoyo_tokenize - Tokenize string.
242 *
243 * @buffer: The line to tokenize.
244 * @w: Pointer to "char *".
245 * @size: Sizeof @w .
246 *
247 * Returns true on success, false otherwise.
248 */
249bool tomoyo_tokenize(char *buffer, char *w[], size_t size)
250{
251 int count = size / sizeof(char *);
252 int i;
253 for (i = 0; i < count; i++)
254 w[i] = "";
255 for (i = 0; i < count; i++) {
256 char *cp = strchr(buffer, ' ');
257 if (cp)
258 *cp = '\0';
259 w[i] = buffer;
260 if (!cp)
261 break;
262 buffer = cp + 1;
263 }
264 return i < count || !*buffer;
265}
266
267/**
268 * tomoyo_correct_word2 - Validate a string. 377 * tomoyo_correct_word2 - Validate a string.
269 * 378 *
270 * @string: The string to check. May be non-'\0'-terminated. 379 * @string: The string to check. Maybe non-'\0'-terminated.
271 * @len: Length of @string. 380 * @len: Length of @string.
272 * 381 *
273 * Check whether the given string follows the naming rules. 382 * Check whether the given string follows the naming rules.
@@ -377,26 +486,21 @@ bool tomoyo_correct_path(const char *filename)
377 */ 486 */
378bool tomoyo_correct_domain(const unsigned char *domainname) 487bool tomoyo_correct_domain(const unsigned char *domainname)
379{ 488{
380 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME, 489 if (!domainname || !tomoyo_domain_def(domainname))
381 TOMOYO_ROOT_NAME_LEN)) 490 return false;
382 goto out; 491 domainname = strchr(domainname, ' ');
383 domainname += TOMOYO_ROOT_NAME_LEN; 492 if (!domainname++)
384 if (!*domainname)
385 return true; 493 return true;
386 if (*domainname++ != ' ')
387 goto out;
388 while (1) { 494 while (1) {
389 const unsigned char *cp = strchr(domainname, ' '); 495 const unsigned char *cp = strchr(domainname, ' ');
390 if (!cp) 496 if (!cp)
391 break; 497 break;
392 if (*domainname != '/' || 498 if (*domainname != '/' ||
393 !tomoyo_correct_word2(domainname, cp - domainname)) 499 !tomoyo_correct_word2(domainname, cp - domainname))
394 goto out; 500 return false;
395 domainname = cp + 1; 501 domainname = cp + 1;
396 } 502 }
397 return tomoyo_correct_path(domainname); 503 return tomoyo_correct_path(domainname);
398 out:
399 return false;
400} 504}
401 505
402/** 506/**
@@ -408,7 +512,19 @@ bool tomoyo_correct_domain(const unsigned char *domainname)
408 */ 512 */
409bool tomoyo_domain_def(const unsigned char *buffer) 513bool tomoyo_domain_def(const unsigned char *buffer)
410{ 514{
411 return !strncmp(buffer, TOMOYO_ROOT_NAME, TOMOYO_ROOT_NAME_LEN); 515 const unsigned char *cp;
516 int len;
517 if (*buffer != '<')
518 return false;
519 cp = strchr(buffer, ' ');
520 if (!cp)
521 len = strlen(buffer);
522 else
523 len = cp - buffer;
524 if (buffer[len - 1] != '>' ||
525 !tomoyo_correct_word2(buffer + 1, len - 2))
526 return false;
527 return true;
412} 528}
413 529
414/** 530/**
@@ -794,22 +910,24 @@ const char *tomoyo_get_exe(void)
794/** 910/**
795 * tomoyo_get_mode - Get MAC mode. 911 * tomoyo_get_mode - Get MAC mode.
796 * 912 *
913 * @ns: Pointer to "struct tomoyo_policy_namespace".
797 * @profile: Profile number. 914 * @profile: Profile number.
798 * @index: Index number of functionality. 915 * @index: Index number of functionality.
799 * 916 *
800 * Returns mode. 917 * Returns mode.
801 */ 918 */
802int tomoyo_get_mode(const u8 profile, const u8 index) 919int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
920 const u8 index)
803{ 921{
804 u8 mode; 922 u8 mode;
805 const u8 category = TOMOYO_MAC_CATEGORY_FILE; 923 const u8 category = TOMOYO_MAC_CATEGORY_FILE;
806 if (!tomoyo_policy_loaded) 924 if (!tomoyo_policy_loaded)
807 return TOMOYO_CONFIG_DISABLED; 925 return TOMOYO_CONFIG_DISABLED;
808 mode = tomoyo_profile(profile)->config[index]; 926 mode = tomoyo_profile(ns, profile)->config[index];
809 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 927 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
810 mode = tomoyo_profile(profile)->config[category]; 928 mode = tomoyo_profile(ns, profile)->config[category];
811 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 929 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
812 mode = tomoyo_profile(profile)->default_config; 930 mode = tomoyo_profile(ns, profile)->default_config;
813 return mode & 3; 931 return mode & 3;
814} 932}
815 933
@@ -833,65 +951,11 @@ int tomoyo_init_request_info(struct tomoyo_request_info *r,
833 profile = domain->profile; 951 profile = domain->profile;
834 r->profile = profile; 952 r->profile = profile;
835 r->type = index; 953 r->type = index;
836 r->mode = tomoyo_get_mode(profile, index); 954 r->mode = tomoyo_get_mode(domain->ns, profile, index);
837 return r->mode; 955 return r->mode;
838} 956}
839 957
840/** 958/**
841 * tomoyo_last_word - Get last component of a line.
842 *
843 * @line: A line.
844 *
845 * Returns the last word of a line.
846 */
847const char *tomoyo_last_word(const char *name)
848{
849 const char *cp = strrchr(name, ' ');
850 if (cp)
851 return cp + 1;
852 return name;
853}
854
855/**
856 * tomoyo_warn_log - Print warning or error message on console.
857 *
858 * @r: Pointer to "struct tomoyo_request_info".
859 * @fmt: The printf()'s format string, followed by parameters.
860 */
861void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...)
862{
863 va_list args;
864 char *buffer;
865 const struct tomoyo_domain_info * const domain = r->domain;
866 const struct tomoyo_profile *profile = tomoyo_profile(domain->profile);
867 switch (r->mode) {
868 case TOMOYO_CONFIG_ENFORCING:
869 if (!profile->enforcing->enforcing_verbose)
870 return;
871 break;
872 case TOMOYO_CONFIG_PERMISSIVE:
873 if (!profile->permissive->permissive_verbose)
874 return;
875 break;
876 case TOMOYO_CONFIG_LEARNING:
877 if (!profile->learning->learning_verbose)
878 return;
879 break;
880 }
881 buffer = kmalloc(4096, GFP_NOFS);
882 if (!buffer)
883 return;
884 va_start(args, fmt);
885 vsnprintf(buffer, 4095, fmt, args);
886 va_end(args);
887 buffer[4095] = '\0';
888 printk(KERN_WARNING "%s: Access %s denied for %s\n",
889 r->mode == TOMOYO_CONFIG_ENFORCING ? "ERROR" : "WARNING", buffer,
890 tomoyo_last_word(domain->domainname->name));
891 kfree(buffer);
892}
893
894/**
895 * tomoyo_domain_quota_is_ok - Check for domain's quota. 959 * tomoyo_domain_quota_is_ok - Check for domain's quota.
896 * 960 *
897 * @r: Pointer to "struct tomoyo_request_info". 961 * @r: Pointer to "struct tomoyo_request_info".
@@ -911,52 +975,43 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
911 if (!domain) 975 if (!domain)
912 return true; 976 return true;
913 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 977 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
978 u16 perm;
979 u8 i;
914 if (ptr->is_deleted) 980 if (ptr->is_deleted)
915 continue; 981 continue;
916 switch (ptr->type) { 982 switch (ptr->type) {
917 u16 perm;
918 u8 i;
919 case TOMOYO_TYPE_PATH_ACL: 983 case TOMOYO_TYPE_PATH_ACL:
920 perm = container_of(ptr, struct tomoyo_path_acl, head) 984 perm = container_of(ptr, struct tomoyo_path_acl, head)
921 ->perm; 985 ->perm;
922 for (i = 0; i < TOMOYO_MAX_PATH_OPERATION; i++)
923 if (perm & (1 << i))
924 count++;
925 if (perm & (1 << TOMOYO_TYPE_READ_WRITE))
926 count -= 2;
927 break; 986 break;
928 case TOMOYO_TYPE_PATH2_ACL: 987 case TOMOYO_TYPE_PATH2_ACL:
929 perm = container_of(ptr, struct tomoyo_path2_acl, head) 988 perm = container_of(ptr, struct tomoyo_path2_acl, head)
930 ->perm; 989 ->perm;
931 for (i = 0; i < TOMOYO_MAX_PATH2_OPERATION; i++)
932 if (perm & (1 << i))
933 count++;
934 break; 990 break;
935 case TOMOYO_TYPE_PATH_NUMBER_ACL: 991 case TOMOYO_TYPE_PATH_NUMBER_ACL:
936 perm = container_of(ptr, struct tomoyo_path_number_acl, 992 perm = container_of(ptr, struct tomoyo_path_number_acl,
937 head)->perm; 993 head)->perm;
938 for (i = 0; i < TOMOYO_MAX_PATH_NUMBER_OPERATION; i++)
939 if (perm & (1 << i))
940 count++;
941 break; 994 break;
942 case TOMOYO_TYPE_MKDEV_ACL: 995 case TOMOYO_TYPE_MKDEV_ACL:
943 perm = container_of(ptr, struct tomoyo_mkdev_acl, 996 perm = container_of(ptr, struct tomoyo_mkdev_acl,
944 head)->perm; 997 head)->perm;
945 for (i = 0; i < TOMOYO_MAX_MKDEV_OPERATION; i++)
946 if (perm & (1 << i))
947 count++;
948 break; 998 break;
949 default: 999 default:
950 count++; 1000 perm = 1;
951 } 1001 }
1002 for (i = 0; i < 16; i++)
1003 if (perm & (1 << i))
1004 count++;
952 } 1005 }
953 if (count < tomoyo_profile(domain->profile)->learning-> 1006 if (count < tomoyo_profile(domain->ns, domain->profile)->
954 learning_max_entry) 1007 pref[TOMOYO_PREF_MAX_LEARNING_ENTRY])
955 return true; 1008 return true;
956 if (!domain->quota_warned) { 1009 if (!domain->flags[TOMOYO_DIF_QUOTA_WARNED]) {
957 domain->quota_warned = true; 1010 domain->flags[TOMOYO_DIF_QUOTA_WARNED] = true;
958 printk(KERN_WARNING "TOMOYO-WARNING: " 1011 /* r->granted = false; */
959 "Domain '%s' has so many ACLs to hold. " 1012 tomoyo_write_log(r, "%s", tomoyo_dif[TOMOYO_DIF_QUOTA_WARNED]);
1013 printk(KERN_WARNING "WARNING: "
1014 "Domain '%s' has too many ACLs to hold. "
960 "Stopped learning mode.\n", domain->domainname->name); 1015 "Stopped learning mode.\n", domain->domainname->name);
961 } 1016 }
962 return false; 1017 return false;