Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

TOMOYO: Abstract use of cred security blob

Don't use the cred->security pointer directly.
Provide helper functions that provide the security blob pointer.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
[kees: adjusted for ordered init series]
Signed-off-by: Kees Cook <keescook@chromium.org>

authored by

Casey Schaufler and committed by
Kees Cook
43fc4609 69b5a44a

+64 -16
+19 -2
security/tomoyo/common.h
··· 29 29 #include <linux/in.h> 30 30 #include <linux/in6.h> 31 31 #include <linux/un.h> 32 + #include <linux/lsm_hooks.h> 32 33 #include <net/sock.h> 33 34 #include <net/af_unix.h> 34 35 #include <net/ip.h> ··· 1063 1062 /********** External variable definitions. **********/ 1064 1063 1065 1064 extern bool tomoyo_policy_loaded; 1065 + extern int tomoyo_enabled; 1066 1066 extern const char * const tomoyo_condition_keyword 1067 1067 [TOMOYO_MAX_CONDITION_KEYWORD]; 1068 1068 extern const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS]; ··· 1199 1197 } 1200 1198 1201 1199 /** 1200 + * tomoyo_cred - Get a pointer to the tomoyo cred security blob 1201 + * @cred - the relevant cred 1202 + * 1203 + * Returns pointer to the tomoyo cred blob. 1204 + */ 1205 + static inline struct tomoyo_domain_info **tomoyo_cred(const struct cred *cred) 1206 + { 1207 + return (struct tomoyo_domain_info **)&cred->security; 1208 + } 1209 + 1210 + /** 1202 1211 * tomoyo_domain - Get "struct tomoyo_domain_info" for current thread. 1203 1212 * 1204 1213 * Returns pointer to "struct tomoyo_domain_info" for current thread. 1205 1214 */ 1206 1215 static inline struct tomoyo_domain_info *tomoyo_domain(void) 1207 1216 { 1208 - return current_cred()->security; 1217 + struct tomoyo_domain_info **blob = tomoyo_cred(current_cred()); 1218 + 1219 + return *blob; 1209 1220 } 1210 1221 1211 1222 /** ··· 1231 1216 static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct 1232 1217 *task) 1233 1218 { 1234 - return task_cred_xxx(task, security); 1219 + struct tomoyo_domain_info **blob = tomoyo_cred(get_task_cred(task)); 1220 + 1221 + return *blob; 1235 1222 } 1236 1223 1237 1224 /**
+3 -1
security/tomoyo/domain.c
··· 678 678 */ 679 679 int tomoyo_find_next_domain(struct linux_binprm *bprm) 680 680 { 681 + struct tomoyo_domain_info **blob; 681 682 struct tomoyo_domain_info *old_domain = tomoyo_domain(); 682 683 struct tomoyo_domain_info *domain = NULL; 683 684 const char *original_name = bprm->filename; ··· 844 843 domain = old_domain; 845 844 /* Update reference count on "struct tomoyo_domain_info". */ 846 845 atomic_inc(&domain->users); 847 - bprm->cred->security = domain; 846 + blob = tomoyo_cred(bprm->cred); 847 + *blob = domain; 848 848 kfree(exename.name); 849 849 if (!retval) { 850 850 ee->r.domain = domain;
+11 -4
security/tomoyo/securityfs_if.c
··· 71 71 if (!cred) { 72 72 error = -ENOMEM; 73 73 } else { 74 - struct tomoyo_domain_info *old_domain = 75 - cred->security; 76 - cred->security = new_domain; 74 + struct tomoyo_domain_info **blob; 75 + struct tomoyo_domain_info *old_domain; 76 + 77 + blob = tomoyo_cred(cred); 78 + old_domain = *blob; 79 + *blob = new_domain; 77 80 atomic_inc(&new_domain->users); 78 81 atomic_dec(&old_domain->users); 79 82 commit_creds(cred); ··· 237 234 */ 238 235 static int __init tomoyo_initerface_init(void) 239 236 { 237 + struct tomoyo_domain_info *domain; 240 238 struct dentry *tomoyo_dir; 241 239 240 + if (!tomoyo_enabled) 241 + return 0; 242 + domain = tomoyo_domain(); 242 243 /* Don't create securityfs entries unless registered. */ 243 - if (current_cred()->security != &tomoyo_kernel_domain) 244 + if (domain != &tomoyo_kernel_domain) 244 245 return 0; 245 246 246 247 tomoyo_dir = securityfs_create_dir("tomoyo", NULL);
+31 -9
security/tomoyo/tomoyo.c
··· 18 18 */ 19 19 static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp) 20 20 { 21 - new->security = NULL; 21 + struct tomoyo_domain_info **blob = tomoyo_cred(new); 22 + 23 + *blob = NULL; 22 24 return 0; 23 25 } 24 26 ··· 36 34 static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, 37 35 gfp_t gfp) 38 36 { 39 - struct tomoyo_domain_info *domain = old->security; 40 - new->security = domain; 37 + struct tomoyo_domain_info **old_blob = tomoyo_cred(old); 38 + struct tomoyo_domain_info **new_blob = tomoyo_cred(new); 39 + struct tomoyo_domain_info *domain; 40 + 41 + domain = *old_blob; 42 + *new_blob = domain; 43 + 41 44 if (domain) 42 45 atomic_inc(&domain->users); 43 46 return 0; ··· 66 59 */ 67 60 static void tomoyo_cred_free(struct cred *cred) 68 61 { 69 - struct tomoyo_domain_info *domain = cred->security; 62 + struct tomoyo_domain_info **blob = tomoyo_cred(cred); 63 + struct tomoyo_domain_info *domain = *blob; 64 + 70 65 if (domain) 71 66 atomic_dec(&domain->users); 72 67 } ··· 82 73 */ 83 74 static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) 84 75 { 76 + struct tomoyo_domain_info **blob; 77 + struct tomoyo_domain_info *domain; 78 + 85 79 /* 86 80 * Do only if this function is called for the first time of an execve 87 81 * operation. ··· 105 93 * stored inside "bprm->cred->security" will be acquired later inside 106 94 * tomoyo_find_next_domain(). 107 95 */ 108 - atomic_dec(&((struct tomoyo_domain_info *) 109 - bprm->cred->security)->users); 96 + blob = tomoyo_cred(bprm->cred); 97 + domain = *blob; 98 + atomic_dec(&domain->users); 110 99 /* 111 100 * Tell tomoyo_bprm_check_security() is called for the first time of an 112 101 * execve operation. 113 102 */ 114 - bprm->cred->security = NULL; 103 + *blob = NULL; 115 104 return 0; 116 105 } 117 106 ··· 125 112 */ 126 113 static int tomoyo_bprm_check_security(struct linux_binprm *bprm) 127 114 { 128 - struct tomoyo_domain_info *domain = bprm->cred->security; 115 + struct tomoyo_domain_info **blob; 116 + struct tomoyo_domain_info *domain; 129 117 118 + blob = tomoyo_cred(bprm->cred); 119 + domain = *blob; 130 120 /* 131 121 * Execute permission is checked against pathname passed to do_execve() 132 122 * using current domain. ··· 547 531 /* Lock for GC. */ 548 532 DEFINE_SRCU(tomoyo_ss); 549 533 534 + int tomoyo_enabled __lsm_ro_after_init = 1; 535 + 550 536 /** 551 537 * tomoyo_init - Register TOMOYO Linux as a LSM module. 552 538 * ··· 557 539 static int __init tomoyo_init(void) 558 540 { 559 541 struct cred *cred = (struct cred *) current_cred(); 542 + struct tomoyo_domain_info **blob; 560 543 561 544 /* register ourselves with the security framework */ 562 545 security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo"); 563 546 printk(KERN_INFO "TOMOYO Linux initialized\n"); 564 - cred->security = &tomoyo_kernel_domain; 547 + blob = tomoyo_cred(cred); 548 + *blob = &tomoyo_kernel_domain; 565 549 tomoyo_mm_init(); 550 + 566 551 return 0; 567 552 } 568 553 569 554 DEFINE_LSM(tomoyo) = { 570 555 .name = "tomoyo", 556 + .enabled = &tomoyo_enabled, 571 557 .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE, 572 558 .init = tomoyo_init, 573 559 };