tomoyo.c revision c656ae95d1c5c8ed5763356263ace2d03087efec
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 17static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp) 18{ 19 new->security = NULL; 20 return 0; 21} 22 23static 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 34static 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 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 * 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 71static 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 * '1' is the result of open_to_namei_flags(O_RDONLY). 84 */ 85 return tomoyo_check_open_permission(domain, &bprm->file->f_path, 1); 86} 87 88static int tomoyo_path_truncate(struct path *path, loff_t length, 89 unsigned int time_attrs) 90{ 91 return tomoyo_check_1path_perm(tomoyo_domain(), 92 TOMOYO_TYPE_TRUNCATE_ACL, 93 path); 94} 95 96static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) 97{ 98 struct path path = { parent->mnt, dentry }; 99 return tomoyo_check_1path_perm(tomoyo_domain(), 100 TOMOYO_TYPE_UNLINK_ACL, 101 &path); 102} 103 104static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, 105 int mode) 106{ 107 struct path path = { parent->mnt, dentry }; 108 return tomoyo_check_1path_perm(tomoyo_domain(), 109 TOMOYO_TYPE_MKDIR_ACL, 110 &path); 111} 112 113static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) 114{ 115 struct path path = { parent->mnt, dentry }; 116 return tomoyo_check_1path_perm(tomoyo_domain(), 117 TOMOYO_TYPE_RMDIR_ACL, 118 &path); 119} 120 121static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, 122 const char *old_name) 123{ 124 struct path path = { parent->mnt, dentry }; 125 return tomoyo_check_1path_perm(tomoyo_domain(), 126 TOMOYO_TYPE_SYMLINK_ACL, 127 &path); 128} 129 130static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, 131 int mode, unsigned int dev) 132{ 133 struct path path = { parent->mnt, dentry }; 134 int type = TOMOYO_TYPE_CREATE_ACL; 135 136 switch (mode & S_IFMT) { 137 case S_IFCHR: 138 type = TOMOYO_TYPE_MKCHAR_ACL; 139 break; 140 case S_IFBLK: 141 type = TOMOYO_TYPE_MKBLOCK_ACL; 142 break; 143 case S_IFIFO: 144 type = TOMOYO_TYPE_MKFIFO_ACL; 145 break; 146 case S_IFSOCK: 147 type = TOMOYO_TYPE_MKSOCK_ACL; 148 break; 149 } 150 return tomoyo_check_1path_perm(tomoyo_domain(), 151 type, &path); 152} 153 154static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir, 155 struct dentry *new_dentry) 156{ 157 struct path path1 = { new_dir->mnt, old_dentry }; 158 struct path path2 = { new_dir->mnt, new_dentry }; 159 return tomoyo_check_2path_perm(tomoyo_domain(), 160 TOMOYO_TYPE_LINK_ACL, 161 &path1, &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_check_2path_perm(tomoyo_domain(), 172 TOMOYO_TYPE_RENAME_ACL, 173 &path1, &path2); 174} 175 176static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, 177 unsigned long arg) 178{ 179 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)) 180 return tomoyo_check_rewrite_permission(tomoyo_domain(), file); 181 return 0; 182} 183 184static int tomoyo_dentry_open(struct file *f, const struct cred *cred) 185{ 186 int flags = f->f_flags; 187 188 if ((flags + 1) & O_ACCMODE) 189 flags++; 190 flags |= f->f_flags & (O_APPEND | O_TRUNC); 191 /* Don't check read permission here if called from do_execve(). */ 192 if (current->in_execve) 193 return 0; 194 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 195} 196 197/* 198 * tomoyo_security_ops is a "struct security_operations" which is used for 199 * registering TOMOYO. 200 */ 201static struct security_operations tomoyo_security_ops = { 202 .name = "tomoyo", 203 .cred_alloc_blank = tomoyo_cred_alloc_blank, 204 .cred_prepare = tomoyo_cred_prepare, 205 .cred_transfer = tomoyo_cred_transfer, 206 .bprm_set_creds = tomoyo_bprm_set_creds, 207 .bprm_check_security = tomoyo_bprm_check_security, 208 .file_fcntl = tomoyo_file_fcntl, 209 .dentry_open = tomoyo_dentry_open, 210 .path_truncate = tomoyo_path_truncate, 211 .path_unlink = tomoyo_path_unlink, 212 .path_mkdir = tomoyo_path_mkdir, 213 .path_rmdir = tomoyo_path_rmdir, 214 .path_symlink = tomoyo_path_symlink, 215 .path_mknod = tomoyo_path_mknod, 216 .path_link = tomoyo_path_link, 217 .path_rename = tomoyo_path_rename, 218}; 219 220static int __init tomoyo_init(void) 221{ 222 struct cred *cred = (struct cred *) current_cred(); 223 224 if (!security_module_enable(&tomoyo_security_ops)) 225 return 0; 226 /* register ourselves with the security framework */ 227 if (register_security(&tomoyo_security_ops)) 228 panic("Failure registering TOMOYO Linux"); 229 printk(KERN_INFO "TOMOYO Linux initialized\n"); 230 cred->security = &tomoyo_kernel_domain; 231 tomoyo_realpath_init(); 232 return 0; 233} 234 235security_initcall(tomoyo_init); 236