tomoyo.c revision 7ef612331fb219620cc1abfc2446bb027d388aa0
1/* 2 * security/tomoyo/tomoyo.c 3 * 4 * LSM hooks for TOMOYO Linux. 5 * 6 * Copyright (C) 2005-2009 NTT DATA CORPORATION 7 * 8 * Version: 2.2.0 2009/04/01 9 * 10 */ 11 12#include <linux/security.h> 13#include "common.h" 14 15static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp) 16{ 17 new->security = NULL; 18 return 0; 19} 20 21static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, 22 gfp_t gfp) 23{ 24 struct tomoyo_domain_info *domain = old->security; 25 new->security = domain; 26 if (domain) 27 atomic_inc(&domain->users); 28 return 0; 29} 30 31static void tomoyo_cred_transfer(struct cred *new, const struct cred *old) 32{ 33 tomoyo_cred_prepare(new, old, 0); 34} 35 36static void tomoyo_cred_free(struct cred *cred) 37{ 38 struct tomoyo_domain_info *domain = cred->security; 39 if (domain) 40 atomic_dec(&domain->users); 41} 42 43static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) 44{ 45 int rc; 46 47 rc = cap_bprm_set_creds(bprm); 48 if (rc) 49 return rc; 50 51 /* 52 * Do only if this function is called for the first time of an execve 53 * operation. 54 */ 55 if (bprm->cred_prepared) 56 return 0; 57 /* 58 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested 59 * for the first time. 60 */ 61 if (!tomoyo_policy_loaded) 62 tomoyo_load_policy(bprm->filename); 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 /* 72 * Tell tomoyo_bprm_check_security() is called for the first time of an 73 * execve operation. 74 */ 75 bprm->cred->security = NULL; 76 return 0; 77} 78 79static int tomoyo_bprm_check_security(struct linux_binprm *bprm) 80{ 81 struct tomoyo_domain_info *domain = bprm->cred->security; 82 83 /* 84 * Execute permission is checked against pathname passed to do_execve() 85 * using current domain. 86 */ 87 if (!domain) { 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 } 93 /* 94 * Read permission is checked against interpreters using next domain. 95 * '1' is the result of open_to_namei_flags(O_RDONLY). 96 */ 97 return tomoyo_check_open_permission(domain, &bprm->file->f_path, 1); 98} 99 100static int tomoyo_path_truncate(struct path *path, loff_t length, 101 unsigned int time_attrs) 102{ 103 return tomoyo_path_perm(tomoyo_domain(), TOMOYO_TYPE_TRUNCATE, path); 104} 105 106static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) 107{ 108 struct path path = { parent->mnt, dentry }; 109 return tomoyo_path_perm(tomoyo_domain(), TOMOYO_TYPE_UNLINK, &path); 110} 111 112static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, 113 int mode) 114{ 115 struct path path = { parent->mnt, dentry }; 116 return tomoyo_path_perm(tomoyo_domain(), TOMOYO_TYPE_MKDIR, &path); 117} 118 119static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) 120{ 121 struct path path = { parent->mnt, dentry }; 122 return tomoyo_path_perm(tomoyo_domain(), TOMOYO_TYPE_RMDIR, &path); 123} 124 125static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, 126 const char *old_name) 127{ 128 struct path path = { parent->mnt, dentry }; 129 return tomoyo_path_perm(tomoyo_domain(), TOMOYO_TYPE_SYMLINK, &path); 130} 131 132static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, 133 int mode, unsigned int dev) 134{ 135 struct path path = { parent->mnt, dentry }; 136 int type = TOMOYO_TYPE_CREATE; 137 138 switch (mode & S_IFMT) { 139 case S_IFCHR: 140 type = TOMOYO_TYPE_MKCHAR; 141 break; 142 case S_IFBLK: 143 type = TOMOYO_TYPE_MKBLOCK; 144 break; 145 case S_IFIFO: 146 type = TOMOYO_TYPE_MKFIFO; 147 break; 148 case S_IFSOCK: 149 type = TOMOYO_TYPE_MKSOCK; 150 break; 151 } 152 return tomoyo_path_perm(tomoyo_domain(), type, &path); 153} 154 155static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir, 156 struct dentry *new_dentry) 157{ 158 struct path path1 = { new_dir->mnt, old_dentry }; 159 struct path path2 = { new_dir->mnt, new_dentry }; 160 return tomoyo_path2_perm(tomoyo_domain(), TOMOYO_TYPE_LINK, &path1, 161 &path2); 162} 163 164static int tomoyo_path_rename(struct path *old_parent, 165 struct dentry *old_dentry, 166 struct path *new_parent, 167 struct dentry *new_dentry) 168{ 169 struct path path1 = { old_parent->mnt, old_dentry }; 170 struct path path2 = { new_parent->mnt, new_dentry }; 171 return tomoyo_path2_perm(tomoyo_domain(), TOMOYO_TYPE_RENAME, &path1, 172 &path2); 173} 174 175static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, 176 unsigned long arg) 177{ 178 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)) 179 return tomoyo_check_rewrite_permission(tomoyo_domain(), file); 180 return 0; 181} 182 183static int tomoyo_dentry_open(struct file *f, const struct cred *cred) 184{ 185 int flags = f->f_flags; 186 187 if ((flags + 1) & O_ACCMODE) 188 flags++; 189 flags |= f->f_flags & (O_APPEND | O_TRUNC); 190 /* Don't check read permission here if called from do_execve(). */ 191 if (current->in_execve) 192 return 0; 193 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 194} 195 196static int tomoyo_file_ioctl(struct file *file, unsigned int cmd, 197 unsigned long arg) 198{ 199 return tomoyo_path_perm(tomoyo_domain(), TOMOYO_TYPE_IOCTL, 200 &file->f_path); 201} 202 203static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt, 204 mode_t mode) 205{ 206 struct path path = { mnt, dentry }; 207 return tomoyo_path_perm(tomoyo_domain(), TOMOYO_TYPE_CHMOD, &path); 208} 209 210static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid) 211{ 212 int error = 0; 213 if (uid != (uid_t) -1) 214 error = tomoyo_path_perm(tomoyo_domain(), TOMOYO_TYPE_CHOWN, 215 path); 216 if (!error && gid != (gid_t) -1) 217 error = tomoyo_path_perm(tomoyo_domain(), TOMOYO_TYPE_CHGRP, 218 path); 219 return error; 220} 221 222static int tomoyo_path_chroot(struct path *path) 223{ 224 return tomoyo_path_perm(tomoyo_domain(), TOMOYO_TYPE_CHROOT, path); 225} 226 227static int tomoyo_sb_mount(char *dev_name, struct path *path, 228 char *type, unsigned long flags, void *data) 229{ 230 return tomoyo_path_perm(tomoyo_domain(), TOMOYO_TYPE_MOUNT, path); 231} 232 233static int tomoyo_sb_umount(struct vfsmount *mnt, int flags) 234{ 235 struct path path = { mnt, mnt->mnt_root }; 236 return tomoyo_path_perm(tomoyo_domain(), TOMOYO_TYPE_UMOUNT, &path); 237} 238 239static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path) 240{ 241 return tomoyo_path2_perm(tomoyo_domain(), TOMOYO_TYPE_PIVOT_ROOT, 242 new_path, old_path); 243} 244 245/* 246 * tomoyo_security_ops is a "struct security_operations" which is used for 247 * registering TOMOYO. 248 */ 249static struct security_operations tomoyo_security_ops = { 250 .name = "tomoyo", 251 .cred_alloc_blank = tomoyo_cred_alloc_blank, 252 .cred_prepare = tomoyo_cred_prepare, 253 .cred_transfer = tomoyo_cred_transfer, 254 .cred_free = tomoyo_cred_free, 255 .bprm_set_creds = tomoyo_bprm_set_creds, 256 .bprm_check_security = tomoyo_bprm_check_security, 257 .file_fcntl = tomoyo_file_fcntl, 258 .dentry_open = tomoyo_dentry_open, 259 .path_truncate = tomoyo_path_truncate, 260 .path_unlink = tomoyo_path_unlink, 261 .path_mkdir = tomoyo_path_mkdir, 262 .path_rmdir = tomoyo_path_rmdir, 263 .path_symlink = tomoyo_path_symlink, 264 .path_mknod = tomoyo_path_mknod, 265 .path_link = tomoyo_path_link, 266 .path_rename = tomoyo_path_rename, 267 .file_ioctl = tomoyo_file_ioctl, 268 .path_chmod = tomoyo_path_chmod, 269 .path_chown = tomoyo_path_chown, 270 .path_chroot = tomoyo_path_chroot, 271 .sb_mount = tomoyo_sb_mount, 272 .sb_umount = tomoyo_sb_umount, 273 .sb_pivotroot = tomoyo_sb_pivotroot, 274}; 275 276/* Lock for GC. */ 277struct srcu_struct tomoyo_ss; 278 279static int __init tomoyo_init(void) 280{ 281 struct cred *cred = (struct cred *) current_cred(); 282 283 if (!security_module_enable(&tomoyo_security_ops)) 284 return 0; 285 /* register ourselves with the security framework */ 286 if (register_security(&tomoyo_security_ops) || 287 init_srcu_struct(&tomoyo_ss)) 288 panic("Failure registering TOMOYO Linux"); 289 printk(KERN_INFO "TOMOYO Linux initialized\n"); 290 cred->security = &tomoyo_kernel_domain; 291 tomoyo_realpath_init(); 292 return 0; 293} 294 295security_initcall(tomoyo_init); 296