tomoyo.c revision 76bb0895d038be7bcdb6ccfcd2dd7deb30371d6b
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 /* 25 * Since "struct tomoyo_domain_info *" is a sharable pointer, 26 * we don't need to duplicate. 27 */ 28 new->security = old->security; 29 return 0; 30} 31 32static void tomoyo_cred_transfer(struct cred *new, const struct cred *old) 33{ 34 /* 35 * Since "struct tomoyo_domain_info *" is a sharable pointer, 36 * we don't need to duplicate. 37 */ 38 new->security = old->security; 39} 40 41static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) 42{ 43 int rc; 44 45 rc = cap_bprm_set_creds(bprm); 46 if (rc) 47 return rc; 48 49 /* 50 * Do only if this function is called for the first time of an execve 51 * operation. 52 */ 53 if (bprm->cred_prepared) 54 return 0; 55 /* 56 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested 57 * for the first time. 58 */ 59 if (!tomoyo_policy_loaded) 60 tomoyo_load_policy(bprm->filename); 61 /* 62 * Tell tomoyo_bprm_check_security() is called for the first time of an 63 * execve operation. 64 */ 65 bprm->cred->security = NULL; 66 return 0; 67} 68 69static int tomoyo_bprm_check_security(struct linux_binprm *bprm) 70{ 71 struct tomoyo_domain_info *domain = bprm->cred->security; 72 73 /* 74 * Execute permission is checked against pathname passed to do_execve() 75 * using current domain. 76 */ 77 if (!domain) { 78 /* 79 * We will need to protect whole execve() operation when GC 80 * starts kfree()ing "struct tomoyo_domain_info" because 81 * bprm->cred->security points to "struct tomoyo_domain_info" 82 * but "struct tomoyo_domain_info" does not have a refcounter. 83 */ 84 const int idx = tomoyo_read_lock(); 85 const int err = tomoyo_find_next_domain(bprm); 86 tomoyo_read_unlock(idx); 87 return err; 88 } 89 /* 90 * Read permission is checked against interpreters using next domain. 91 * '1' is the result of open_to_namei_flags(O_RDONLY). 92 */ 93 return tomoyo_check_open_permission(domain, &bprm->file->f_path, 1); 94} 95 96static int tomoyo_path_truncate(struct path *path, loff_t length, 97 unsigned int time_attrs) 98{ 99 return tomoyo_check_1path_perm(tomoyo_domain(), 100 TOMOYO_TYPE_TRUNCATE_ACL, 101 path); 102} 103 104static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) 105{ 106 struct path path = { parent->mnt, dentry }; 107 return tomoyo_check_1path_perm(tomoyo_domain(), 108 TOMOYO_TYPE_UNLINK_ACL, 109 &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_check_1path_perm(tomoyo_domain(), 117 TOMOYO_TYPE_MKDIR_ACL, 118 &path); 119} 120 121static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) 122{ 123 struct path path = { parent->mnt, dentry }; 124 return tomoyo_check_1path_perm(tomoyo_domain(), 125 TOMOYO_TYPE_RMDIR_ACL, 126 &path); 127} 128 129static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, 130 const char *old_name) 131{ 132 struct path path = { parent->mnt, dentry }; 133 return tomoyo_check_1path_perm(tomoyo_domain(), 134 TOMOYO_TYPE_SYMLINK_ACL, 135 &path); 136} 137 138static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, 139 int mode, unsigned int dev) 140{ 141 struct path path = { parent->mnt, dentry }; 142 int type = TOMOYO_TYPE_CREATE_ACL; 143 144 switch (mode & S_IFMT) { 145 case S_IFCHR: 146 type = TOMOYO_TYPE_MKCHAR_ACL; 147 break; 148 case S_IFBLK: 149 type = TOMOYO_TYPE_MKBLOCK_ACL; 150 break; 151 case S_IFIFO: 152 type = TOMOYO_TYPE_MKFIFO_ACL; 153 break; 154 case S_IFSOCK: 155 type = TOMOYO_TYPE_MKSOCK_ACL; 156 break; 157 } 158 return tomoyo_check_1path_perm(tomoyo_domain(), 159 type, &path); 160} 161 162static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir, 163 struct dentry *new_dentry) 164{ 165 struct path path1 = { new_dir->mnt, old_dentry }; 166 struct path path2 = { new_dir->mnt, new_dentry }; 167 return tomoyo_check_2path_perm(tomoyo_domain(), 168 TOMOYO_TYPE_LINK_ACL, 169 &path1, &path2); 170} 171 172static int tomoyo_path_rename(struct path *old_parent, 173 struct dentry *old_dentry, 174 struct path *new_parent, 175 struct dentry *new_dentry) 176{ 177 struct path path1 = { old_parent->mnt, old_dentry }; 178 struct path path2 = { new_parent->mnt, new_dentry }; 179 return tomoyo_check_2path_perm(tomoyo_domain(), 180 TOMOYO_TYPE_RENAME_ACL, 181 &path1, &path2); 182} 183 184static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, 185 unsigned long arg) 186{ 187 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)) 188 return tomoyo_check_rewrite_permission(tomoyo_domain(), file); 189 return 0; 190} 191 192static int tomoyo_dentry_open(struct file *f, const struct cred *cred) 193{ 194 int flags = f->f_flags; 195 196 if ((flags + 1) & O_ACCMODE) 197 flags++; 198 flags |= f->f_flags & (O_APPEND | O_TRUNC); 199 /* Don't check read permission here if called from do_execve(). */ 200 if (current->in_execve) 201 return 0; 202 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 203} 204 205static int tomoyo_file_ioctl(struct file *file, unsigned int cmd, 206 unsigned long arg) 207{ 208 return tomoyo_check_1path_perm(tomoyo_domain(), TOMOYO_TYPE_IOCTL_ACL, 209 &file->f_path); 210} 211 212static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt, 213 mode_t mode) 214{ 215 struct path path = { mnt, dentry }; 216 return tomoyo_check_1path_perm(tomoyo_domain(), TOMOYO_TYPE_CHMOD_ACL, 217 &path); 218} 219 220static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid) 221{ 222 int error = 0; 223 if (uid != (uid_t) -1) 224 error = tomoyo_check_1path_perm(tomoyo_domain(), 225 TOMOYO_TYPE_CHOWN_ACL, path); 226 if (!error && gid != (gid_t) -1) 227 error = tomoyo_check_1path_perm(tomoyo_domain(), 228 TOMOYO_TYPE_CHGRP_ACL, path); 229 return error; 230} 231 232static int tomoyo_path_chroot(struct path *path) 233{ 234 return tomoyo_check_1path_perm(tomoyo_domain(), TOMOYO_TYPE_CHROOT_ACL, 235 path); 236} 237 238static int tomoyo_sb_mount(char *dev_name, struct path *path, 239 char *type, unsigned long flags, void *data) 240{ 241 return tomoyo_check_1path_perm(tomoyo_domain(), TOMOYO_TYPE_MOUNT_ACL, 242 path); 243} 244 245static int tomoyo_sb_umount(struct vfsmount *mnt, int flags) 246{ 247 struct path path = { mnt, mnt->mnt_root }; 248 return tomoyo_check_1path_perm(tomoyo_domain(), TOMOYO_TYPE_UMOUNT_ACL, 249 &path); 250} 251 252static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path) 253{ 254 return tomoyo_check_2path_perm(tomoyo_domain(), 255 TOMOYO_TYPE_PIVOT_ROOT_ACL, 256 new_path, old_path); 257} 258 259/* 260 * tomoyo_security_ops is a "struct security_operations" which is used for 261 * registering TOMOYO. 262 */ 263static struct security_operations tomoyo_security_ops = { 264 .name = "tomoyo", 265 .cred_alloc_blank = tomoyo_cred_alloc_blank, 266 .cred_prepare = tomoyo_cred_prepare, 267 .cred_transfer = tomoyo_cred_transfer, 268 .bprm_set_creds = tomoyo_bprm_set_creds, 269 .bprm_check_security = tomoyo_bprm_check_security, 270 .file_fcntl = tomoyo_file_fcntl, 271 .dentry_open = tomoyo_dentry_open, 272 .path_truncate = tomoyo_path_truncate, 273 .path_unlink = tomoyo_path_unlink, 274 .path_mkdir = tomoyo_path_mkdir, 275 .path_rmdir = tomoyo_path_rmdir, 276 .path_symlink = tomoyo_path_symlink, 277 .path_mknod = tomoyo_path_mknod, 278 .path_link = tomoyo_path_link, 279 .path_rename = tomoyo_path_rename, 280 .file_ioctl = tomoyo_file_ioctl, 281 .path_chmod = tomoyo_path_chmod, 282 .path_chown = tomoyo_path_chown, 283 .path_chroot = tomoyo_path_chroot, 284 .sb_mount = tomoyo_sb_mount, 285 .sb_umount = tomoyo_sb_umount, 286 .sb_pivotroot = tomoyo_sb_pivotroot, 287}; 288 289/* Lock for GC. */ 290struct srcu_struct tomoyo_ss; 291 292static int __init tomoyo_init(void) 293{ 294 struct cred *cred = (struct cred *) current_cred(); 295 296 if (!security_module_enable(&tomoyo_security_ops)) 297 return 0; 298 /* register ourselves with the security framework */ 299 if (register_security(&tomoyo_security_ops) || 300 init_srcu_struct(&tomoyo_ss)) 301 panic("Failure registering TOMOYO Linux"); 302 printk(KERN_INFO "TOMOYO Linux initialized\n"); 303 cred->security = &tomoyo_kernel_domain; 304 tomoyo_realpath_init(); 305 return 0; 306} 307 308security_initcall(tomoyo_init); 309