diff options
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r-- | security/smack/smack_lsm.c | 354 |
1 files changed, 246 insertions, 108 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index ccb71a044a1a..533bf3255d7f 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -3,12 +3,14 @@ | |||
3 | * | 3 | * |
4 | * This file contains the smack hook function implementations. | 4 | * This file contains the smack hook function implementations. |
5 | * | 5 | * |
6 | * Author: | 6 | * Authors: |
7 | * Casey Schaufler <casey@schaufler-ca.com> | 7 | * Casey Schaufler <casey@schaufler-ca.com> |
8 | * Jarkko Sakkinen <ext-jarkko.2.sakkinen@nokia.com> | ||
8 | * | 9 | * |
9 | * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> | 10 | * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> |
10 | * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. | 11 | * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. |
11 | * Paul Moore <paul.moore@hp.com> | 12 | * Paul Moore <paul.moore@hp.com> |
13 | * Copyright (C) 2010 Nokia Corporation | ||
12 | * | 14 | * |
13 | * This program is free software; you can redistribute it and/or modify | 15 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License version 2, | 16 | * it under the terms of the GNU General Public License version 2, |
@@ -35,6 +37,9 @@ | |||
35 | 37 | ||
36 | #define task_security(task) (task_cred_xxx((task), security)) | 38 | #define task_security(task) (task_cred_xxx((task), security)) |
37 | 39 | ||
40 | #define TRANS_TRUE "TRUE" | ||
41 | #define TRANS_TRUE_SIZE 4 | ||
42 | |||
38 | /** | 43 | /** |
39 | * smk_fetch - Fetch the smack label from a file. | 44 | * smk_fetch - Fetch the smack label from a file. |
40 | * @ip: a pointer to the inode | 45 | * @ip: a pointer to the inode |
@@ -43,7 +48,7 @@ | |||
43 | * Returns a pointer to the master list entry for the Smack label | 48 | * Returns a pointer to the master list entry for the Smack label |
44 | * or NULL if there was no label to fetch. | 49 | * or NULL if there was no label to fetch. |
45 | */ | 50 | */ |
46 | static char *smk_fetch(struct inode *ip, struct dentry *dp) | 51 | static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp) |
47 | { | 52 | { |
48 | int rc; | 53 | int rc; |
49 | char in[SMK_LABELLEN]; | 54 | char in[SMK_LABELLEN]; |
@@ -51,7 +56,7 @@ static char *smk_fetch(struct inode *ip, struct dentry *dp) | |||
51 | if (ip->i_op->getxattr == NULL) | 56 | if (ip->i_op->getxattr == NULL) |
52 | return NULL; | 57 | return NULL; |
53 | 58 | ||
54 | rc = ip->i_op->getxattr(dp, XATTR_NAME_SMACK, in, SMK_LABELLEN); | 59 | rc = ip->i_op->getxattr(dp, name, in, SMK_LABELLEN); |
55 | if (rc < 0) | 60 | if (rc < 0) |
56 | return NULL; | 61 | return NULL; |
57 | 62 | ||
@@ -103,8 +108,8 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) | |||
103 | if (rc != 0) | 108 | if (rc != 0) |
104 | return rc; | 109 | return rc; |
105 | 110 | ||
106 | sp = current_security(); | 111 | sp = smk_of_current(); |
107 | tsp = task_security(ctp); | 112 | tsp = smk_of_task(task_security(ctp)); |
108 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | 113 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); |
109 | smk_ad_setfield_u_tsk(&ad, ctp); | 114 | smk_ad_setfield_u_tsk(&ad, ctp); |
110 | 115 | ||
@@ -138,8 +143,8 @@ static int smack_ptrace_traceme(struct task_struct *ptp) | |||
138 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | 143 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); |
139 | smk_ad_setfield_u_tsk(&ad, ptp); | 144 | smk_ad_setfield_u_tsk(&ad, ptp); |
140 | 145 | ||
141 | sp = current_security(); | 146 | sp = smk_of_current(); |
142 | tsp = task_security(ptp); | 147 | tsp = smk_of_task(task_security(ptp)); |
143 | /* we won't log here, because rc can be overriden */ | 148 | /* we won't log here, because rc can be overriden */ |
144 | rc = smk_access(tsp, sp, MAY_READWRITE, NULL); | 149 | rc = smk_access(tsp, sp, MAY_READWRITE, NULL); |
145 | if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE)) | 150 | if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE)) |
@@ -160,7 +165,7 @@ static int smack_ptrace_traceme(struct task_struct *ptp) | |||
160 | static int smack_syslog(int typefrom_file) | 165 | static int smack_syslog(int typefrom_file) |
161 | { | 166 | { |
162 | int rc = 0; | 167 | int rc = 0; |
163 | char *sp = current_security(); | 168 | char *sp = smk_of_current(); |
164 | 169 | ||
165 | if (capable(CAP_MAC_OVERRIDE)) | 170 | if (capable(CAP_MAC_OVERRIDE)) |
166 | return 0; | 171 | return 0; |
@@ -391,6 +396,40 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags) | |||
391 | } | 396 | } |
392 | 397 | ||
393 | /* | 398 | /* |
399 | * BPRM hooks | ||
400 | */ | ||
401 | |||
402 | static int smack_bprm_set_creds(struct linux_binprm *bprm) | ||
403 | { | ||
404 | struct task_smack *tsp = bprm->cred->security; | ||
405 | struct inode_smack *isp; | ||
406 | struct dentry *dp; | ||
407 | int rc; | ||
408 | |||
409 | rc = cap_bprm_set_creds(bprm); | ||
410 | if (rc != 0) | ||
411 | return rc; | ||
412 | |||
413 | if (bprm->cred_prepared) | ||
414 | return 0; | ||
415 | |||
416 | if (bprm->file == NULL || bprm->file->f_dentry == NULL) | ||
417 | return 0; | ||
418 | |||
419 | dp = bprm->file->f_dentry; | ||
420 | |||
421 | if (dp->d_inode == NULL) | ||
422 | return 0; | ||
423 | |||
424 | isp = dp->d_inode->i_security; | ||
425 | |||
426 | if (isp->smk_task != NULL) | ||
427 | tsp->smk_task = isp->smk_task; | ||
428 | |||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | /* | ||
394 | * Inode hooks | 433 | * Inode hooks |
395 | */ | 434 | */ |
396 | 435 | ||
@@ -402,7 +441,7 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags) | |||
402 | */ | 441 | */ |
403 | static int smack_inode_alloc_security(struct inode *inode) | 442 | static int smack_inode_alloc_security(struct inode *inode) |
404 | { | 443 | { |
405 | inode->i_security = new_inode_smack(current_security()); | 444 | inode->i_security = new_inode_smack(smk_of_current()); |
406 | if (inode->i_security == NULL) | 445 | if (inode->i_security == NULL) |
407 | return -ENOMEM; | 446 | return -ENOMEM; |
408 | return 0; | 447 | return 0; |
@@ -434,6 +473,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, | |||
434 | char **name, void **value, size_t *len) | 473 | char **name, void **value, size_t *len) |
435 | { | 474 | { |
436 | char *isp = smk_of_inode(inode); | 475 | char *isp = smk_of_inode(inode); |
476 | char *dsp = smk_of_inode(dir); | ||
477 | u32 may; | ||
437 | 478 | ||
438 | if (name) { | 479 | if (name) { |
439 | *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL); | 480 | *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL); |
@@ -442,6 +483,16 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, | |||
442 | } | 483 | } |
443 | 484 | ||
444 | if (value) { | 485 | if (value) { |
486 | may = smk_access_entry(smk_of_current(), dsp); | ||
487 | |||
488 | /* | ||
489 | * If the access rule allows transmutation and | ||
490 | * the directory requests transmutation then | ||
491 | * by all means transmute. | ||
492 | */ | ||
493 | if (((may & MAY_TRANSMUTE) != 0) && smk_inode_transmutable(dir)) | ||
494 | isp = dsp; | ||
495 | |||
445 | *value = kstrdup(isp, GFP_KERNEL); | 496 | *value = kstrdup(isp, GFP_KERNEL); |
446 | if (*value == NULL) | 497 | if (*value == NULL) |
447 | return -ENOMEM; | 498 | return -ENOMEM; |
@@ -664,7 +715,8 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
664 | 715 | ||
665 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || | 716 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || |
666 | strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || | 717 | strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || |
667 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { | 718 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || |
719 | strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { | ||
668 | if (!capable(CAP_MAC_ADMIN)) | 720 | if (!capable(CAP_MAC_ADMIN)) |
669 | rc = -EPERM; | 721 | rc = -EPERM; |
670 | /* | 722 | /* |
@@ -674,6 +726,12 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
674 | if (size == 0 || size >= SMK_LABELLEN || | 726 | if (size == 0 || size >= SMK_LABELLEN || |
675 | smk_import(value, size) == NULL) | 727 | smk_import(value, size) == NULL) |
676 | rc = -EINVAL; | 728 | rc = -EINVAL; |
729 | } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { | ||
730 | if (!capable(CAP_MAC_ADMIN)) | ||
731 | rc = -EPERM; | ||
732 | if (size != TRANS_TRUE_SIZE || | ||
733 | strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) | ||
734 | rc = -EINVAL; | ||
677 | } else | 735 | } else |
678 | rc = cap_inode_setxattr(dentry, name, value, size, flags); | 736 | rc = cap_inode_setxattr(dentry, name, value, size, flags); |
679 | 737 | ||
@@ -700,26 +758,23 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
700 | static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, | 758 | static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, |
701 | const void *value, size_t size, int flags) | 759 | const void *value, size_t size, int flags) |
702 | { | 760 | { |
703 | struct inode_smack *isp; | ||
704 | char *nsp; | 761 | char *nsp; |
762 | struct inode_smack *isp = dentry->d_inode->i_security; | ||
705 | 763 | ||
706 | /* | 764 | if (strcmp(name, XATTR_NAME_SMACK) == 0) { |
707 | * Not SMACK | 765 | nsp = smk_import(value, size); |
708 | */ | 766 | if (nsp != NULL) |
709 | if (strcmp(name, XATTR_NAME_SMACK)) | 767 | isp->smk_inode = nsp; |
710 | return; | 768 | else |
711 | 769 | isp->smk_inode = smack_known_invalid.smk_known; | |
712 | isp = dentry->d_inode->i_security; | 770 | } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { |
713 | 771 | nsp = smk_import(value, size); | |
714 | /* | 772 | if (nsp != NULL) |
715 | * No locking is done here. This is a pointer | 773 | isp->smk_task = nsp; |
716 | * assignment. | 774 | else |
717 | */ | 775 | isp->smk_task = smack_known_invalid.smk_known; |
718 | nsp = smk_import(value, size); | 776 | } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) |
719 | if (nsp != NULL) | 777 | isp->smk_flags |= SMK_INODE_TRANSMUTE; |
720 | isp->smk_inode = nsp; | ||
721 | else | ||
722 | isp->smk_inode = smack_known_invalid.smk_known; | ||
723 | 778 | ||
724 | return; | 779 | return; |
725 | } | 780 | } |
@@ -752,12 +807,15 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name) | |||
752 | */ | 807 | */ |
753 | static int smack_inode_removexattr(struct dentry *dentry, const char *name) | 808 | static int smack_inode_removexattr(struct dentry *dentry, const char *name) |
754 | { | 809 | { |
810 | struct inode_smack *isp; | ||
755 | struct smk_audit_info ad; | 811 | struct smk_audit_info ad; |
756 | int rc = 0; | 812 | int rc = 0; |
757 | 813 | ||
758 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || | 814 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || |
759 | strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || | 815 | strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || |
760 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { | 816 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || |
817 | strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || | ||
818 | strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { | ||
761 | if (!capable(CAP_MAC_ADMIN)) | 819 | if (!capable(CAP_MAC_ADMIN)) |
762 | rc = -EPERM; | 820 | rc = -EPERM; |
763 | } else | 821 | } else |
@@ -768,6 +826,11 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) | |||
768 | if (rc == 0) | 826 | if (rc == 0) |
769 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); | 827 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); |
770 | 828 | ||
829 | if (rc == 0) { | ||
830 | isp = dentry->d_inode->i_security; | ||
831 | isp->smk_task = NULL; | ||
832 | } | ||
833 | |||
771 | return rc; | 834 | return rc; |
772 | } | 835 | } |
773 | 836 | ||
@@ -895,7 +958,7 @@ static int smack_file_permission(struct file *file, int mask) | |||
895 | */ | 958 | */ |
896 | static int smack_file_alloc_security(struct file *file) | 959 | static int smack_file_alloc_security(struct file *file) |
897 | { | 960 | { |
898 | file->f_security = current_security(); | 961 | file->f_security = smk_of_current(); |
899 | return 0; | 962 | return 0; |
900 | } | 963 | } |
901 | 964 | ||
@@ -1005,7 +1068,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, | |||
1005 | */ | 1068 | */ |
1006 | static int smack_file_set_fowner(struct file *file) | 1069 | static int smack_file_set_fowner(struct file *file) |
1007 | { | 1070 | { |
1008 | file->f_security = current_security(); | 1071 | file->f_security = smk_of_current(); |
1009 | return 0; | 1072 | return 0; |
1010 | } | 1073 | } |
1011 | 1074 | ||
@@ -1025,7 +1088,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, | |||
1025 | { | 1088 | { |
1026 | struct file *file; | 1089 | struct file *file; |
1027 | int rc; | 1090 | int rc; |
1028 | char *tsp = tsk->cred->security; | 1091 | char *tsp = smk_of_task(tsk->cred->security); |
1029 | struct smk_audit_info ad; | 1092 | struct smk_audit_info ad; |
1030 | 1093 | ||
1031 | /* | 1094 | /* |
@@ -1082,7 +1145,9 @@ static int smack_file_receive(struct file *file) | |||
1082 | */ | 1145 | */ |
1083 | static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) | 1146 | static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) |
1084 | { | 1147 | { |
1085 | cred->security = NULL; | 1148 | cred->security = kzalloc(sizeof(struct task_smack), gfp); |
1149 | if (cred->security == NULL) | ||
1150 | return -ENOMEM; | ||
1086 | return 0; | 1151 | return 0; |
1087 | } | 1152 | } |
1088 | 1153 | ||
@@ -1097,7 +1162,7 @@ static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) | |||
1097 | */ | 1162 | */ |
1098 | static void smack_cred_free(struct cred *cred) | 1163 | static void smack_cred_free(struct cred *cred) |
1099 | { | 1164 | { |
1100 | cred->security = NULL; | 1165 | kfree(cred->security); |
1101 | } | 1166 | } |
1102 | 1167 | ||
1103 | /** | 1168 | /** |
@@ -1111,7 +1176,16 @@ static void smack_cred_free(struct cred *cred) | |||
1111 | static int smack_cred_prepare(struct cred *new, const struct cred *old, | 1176 | static int smack_cred_prepare(struct cred *new, const struct cred *old, |
1112 | gfp_t gfp) | 1177 | gfp_t gfp) |
1113 | { | 1178 | { |
1114 | new->security = old->security; | 1179 | struct task_smack *old_tsp = old->security; |
1180 | struct task_smack *new_tsp; | ||
1181 | |||
1182 | new_tsp = kzalloc(sizeof(struct task_smack), gfp); | ||
1183 | if (new_tsp == NULL) | ||
1184 | return -ENOMEM; | ||
1185 | |||
1186 | new_tsp->smk_task = old_tsp->smk_task; | ||
1187 | new_tsp->smk_forked = old_tsp->smk_task; | ||
1188 | new->security = new_tsp; | ||
1115 | return 0; | 1189 | return 0; |
1116 | } | 1190 | } |
1117 | 1191 | ||
@@ -1124,7 +1198,11 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old, | |||
1124 | */ | 1198 | */ |
1125 | static void smack_cred_transfer(struct cred *new, const struct cred *old) | 1199 | static void smack_cred_transfer(struct cred *new, const struct cred *old) |
1126 | { | 1200 | { |
1127 | new->security = old->security; | 1201 | struct task_smack *old_tsp = old->security; |
1202 | struct task_smack *new_tsp = new->security; | ||
1203 | |||
1204 | new_tsp->smk_task = old_tsp->smk_task; | ||
1205 | new_tsp->smk_forked = old_tsp->smk_task; | ||
1128 | } | 1206 | } |
1129 | 1207 | ||
1130 | /** | 1208 | /** |
@@ -1136,12 +1214,13 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old) | |||
1136 | */ | 1214 | */ |
1137 | static int smack_kernel_act_as(struct cred *new, u32 secid) | 1215 | static int smack_kernel_act_as(struct cred *new, u32 secid) |
1138 | { | 1216 | { |
1217 | struct task_smack *new_tsp = new->security; | ||
1139 | char *smack = smack_from_secid(secid); | 1218 | char *smack = smack_from_secid(secid); |
1140 | 1219 | ||
1141 | if (smack == NULL) | 1220 | if (smack == NULL) |
1142 | return -EINVAL; | 1221 | return -EINVAL; |
1143 | 1222 | ||
1144 | new->security = smack; | 1223 | new_tsp->smk_task = smack; |
1145 | return 0; | 1224 | return 0; |
1146 | } | 1225 | } |
1147 | 1226 | ||
@@ -1157,8 +1236,10 @@ static int smack_kernel_create_files_as(struct cred *new, | |||
1157 | struct inode *inode) | 1236 | struct inode *inode) |
1158 | { | 1237 | { |
1159 | struct inode_smack *isp = inode->i_security; | 1238 | struct inode_smack *isp = inode->i_security; |
1239 | struct task_smack *tsp = new->security; | ||
1160 | 1240 | ||
1161 | new->security = isp->smk_inode; | 1241 | tsp->smk_forked = isp->smk_inode; |
1242 | tsp->smk_task = isp->smk_inode; | ||
1162 | return 0; | 1243 | return 0; |
1163 | } | 1244 | } |
1164 | 1245 | ||
@@ -1175,7 +1256,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access) | |||
1175 | 1256 | ||
1176 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | 1257 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); |
1177 | smk_ad_setfield_u_tsk(&ad, p); | 1258 | smk_ad_setfield_u_tsk(&ad, p); |
1178 | return smk_curacc(task_security(p), access, &ad); | 1259 | return smk_curacc(smk_of_task(task_security(p)), access, &ad); |
1179 | } | 1260 | } |
1180 | 1261 | ||
1181 | /** | 1262 | /** |
@@ -1221,7 +1302,7 @@ static int smack_task_getsid(struct task_struct *p) | |||
1221 | */ | 1302 | */ |
1222 | static void smack_task_getsecid(struct task_struct *p, u32 *secid) | 1303 | static void smack_task_getsecid(struct task_struct *p, u32 *secid) |
1223 | { | 1304 | { |
1224 | *secid = smack_to_secid(task_security(p)); | 1305 | *secid = smack_to_secid(smk_of_task(task_security(p))); |
1225 | } | 1306 | } |
1226 | 1307 | ||
1227 | /** | 1308 | /** |
@@ -1333,14 +1414,15 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, | |||
1333 | * can write the receiver. | 1414 | * can write the receiver. |
1334 | */ | 1415 | */ |
1335 | if (secid == 0) | 1416 | if (secid == 0) |
1336 | return smk_curacc(task_security(p), MAY_WRITE, &ad); | 1417 | return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE, |
1418 | &ad); | ||
1337 | /* | 1419 | /* |
1338 | * If the secid isn't 0 we're dealing with some USB IO | 1420 | * If the secid isn't 0 we're dealing with some USB IO |
1339 | * specific behavior. This is not clean. For one thing | 1421 | * specific behavior. This is not clean. For one thing |
1340 | * we can't take privilege into account. | 1422 | * we can't take privilege into account. |
1341 | */ | 1423 | */ |
1342 | return smk_access(smack_from_secid(secid), task_security(p), | 1424 | return smk_access(smack_from_secid(secid), |
1343 | MAY_WRITE, &ad); | 1425 | smk_of_task(task_security(p)), MAY_WRITE, &ad); |
1344 | } | 1426 | } |
1345 | 1427 | ||
1346 | /** | 1428 | /** |
@@ -1352,12 +1434,12 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, | |||
1352 | static int smack_task_wait(struct task_struct *p) | 1434 | static int smack_task_wait(struct task_struct *p) |
1353 | { | 1435 | { |
1354 | struct smk_audit_info ad; | 1436 | struct smk_audit_info ad; |
1355 | char *sp = current_security(); | 1437 | char *sp = smk_of_current(); |
1356 | char *tsp = task_security(p); | 1438 | char *tsp = smk_of_forked(task_security(p)); |
1357 | int rc; | 1439 | int rc; |
1358 | 1440 | ||
1359 | /* we don't log here, we can be overriden */ | 1441 | /* we don't log here, we can be overriden */ |
1360 | rc = smk_access(sp, tsp, MAY_WRITE, NULL); | 1442 | rc = smk_access(tsp, sp, MAY_WRITE, NULL); |
1361 | if (rc == 0) | 1443 | if (rc == 0) |
1362 | goto out_log; | 1444 | goto out_log; |
1363 | 1445 | ||
@@ -1378,7 +1460,7 @@ static int smack_task_wait(struct task_struct *p) | |||
1378 | out_log: | 1460 | out_log: |
1379 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | 1461 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); |
1380 | smk_ad_setfield_u_tsk(&ad, p); | 1462 | smk_ad_setfield_u_tsk(&ad, p); |
1381 | smack_log(sp, tsp, MAY_WRITE, rc, &ad); | 1463 | smack_log(tsp, sp, MAY_WRITE, rc, &ad); |
1382 | return rc; | 1464 | return rc; |
1383 | } | 1465 | } |
1384 | 1466 | ||
@@ -1392,7 +1474,7 @@ static int smack_task_wait(struct task_struct *p) | |||
1392 | static void smack_task_to_inode(struct task_struct *p, struct inode *inode) | 1474 | static void smack_task_to_inode(struct task_struct *p, struct inode *inode) |
1393 | { | 1475 | { |
1394 | struct inode_smack *isp = inode->i_security; | 1476 | struct inode_smack *isp = inode->i_security; |
1395 | isp->smk_inode = task_security(p); | 1477 | isp->smk_inode = smk_of_task(task_security(p)); |
1396 | } | 1478 | } |
1397 | 1479 | ||
1398 | /* | 1480 | /* |
@@ -1411,7 +1493,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode) | |||
1411 | */ | 1493 | */ |
1412 | static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) | 1494 | static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) |
1413 | { | 1495 | { |
1414 | char *csp = current_security(); | 1496 | char *csp = smk_of_current(); |
1415 | struct socket_smack *ssp; | 1497 | struct socket_smack *ssp; |
1416 | 1498 | ||
1417 | ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); | 1499 | ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); |
@@ -1667,10 +1749,13 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, | |||
1667 | ssp->smk_in = sp; | 1749 | ssp->smk_in = sp; |
1668 | else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { | 1750 | else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { |
1669 | ssp->smk_out = sp; | 1751 | ssp->smk_out = sp; |
1670 | rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); | 1752 | if (sock->sk->sk_family != PF_UNIX) { |
1671 | if (rc != 0) | 1753 | rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); |
1672 | printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", | 1754 | if (rc != 0) |
1673 | __func__, -rc); | 1755 | printk(KERN_WARNING |
1756 | "Smack: \"%s\" netlbl error %d.\n", | ||
1757 | __func__, -rc); | ||
1758 | } | ||
1674 | } else | 1759 | } else |
1675 | return -EOPNOTSUPP; | 1760 | return -EOPNOTSUPP; |
1676 | 1761 | ||
@@ -1749,7 +1834,7 @@ static int smack_flags_to_may(int flags) | |||
1749 | */ | 1834 | */ |
1750 | static int smack_msg_msg_alloc_security(struct msg_msg *msg) | 1835 | static int smack_msg_msg_alloc_security(struct msg_msg *msg) |
1751 | { | 1836 | { |
1752 | msg->security = current_security(); | 1837 | msg->security = smk_of_current(); |
1753 | return 0; | 1838 | return 0; |
1754 | } | 1839 | } |
1755 | 1840 | ||
@@ -1785,7 +1870,7 @@ static int smack_shm_alloc_security(struct shmid_kernel *shp) | |||
1785 | { | 1870 | { |
1786 | struct kern_ipc_perm *isp = &shp->shm_perm; | 1871 | struct kern_ipc_perm *isp = &shp->shm_perm; |
1787 | 1872 | ||
1788 | isp->security = current_security(); | 1873 | isp->security = smk_of_current(); |
1789 | return 0; | 1874 | return 0; |
1790 | } | 1875 | } |
1791 | 1876 | ||
@@ -1908,7 +1993,7 @@ static int smack_sem_alloc_security(struct sem_array *sma) | |||
1908 | { | 1993 | { |
1909 | struct kern_ipc_perm *isp = &sma->sem_perm; | 1994 | struct kern_ipc_perm *isp = &sma->sem_perm; |
1910 | 1995 | ||
1911 | isp->security = current_security(); | 1996 | isp->security = smk_of_current(); |
1912 | return 0; | 1997 | return 0; |
1913 | } | 1998 | } |
1914 | 1999 | ||
@@ -2026,7 +2111,7 @@ static int smack_msg_queue_alloc_security(struct msg_queue *msq) | |||
2026 | { | 2111 | { |
2027 | struct kern_ipc_perm *kisp = &msq->q_perm; | 2112 | struct kern_ipc_perm *kisp = &msq->q_perm; |
2028 | 2113 | ||
2029 | kisp->security = current_security(); | 2114 | kisp->security = smk_of_current(); |
2030 | return 0; | 2115 | return 0; |
2031 | } | 2116 | } |
2032 | 2117 | ||
@@ -2198,9 +2283,11 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
2198 | struct super_block *sbp; | 2283 | struct super_block *sbp; |
2199 | struct superblock_smack *sbsp; | 2284 | struct superblock_smack *sbsp; |
2200 | struct inode_smack *isp; | 2285 | struct inode_smack *isp; |
2201 | char *csp = current_security(); | 2286 | char *csp = smk_of_current(); |
2202 | char *fetched; | 2287 | char *fetched; |
2203 | char *final; | 2288 | char *final; |
2289 | char trattr[TRANS_TRUE_SIZE]; | ||
2290 | int transflag = 0; | ||
2204 | struct dentry *dp; | 2291 | struct dentry *dp; |
2205 | 2292 | ||
2206 | if (inode == NULL) | 2293 | if (inode == NULL) |
@@ -2267,9 +2354,10 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
2267 | break; | 2354 | break; |
2268 | case SOCKFS_MAGIC: | 2355 | case SOCKFS_MAGIC: |
2269 | /* | 2356 | /* |
2270 | * Casey says sockets get the smack of the task. | 2357 | * Socket access is controlled by the socket |
2358 | * structures associated with the task involved. | ||
2271 | */ | 2359 | */ |
2272 | final = csp; | 2360 | final = smack_known_star.smk_known; |
2273 | break; | 2361 | break; |
2274 | case PROC_SUPER_MAGIC: | 2362 | case PROC_SUPER_MAGIC: |
2275 | /* | 2363 | /* |
@@ -2296,7 +2384,16 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
2296 | /* | 2384 | /* |
2297 | * This isn't an understood special case. | 2385 | * This isn't an understood special case. |
2298 | * Get the value from the xattr. | 2386 | * Get the value from the xattr. |
2299 | * | 2387 | */ |
2388 | |||
2389 | /* | ||
2390 | * UNIX domain sockets use lower level socket data. | ||
2391 | */ | ||
2392 | if (S_ISSOCK(inode->i_mode)) { | ||
2393 | final = smack_known_star.smk_known; | ||
2394 | break; | ||
2395 | } | ||
2396 | /* | ||
2300 | * No xattr support means, alas, no SMACK label. | 2397 | * No xattr support means, alas, no SMACK label. |
2301 | * Use the aforeapplied default. | 2398 | * Use the aforeapplied default. |
2302 | * It would be curious if the label of the task | 2399 | * It would be curious if the label of the task |
@@ -2308,9 +2405,21 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
2308 | * Get the dentry for xattr. | 2405 | * Get the dentry for xattr. |
2309 | */ | 2406 | */ |
2310 | dp = dget(opt_dentry); | 2407 | dp = dget(opt_dentry); |
2311 | fetched = smk_fetch(inode, dp); | 2408 | fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp); |
2312 | if (fetched != NULL) | 2409 | if (fetched != NULL) { |
2313 | final = fetched; | 2410 | final = fetched; |
2411 | if (S_ISDIR(inode->i_mode)) { | ||
2412 | trattr[0] = '\0'; | ||
2413 | inode->i_op->getxattr(dp, | ||
2414 | XATTR_NAME_SMACKTRANSMUTE, | ||
2415 | trattr, TRANS_TRUE_SIZE); | ||
2416 | if (strncmp(trattr, TRANS_TRUE, | ||
2417 | TRANS_TRUE_SIZE) == 0) | ||
2418 | transflag = SMK_INODE_TRANSMUTE; | ||
2419 | } | ||
2420 | } | ||
2421 | isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); | ||
2422 | |||
2314 | dput(dp); | 2423 | dput(dp); |
2315 | break; | 2424 | break; |
2316 | } | 2425 | } |
@@ -2320,7 +2429,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
2320 | else | 2429 | else |
2321 | isp->smk_inode = final; | 2430 | isp->smk_inode = final; |
2322 | 2431 | ||
2323 | isp->smk_flags |= SMK_INODE_INSTANT; | 2432 | isp->smk_flags |= (SMK_INODE_INSTANT | transflag); |
2324 | 2433 | ||
2325 | unlockandout: | 2434 | unlockandout: |
2326 | mutex_unlock(&isp->smk_lock); | 2435 | mutex_unlock(&isp->smk_lock); |
@@ -2345,7 +2454,7 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value) | |||
2345 | if (strcmp(name, "current") != 0) | 2454 | if (strcmp(name, "current") != 0) |
2346 | return -EINVAL; | 2455 | return -EINVAL; |
2347 | 2456 | ||
2348 | cp = kstrdup(task_security(p), GFP_KERNEL); | 2457 | cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL); |
2349 | if (cp == NULL) | 2458 | if (cp == NULL) |
2350 | return -ENOMEM; | 2459 | return -ENOMEM; |
2351 | 2460 | ||
@@ -2369,6 +2478,8 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value) | |||
2369 | static int smack_setprocattr(struct task_struct *p, char *name, | 2478 | static int smack_setprocattr(struct task_struct *p, char *name, |
2370 | void *value, size_t size) | 2479 | void *value, size_t size) |
2371 | { | 2480 | { |
2481 | struct task_smack *tsp; | ||
2482 | struct task_smack *oldtsp; | ||
2372 | struct cred *new; | 2483 | struct cred *new; |
2373 | char *newsmack; | 2484 | char *newsmack; |
2374 | 2485 | ||
@@ -2398,10 +2509,18 @@ static int smack_setprocattr(struct task_struct *p, char *name, | |||
2398 | if (newsmack == smack_known_web.smk_known) | 2509 | if (newsmack == smack_known_web.smk_known) |
2399 | return -EPERM; | 2510 | return -EPERM; |
2400 | 2511 | ||
2512 | oldtsp = p->cred->security; | ||
2401 | new = prepare_creds(); | 2513 | new = prepare_creds(); |
2402 | if (new == NULL) | 2514 | if (new == NULL) |
2403 | return -ENOMEM; | 2515 | return -ENOMEM; |
2404 | new->security = newsmack; | 2516 | tsp = kzalloc(sizeof(struct task_smack), GFP_KERNEL); |
2517 | if (tsp == NULL) { | ||
2518 | kfree(new); | ||
2519 | return -ENOMEM; | ||
2520 | } | ||
2521 | tsp->smk_task = newsmack; | ||
2522 | tsp->smk_forked = oldtsp->smk_forked; | ||
2523 | new->security = tsp; | ||
2405 | commit_creds(new); | 2524 | commit_creds(new); |
2406 | return size; | 2525 | return size; |
2407 | } | 2526 | } |
@@ -2418,14 +2537,18 @@ static int smack_setprocattr(struct task_struct *p, char *name, | |||
2418 | static int smack_unix_stream_connect(struct sock *sock, | 2537 | static int smack_unix_stream_connect(struct sock *sock, |
2419 | struct sock *other, struct sock *newsk) | 2538 | struct sock *other, struct sock *newsk) |
2420 | { | 2539 | { |
2421 | struct inode *sp = SOCK_INODE(sock->sk_socket); | 2540 | struct socket_smack *ssp = sock->sk_security; |
2422 | struct inode *op = SOCK_INODE(other->sk_socket); | 2541 | struct socket_smack *osp = other->sk_security; |
2423 | struct smk_audit_info ad; | 2542 | struct smk_audit_info ad; |
2543 | int rc = 0; | ||
2424 | 2544 | ||
2425 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); | 2545 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); |
2426 | smk_ad_setfield_u_net_sk(&ad, other); | 2546 | smk_ad_setfield_u_net_sk(&ad, other); |
2427 | return smk_access(smk_of_inode(sp), smk_of_inode(op), | 2547 | |
2428 | MAY_READWRITE, &ad); | 2548 | if (!capable(CAP_MAC_OVERRIDE)) |
2549 | rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); | ||
2550 | |||
2551 | return rc; | ||
2429 | } | 2552 | } |
2430 | 2553 | ||
2431 | /** | 2554 | /** |
@@ -2438,13 +2561,18 @@ static int smack_unix_stream_connect(struct sock *sock, | |||
2438 | */ | 2561 | */ |
2439 | static int smack_unix_may_send(struct socket *sock, struct socket *other) | 2562 | static int smack_unix_may_send(struct socket *sock, struct socket *other) |
2440 | { | 2563 | { |
2441 | struct inode *sp = SOCK_INODE(sock); | 2564 | struct socket_smack *ssp = sock->sk->sk_security; |
2442 | struct inode *op = SOCK_INODE(other); | 2565 | struct socket_smack *osp = other->sk->sk_security; |
2443 | struct smk_audit_info ad; | 2566 | struct smk_audit_info ad; |
2567 | int rc = 0; | ||
2444 | 2568 | ||
2445 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); | 2569 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); |
2446 | smk_ad_setfield_u_net_sk(&ad, other->sk); | 2570 | smk_ad_setfield_u_net_sk(&ad, other->sk); |
2447 | return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE, &ad); | 2571 | |
2572 | if (!capable(CAP_MAC_OVERRIDE)) | ||
2573 | rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); | ||
2574 | |||
2575 | return rc; | ||
2448 | } | 2576 | } |
2449 | 2577 | ||
2450 | /** | 2578 | /** |
@@ -2629,7 +2757,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock, | |||
2629 | 2757 | ||
2630 | /** | 2758 | /** |
2631 | * smack_socket_getpeersec_dgram - pull in packet label | 2759 | * smack_socket_getpeersec_dgram - pull in packet label |
2632 | * @sock: the socket | 2760 | * @sock: the peer socket |
2633 | * @skb: packet data | 2761 | * @skb: packet data |
2634 | * @secid: pointer to where to put the secid of the packet | 2762 | * @secid: pointer to where to put the secid of the packet |
2635 | * | 2763 | * |
@@ -2640,41 +2768,39 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, | |||
2640 | 2768 | ||
2641 | { | 2769 | { |
2642 | struct netlbl_lsm_secattr secattr; | 2770 | struct netlbl_lsm_secattr secattr; |
2643 | struct sock *sk; | 2771 | struct socket_smack *sp; |
2644 | char smack[SMK_LABELLEN]; | 2772 | char smack[SMK_LABELLEN]; |
2645 | int family = PF_INET; | 2773 | int family = PF_UNSPEC; |
2646 | u32 s; | 2774 | u32 s = 0; /* 0 is the invalid secid */ |
2647 | int rc; | 2775 | int rc; |
2648 | 2776 | ||
2649 | /* | 2777 | if (skb != NULL) { |
2650 | * Only works for families with packets. | 2778 | if (skb->protocol == htons(ETH_P_IP)) |
2651 | */ | 2779 | family = PF_INET; |
2652 | if (sock != NULL) { | 2780 | else if (skb->protocol == htons(ETH_P_IPV6)) |
2653 | sk = sock->sk; | 2781 | family = PF_INET6; |
2654 | if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) | ||
2655 | return 0; | ||
2656 | family = sk->sk_family; | ||
2657 | } | 2782 | } |
2658 | /* | 2783 | if (family == PF_UNSPEC && sock != NULL) |
2659 | * Translate what netlabel gave us. | 2784 | family = sock->sk->sk_family; |
2660 | */ | ||
2661 | netlbl_secattr_init(&secattr); | ||
2662 | rc = netlbl_skbuff_getattr(skb, family, &secattr); | ||
2663 | if (rc == 0) | ||
2664 | smack_from_secattr(&secattr, smack); | ||
2665 | netlbl_secattr_destroy(&secattr); | ||
2666 | 2785 | ||
2667 | /* | 2786 | if (family == PF_UNIX) { |
2668 | * Give up if we couldn't get anything | 2787 | sp = sock->sk->sk_security; |
2669 | */ | 2788 | s = smack_to_secid(sp->smk_out); |
2670 | if (rc != 0) | 2789 | } else if (family == PF_INET || family == PF_INET6) { |
2671 | return rc; | 2790 | /* |
2672 | 2791 | * Translate what netlabel gave us. | |
2673 | s = smack_to_secid(smack); | 2792 | */ |
2793 | netlbl_secattr_init(&secattr); | ||
2794 | rc = netlbl_skbuff_getattr(skb, family, &secattr); | ||
2795 | if (rc == 0) { | ||
2796 | smack_from_secattr(&secattr, smack); | ||
2797 | s = smack_to_secid(smack); | ||
2798 | } | ||
2799 | netlbl_secattr_destroy(&secattr); | ||
2800 | } | ||
2801 | *secid = s; | ||
2674 | if (s == 0) | 2802 | if (s == 0) |
2675 | return -EINVAL; | 2803 | return -EINVAL; |
2676 | |||
2677 | *secid = s; | ||
2678 | return 0; | 2804 | return 0; |
2679 | } | 2805 | } |
2680 | 2806 | ||
@@ -2695,7 +2821,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) | |||
2695 | return; | 2821 | return; |
2696 | 2822 | ||
2697 | ssp = sk->sk_security; | 2823 | ssp = sk->sk_security; |
2698 | ssp->smk_in = ssp->smk_out = current_security(); | 2824 | ssp->smk_in = ssp->smk_out = smk_of_current(); |
2699 | /* cssp->smk_packet is already set in smack_inet_csk_clone() */ | 2825 | /* cssp->smk_packet is already set in smack_inet_csk_clone() */ |
2700 | } | 2826 | } |
2701 | 2827 | ||
@@ -2816,7 +2942,7 @@ static void smack_inet_csk_clone(struct sock *sk, | |||
2816 | static int smack_key_alloc(struct key *key, const struct cred *cred, | 2942 | static int smack_key_alloc(struct key *key, const struct cred *cred, |
2817 | unsigned long flags) | 2943 | unsigned long flags) |
2818 | { | 2944 | { |
2819 | key->security = cred->security; | 2945 | key->security = smk_of_task(cred->security); |
2820 | return 0; | 2946 | return 0; |
2821 | } | 2947 | } |
2822 | 2948 | ||
@@ -2845,6 +2971,7 @@ static int smack_key_permission(key_ref_t key_ref, | |||
2845 | { | 2971 | { |
2846 | struct key *keyp; | 2972 | struct key *keyp; |
2847 | struct smk_audit_info ad; | 2973 | struct smk_audit_info ad; |
2974 | char *tsp = smk_of_task(cred->security); | ||
2848 | 2975 | ||
2849 | keyp = key_ref_to_ptr(key_ref); | 2976 | keyp = key_ref_to_ptr(key_ref); |
2850 | if (keyp == NULL) | 2977 | if (keyp == NULL) |
@@ -2858,14 +2985,14 @@ static int smack_key_permission(key_ref_t key_ref, | |||
2858 | /* | 2985 | /* |
2859 | * This should not occur | 2986 | * This should not occur |
2860 | */ | 2987 | */ |
2861 | if (cred->security == NULL) | 2988 | if (tsp == NULL) |
2862 | return -EACCES; | 2989 | return -EACCES; |
2863 | #ifdef CONFIG_AUDIT | 2990 | #ifdef CONFIG_AUDIT |
2864 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); | 2991 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); |
2865 | ad.a.u.key_struct.key = keyp->serial; | 2992 | ad.a.u.key_struct.key = keyp->serial; |
2866 | ad.a.u.key_struct.key_desc = keyp->description; | 2993 | ad.a.u.key_struct.key_desc = keyp->description; |
2867 | #endif | 2994 | #endif |
2868 | return smk_access(cred->security, keyp->security, | 2995 | return smk_access(tsp, keyp->security, |
2869 | MAY_READWRITE, &ad); | 2996 | MAY_READWRITE, &ad); |
2870 | } | 2997 | } |
2871 | #endif /* CONFIG_KEYS */ | 2998 | #endif /* CONFIG_KEYS */ |
@@ -3067,6 +3194,8 @@ struct security_operations smack_ops = { | |||
3067 | .sb_mount = smack_sb_mount, | 3194 | .sb_mount = smack_sb_mount, |
3068 | .sb_umount = smack_sb_umount, | 3195 | .sb_umount = smack_sb_umount, |
3069 | 3196 | ||
3197 | .bprm_set_creds = smack_bprm_set_creds, | ||
3198 | |||
3070 | .inode_alloc_security = smack_inode_alloc_security, | 3199 | .inode_alloc_security = smack_inode_alloc_security, |
3071 | .inode_free_security = smack_inode_free_security, | 3200 | .inode_free_security = smack_inode_free_security, |
3072 | .inode_init_security = smack_inode_init_security, | 3201 | .inode_init_security = smack_inode_init_security, |
@@ -3203,9 +3332,16 @@ static __init void init_smack_know_list(void) | |||
3203 | static __init int smack_init(void) | 3332 | static __init int smack_init(void) |
3204 | { | 3333 | { |
3205 | struct cred *cred; | 3334 | struct cred *cred; |
3335 | struct task_smack *tsp; | ||
3206 | 3336 | ||
3207 | if (!security_module_enable(&smack_ops)) | 3337 | tsp = kzalloc(sizeof(struct task_smack), GFP_KERNEL); |
3338 | if (tsp == NULL) | ||
3339 | return -ENOMEM; | ||
3340 | |||
3341 | if (!security_module_enable(&smack_ops)) { | ||
3342 | kfree(tsp); | ||
3208 | return 0; | 3343 | return 0; |
3344 | } | ||
3209 | 3345 | ||
3210 | printk(KERN_INFO "Smack: Initializing.\n"); | 3346 | printk(KERN_INFO "Smack: Initializing.\n"); |
3211 | 3347 | ||
@@ -3213,7 +3349,9 @@ static __init int smack_init(void) | |||
3213 | * Set the security state for the initial task. | 3349 | * Set the security state for the initial task. |
3214 | */ | 3350 | */ |
3215 | cred = (struct cred *) current->cred; | 3351 | cred = (struct cred *) current->cred; |
3216 | cred->security = &smack_known_floor.smk_known; | 3352 | tsp->smk_forked = smack_known_floor.smk_known; |
3353 | tsp->smk_task = smack_known_floor.smk_known; | ||
3354 | cred->security = tsp; | ||
3217 | 3355 | ||
3218 | /* initialize the smack_know_list */ | 3356 | /* initialize the smack_know_list */ |
3219 | init_smack_know_list(); | 3357 | init_smack_know_list(); |