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 #include "tomoyo.h" 15 #include "realpath.h" 16 17 static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp) 18 { 19 new->security = NULL; 20 return 0; 21 } 22 23 static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, 24 gfp_t gfp) 25 { 26 /* 27 * Since "struct tomoyo_domain_info *" is a sharable pointer, 28 * we don't need to duplicate. 29 */ 30 new->security = old->security; 31 return 0; 32 } 33 34 static void tomoyo_cred_transfer(struct cred *new, const struct cred *old) 35 { 36 /* 37 * Since "struct tomoyo_domain_info *" is a sharable pointer, 38 * we don't need to duplicate. 39 */ 40 new->security = old->security; 41 } 42 43 static 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 * Tell tomoyo_bprm_check_security() is called for the first time of an 65 * execve operation. 66 */ 67 bprm->cred->security = NULL; 68 return 0; 69 } 70 71 static int tomoyo_bprm_check_security(struct linux_binprm *bprm) 72 { 73 struct tomoyo_domain_info *domain = bprm->cred->security; 74 75 /* 76 * Execute permission is checked against pathname passed to do_execve() 77 * using current domain. 78 */ 79 if (!domain) 80 return tomoyo_find_next_domain(bprm); 81 /* 82 * Read permission is checked against interpreters using next domain. 83 */ 84 return tomoyo_check_open_permission(domain, &bprm->file->f_path, O_RDONLY); 85 } 86 87 static int tomoyo_path_truncate(struct path *path, loff_t length, 88 unsigned int time_attrs) 89 { 90 return tomoyo_check_1path_perm(tomoyo_domain(), 91 TOMOYO_TYPE_TRUNCATE_ACL, 92 path); 93 } 94 95 static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) 96 { 97 struct path path = { parent->mnt, dentry }; 98 return tomoyo_check_1path_perm(tomoyo_domain(), 99 TOMOYO_TYPE_UNLINK_ACL, 100 &path); 101 } 102 103 static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, 104 int mode) 105 { 106 struct path path = { parent->mnt, dentry }; 107 return tomoyo_check_1path_perm(tomoyo_domain(), 108 TOMOYO_TYPE_MKDIR_ACL, 109 &path); 110 } 111 112 static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) 113 { 114 struct path path = { parent->mnt, dentry }; 115 return tomoyo_check_1path_perm(tomoyo_domain(), 116 TOMOYO_TYPE_RMDIR_ACL, 117 &path); 118 } 119 120 static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, 121 const char *old_name) 122 { 123 struct path path = { parent->mnt, dentry }; 124 return tomoyo_check_1path_perm(tomoyo_domain(), 125 TOMOYO_TYPE_SYMLINK_ACL, 126 &path); 127 } 128 129 static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, 130 int mode, unsigned int dev) 131 { 132 struct path path = { parent->mnt, dentry }; 133 int type = TOMOYO_TYPE_CREATE_ACL; 134 135 switch (mode & S_IFMT) { 136 case S_IFCHR: 137 type = TOMOYO_TYPE_MKCHAR_ACL; 138 break; 139 case S_IFBLK: 140 type = TOMOYO_TYPE_MKBLOCK_ACL; 141 break; 142 case S_IFIFO: 143 type = TOMOYO_TYPE_MKFIFO_ACL; 144 break; 145 case S_IFSOCK: 146 type = TOMOYO_TYPE_MKSOCK_ACL; 147 break; 148 } 149 return tomoyo_check_1path_perm(tomoyo_domain(), 150 type, &path); 151 } 152 153 static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir, 154 struct dentry *new_dentry) 155 { 156 struct path path1 = { new_dir->mnt, old_dentry }; 157 struct path path2 = { new_dir->mnt, new_dentry }; 158 return tomoyo_check_2path_perm(tomoyo_domain(), 159 TOMOYO_TYPE_LINK_ACL, 160 &path1, &path2); 161 } 162 163 static 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_check_2path_perm(tomoyo_domain(), 171 TOMOYO_TYPE_RENAME_ACL, 172 &path1, &path2); 173 } 174 175 static 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 183 static int tomoyo_dentry_open(struct file *f, const struct cred *cred) 184 { 185 int flags = f->f_flags; 186 /* Don't check read permission here if called from do_execve(). */ 187 if (current->in_execve) 188 return 0; 189 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 190 } 191 192 /* 193 * tomoyo_security_ops is a "struct security_operations" which is used for 194 * registering TOMOYO. 195 */ 196 static struct security_operations tomoyo_security_ops = { 197 .name = "tomoyo", 198 .cred_alloc_blank = tomoyo_cred_alloc_blank, 199 .cred_prepare = tomoyo_cred_prepare, 200 .cred_transfer = tomoyo_cred_transfer, 201 .bprm_set_creds = tomoyo_bprm_set_creds, 202 .bprm_check_security = tomoyo_bprm_check_security, 203 .file_fcntl = tomoyo_file_fcntl, 204 .dentry_open = tomoyo_dentry_open, 205 .path_truncate = tomoyo_path_truncate, 206 .path_unlink = tomoyo_path_unlink, 207 .path_mkdir = tomoyo_path_mkdir, 208 .path_rmdir = tomoyo_path_rmdir, 209 .path_symlink = tomoyo_path_symlink, 210 .path_mknod = tomoyo_path_mknod, 211 .path_link = tomoyo_path_link, 212 .path_rename = tomoyo_path_rename, 213 }; 214 215 static int __init tomoyo_init(void) 216 { 217 struct cred *cred = (struct cred *) current_cred(); 218 219 if (!security_module_enable(&tomoyo_security_ops)) 220 return 0; 221 /* register ourselves with the security framework */ 222 if (register_security(&tomoyo_security_ops)) 223 panic("Failure registering TOMOYO Linux"); 224 printk(KERN_INFO "TOMOYO Linux initialized\n"); 225 cred->security = &tomoyo_kernel_domain; 226 tomoyo_realpath_init(); 227 return 0; 228 } 229 230 security_initcall(tomoyo_init); 231