tomoyo.c revision 97d6931ead3e89a764cdaa3ad0924037367f0d34
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_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_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_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_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_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(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_TYPE_LINK, &path1, &path2); 161} 162 163static int tomoyo_path_rename(struct path *old_parent, 164 struct dentry *old_dentry, 165 struct path *new_parent, 166 struct dentry *new_dentry) 167{ 168 struct path path1 = { old_parent->mnt, old_dentry }; 169 struct path path2 = { new_parent->mnt, new_dentry }; 170 return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2); 171} 172 173static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, 174 unsigned long arg) 175{ 176 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)) 177 return tomoyo_check_rewrite_permission(file); 178 return 0; 179} 180 181static int tomoyo_dentry_open(struct file *f, const struct cred *cred) 182{ 183 int flags = f->f_flags; 184 185 if ((flags + 1) & O_ACCMODE) 186 flags++; 187 flags |= f->f_flags & (O_APPEND | O_TRUNC); 188 /* Don't check read permission here if called from do_execve(). */ 189 if (current->in_execve) 190 return 0; 191 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 192} 193 194static int tomoyo_file_ioctl(struct file *file, unsigned int cmd, 195 unsigned long arg) 196{ 197 return tomoyo_path_perm(TOMOYO_TYPE_IOCTL, &file->f_path); 198} 199 200static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt, 201 mode_t mode) 202{ 203 struct path path = { mnt, dentry }; 204 return tomoyo_path_perm(TOMOYO_TYPE_CHMOD, &path); 205} 206 207static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid) 208{ 209 int error = 0; 210 if (uid != (uid_t) -1) 211 error = tomoyo_path_perm(TOMOYO_TYPE_CHOWN, path); 212 if (!error && gid != (gid_t) -1) 213 error = tomoyo_path_perm(TOMOYO_TYPE_CHGRP, path); 214 return error; 215} 216 217static int tomoyo_path_chroot(struct path *path) 218{ 219 return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path); 220} 221 222static int tomoyo_sb_mount(char *dev_name, struct path *path, 223 char *type, unsigned long flags, void *data) 224{ 225 return tomoyo_path_perm(TOMOYO_TYPE_MOUNT, path); 226} 227 228static int tomoyo_sb_umount(struct vfsmount *mnt, int flags) 229{ 230 struct path path = { mnt, mnt->mnt_root }; 231 return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path); 232} 233 234static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path) 235{ 236 return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path); 237} 238 239/* 240 * tomoyo_security_ops is a "struct security_operations" which is used for 241 * registering TOMOYO. 242 */ 243static struct security_operations tomoyo_security_ops = { 244 .name = "tomoyo", 245 .cred_alloc_blank = tomoyo_cred_alloc_blank, 246 .cred_prepare = tomoyo_cred_prepare, 247 .cred_transfer = tomoyo_cred_transfer, 248 .cred_free = tomoyo_cred_free, 249 .bprm_set_creds = tomoyo_bprm_set_creds, 250 .bprm_check_security = tomoyo_bprm_check_security, 251 .file_fcntl = tomoyo_file_fcntl, 252 .dentry_open = tomoyo_dentry_open, 253 .path_truncate = tomoyo_path_truncate, 254 .path_unlink = tomoyo_path_unlink, 255 .path_mkdir = tomoyo_path_mkdir, 256 .path_rmdir = tomoyo_path_rmdir, 257 .path_symlink = tomoyo_path_symlink, 258 .path_mknod = tomoyo_path_mknod, 259 .path_link = tomoyo_path_link, 260 .path_rename = tomoyo_path_rename, 261 .file_ioctl = tomoyo_file_ioctl, 262 .path_chmod = tomoyo_path_chmod, 263 .path_chown = tomoyo_path_chown, 264 .path_chroot = tomoyo_path_chroot, 265 .sb_mount = tomoyo_sb_mount, 266 .sb_umount = tomoyo_sb_umount, 267 .sb_pivotroot = tomoyo_sb_pivotroot, 268}; 269 270/* Lock for GC. */ 271struct srcu_struct tomoyo_ss; 272 273static int __init tomoyo_init(void) 274{ 275 struct cred *cred = (struct cred *) current_cred(); 276 277 if (!security_module_enable(&tomoyo_security_ops)) 278 return 0; 279 /* register ourselves with the security framework */ 280 if (register_security(&tomoyo_security_ops) || 281 init_srcu_struct(&tomoyo_ss)) 282 panic("Failure registering TOMOYO Linux"); 283 printk(KERN_INFO "TOMOYO Linux initialized\n"); 284 cred->security = &tomoyo_kernel_domain; 285 tomoyo_realpath_init(); 286 return 0; 287} 288 289security_initcall(tomoyo_init); 290