aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/tomoyo.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/tomoyo.c')
-rw-r--r--security/tomoyo/tomoyo.c142
1 files changed, 98 insertions, 44 deletions
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index 2aceebf5f354..dedd97d0c163 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -11,8 +11,6 @@
11 11
12#include <linux/security.h> 12#include <linux/security.h>
13#include "common.h" 13#include "common.h"
14#include "tomoyo.h"
15#include "realpath.h"
16 14
17static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp) 15static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
18{ 16{
@@ -23,21 +21,23 @@ static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
23static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, 21static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
24 gfp_t gfp) 22 gfp_t gfp)
25{ 23{
26 /* 24 struct tomoyo_domain_info *domain = old->security;
27 * Since "struct tomoyo_domain_info *" is a sharable pointer, 25 new->security = domain;
28 * we don't need to duplicate. 26 if (domain)
29 */ 27 atomic_inc(&domain->users);
30 new->security = old->security;
31 return 0; 28 return 0;
32} 29}
33 30
34static void tomoyo_cred_transfer(struct cred *new, const struct cred *old) 31static void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
35{ 32{
36 /* 33 tomoyo_cred_prepare(new, old, 0);
37 * Since "struct tomoyo_domain_info *" is a sharable pointer, 34}
38 * we don't need to duplicate. 35
39 */ 36static void tomoyo_cred_free(struct cred *cred)
40 new->security = old->security; 37{
38 struct tomoyo_domain_info *domain = cred->security;
39 if (domain)
40 atomic_dec(&domain->users);
41} 41}
42 42
43static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) 43static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
@@ -61,6 +61,14 @@ static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
61 if (!tomoyo_policy_loaded) 61 if (!tomoyo_policy_loaded)
62 tomoyo_load_policy(bprm->filename); 62 tomoyo_load_policy(bprm->filename);
63 /* 63 /*
64 * Release reference to "struct tomoyo_domain_info" stored inside
65 * "bprm->cred->security". New reference to "struct tomoyo_domain_info"
66 * stored inside "bprm->cred->security" will be acquired later inside
67 * tomoyo_find_next_domain().
68 */
69 atomic_dec(&((struct tomoyo_domain_info *)
70 bprm->cred->security)->users);
71 /*
64 * Tell tomoyo_bprm_check_security() is called for the first time of an 72 * Tell tomoyo_bprm_check_security() is called for the first time of an
65 * execve operation. 73 * execve operation.
66 */ 74 */
@@ -76,8 +84,12 @@ static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
76 * Execute permission is checked against pathname passed to do_execve() 84 * Execute permission is checked against pathname passed to do_execve()
77 * using current domain. 85 * using current domain.
78 */ 86 */
79 if (!domain) 87 if (!domain) {
80 return tomoyo_find_next_domain(bprm); 88 const int idx = tomoyo_read_lock();
89 const int err = tomoyo_find_next_domain(bprm);
90 tomoyo_read_unlock(idx);
91 return err;
92 }
81 /* 93 /*
82 * Read permission is checked against interpreters using next domain. 94 * Read permission is checked against interpreters using next domain.
83 */ 95 */
@@ -87,67 +99,56 @@ static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
87static int tomoyo_path_truncate(struct path *path, loff_t length, 99static int tomoyo_path_truncate(struct path *path, loff_t length,
88 unsigned int time_attrs) 100 unsigned int time_attrs)
89{ 101{
90 return tomoyo_check_1path_perm(tomoyo_domain(), 102 return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path);
91 TOMOYO_TYPE_TRUNCATE_ACL,
92 path);
93} 103}
94 104
95static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) 105static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry)
96{ 106{
97 struct path path = { parent->mnt, dentry }; 107 struct path path = { parent->mnt, dentry };
98 return tomoyo_check_1path_perm(tomoyo_domain(), 108 return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path);
99 TOMOYO_TYPE_UNLINK_ACL,
100 &path);
101} 109}
102 110
103static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, 111static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry,
104 int mode) 112 int mode)
105{ 113{
106 struct path path = { parent->mnt, dentry }; 114 struct path path = { parent->mnt, dentry };
107 return tomoyo_check_1path_perm(tomoyo_domain(), 115 return tomoyo_path_perm(TOMOYO_TYPE_MKDIR, &path);
108 TOMOYO_TYPE_MKDIR_ACL,
109 &path);
110} 116}
111 117
112static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) 118static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry)
113{ 119{
114 struct path path = { parent->mnt, dentry }; 120 struct path path = { parent->mnt, dentry };
115 return tomoyo_check_1path_perm(tomoyo_domain(), 121 return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path);
116 TOMOYO_TYPE_RMDIR_ACL,
117 &path);
118} 122}
119 123
120static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, 124static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry,
121 const char *old_name) 125 const char *old_name)
122{ 126{
123 struct path path = { parent->mnt, dentry }; 127 struct path path = { parent->mnt, dentry };
124 return tomoyo_check_1path_perm(tomoyo_domain(), 128 return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path);
125 TOMOYO_TYPE_SYMLINK_ACL,
126 &path);
127} 129}
128 130
129static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, 131static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry,
130 int mode, unsigned int dev) 132 int mode, unsigned int dev)
131{ 133{
132 struct path path = { parent->mnt, dentry }; 134 struct path path = { parent->mnt, dentry };
133 int type = TOMOYO_TYPE_CREATE_ACL; 135 int type = TOMOYO_TYPE_CREATE;
134 136
135 switch (mode & S_IFMT) { 137 switch (mode & S_IFMT) {
136 case S_IFCHR: 138 case S_IFCHR:
137 type = TOMOYO_TYPE_MKCHAR_ACL; 139 type = TOMOYO_TYPE_MKCHAR;
138 break; 140 break;
139 case S_IFBLK: 141 case S_IFBLK:
140 type = TOMOYO_TYPE_MKBLOCK_ACL; 142 type = TOMOYO_TYPE_MKBLOCK;
141 break; 143 break;
142 case S_IFIFO: 144 case S_IFIFO:
143 type = TOMOYO_TYPE_MKFIFO_ACL; 145 type = TOMOYO_TYPE_MKFIFO;
144 break; 146 break;
145 case S_IFSOCK: 147 case S_IFSOCK:
146 type = TOMOYO_TYPE_MKSOCK_ACL; 148 type = TOMOYO_TYPE_MKSOCK;
147 break; 149 break;
148 } 150 }
149 return tomoyo_check_1path_perm(tomoyo_domain(), 151 return tomoyo_path_perm(type, &path);
150 type, &path);
151} 152}
152 153
153static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir, 154static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
@@ -155,9 +156,7 @@ static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
155{ 156{
156 struct path path1 = { new_dir->mnt, old_dentry }; 157 struct path path1 = { new_dir->mnt, old_dentry };
157 struct path path2 = { new_dir->mnt, new_dentry }; 158 struct path path2 = { new_dir->mnt, new_dentry };
158 return tomoyo_check_2path_perm(tomoyo_domain(), 159 return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
159 TOMOYO_TYPE_LINK_ACL,
160 &path1, &path2);
161} 160}
162 161
163static int tomoyo_path_rename(struct path *old_parent, 162static int tomoyo_path_rename(struct path *old_parent,
@@ -167,16 +166,14 @@ static int tomoyo_path_rename(struct path *old_parent,
167{ 166{
168 struct path path1 = { old_parent->mnt, old_dentry }; 167 struct path path1 = { old_parent->mnt, old_dentry };
169 struct path path2 = { new_parent->mnt, new_dentry }; 168 struct path path2 = { new_parent->mnt, new_dentry };
170 return tomoyo_check_2path_perm(tomoyo_domain(), 169 return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
171 TOMOYO_TYPE_RENAME_ACL,
172 &path1, &path2);
173} 170}
174 171
175static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, 172static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
176 unsigned long arg) 173 unsigned long arg)
177{ 174{
178 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)) 175 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND))
179 return tomoyo_check_rewrite_permission(tomoyo_domain(), file); 176 return tomoyo_check_rewrite_permission(file);
180 return 0; 177 return 0;
181} 178}
182 179
@@ -189,6 +186,51 @@ static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
189 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 186 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
190} 187}
191 188
189static int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
190 unsigned long arg)
191{
192 return tomoyo_path_perm(TOMOYO_TYPE_IOCTL, &file->f_path);
193}
194
195static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
196 mode_t mode)
197{
198 struct path path = { mnt, dentry };
199 return tomoyo_path_perm(TOMOYO_TYPE_CHMOD, &path);
200}
201
202static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid)
203{
204 int error = 0;
205 if (uid != (uid_t) -1)
206 error = tomoyo_path_perm(TOMOYO_TYPE_CHOWN, path);
207 if (!error && gid != (gid_t) -1)
208 error = tomoyo_path_perm(TOMOYO_TYPE_CHGRP, path);
209 return error;
210}
211
212static int tomoyo_path_chroot(struct path *path)
213{
214 return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path);
215}
216
217static int tomoyo_sb_mount(char *dev_name, struct path *path,
218 char *type, unsigned long flags, void *data)
219{
220 return tomoyo_path_perm(TOMOYO_TYPE_MOUNT, path);
221}
222
223static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
224{
225 struct path path = { mnt, mnt->mnt_root };
226 return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path);
227}
228
229static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path)
230{
231 return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
232}
233
192/* 234/*
193 * tomoyo_security_ops is a "struct security_operations" which is used for 235 * tomoyo_security_ops is a "struct security_operations" which is used for
194 * registering TOMOYO. 236 * registering TOMOYO.
@@ -198,6 +240,7 @@ static struct security_operations tomoyo_security_ops = {
198 .cred_alloc_blank = tomoyo_cred_alloc_blank, 240 .cred_alloc_blank = tomoyo_cred_alloc_blank,
199 .cred_prepare = tomoyo_cred_prepare, 241 .cred_prepare = tomoyo_cred_prepare,
200 .cred_transfer = tomoyo_cred_transfer, 242 .cred_transfer = tomoyo_cred_transfer,
243 .cred_free = tomoyo_cred_free,
201 .bprm_set_creds = tomoyo_bprm_set_creds, 244 .bprm_set_creds = tomoyo_bprm_set_creds,
202 .bprm_check_security = tomoyo_bprm_check_security, 245 .bprm_check_security = tomoyo_bprm_check_security,
203 .file_fcntl = tomoyo_file_fcntl, 246 .file_fcntl = tomoyo_file_fcntl,
@@ -210,8 +253,18 @@ static struct security_operations tomoyo_security_ops = {
210 .path_mknod = tomoyo_path_mknod, 253 .path_mknod = tomoyo_path_mknod,
211 .path_link = tomoyo_path_link, 254 .path_link = tomoyo_path_link,
212 .path_rename = tomoyo_path_rename, 255 .path_rename = tomoyo_path_rename,
256 .file_ioctl = tomoyo_file_ioctl,
257 .path_chmod = tomoyo_path_chmod,
258 .path_chown = tomoyo_path_chown,
259 .path_chroot = tomoyo_path_chroot,
260 .sb_mount = tomoyo_sb_mount,
261 .sb_umount = tomoyo_sb_umount,
262 .sb_pivotroot = tomoyo_sb_pivotroot,
213}; 263};
214 264
265/* Lock for GC. */
266struct srcu_struct tomoyo_ss;
267
215static int __init tomoyo_init(void) 268static int __init tomoyo_init(void)
216{ 269{
217 struct cred *cred = (struct cred *) current_cred(); 270 struct cred *cred = (struct cred *) current_cred();
@@ -219,7 +272,8 @@ static int __init tomoyo_init(void)
219 if (!security_module_enable(&tomoyo_security_ops)) 272 if (!security_module_enable(&tomoyo_security_ops))
220 return 0; 273 return 0;
221 /* register ourselves with the security framework */ 274 /* register ourselves with the security framework */
222 if (register_security(&tomoyo_security_ops)) 275 if (register_security(&tomoyo_security_ops) ||
276 init_srcu_struct(&tomoyo_ss))
223 panic("Failure registering TOMOYO Linux"); 277 panic("Failure registering TOMOYO Linux");
224 printk(KERN_INFO "TOMOYO Linux initialized\n"); 278 printk(KERN_INFO "TOMOYO Linux initialized\n");
225 cred->security = &tomoyo_kernel_domain; 279 cred->security = &tomoyo_kernel_domain;