diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/capability.c | 19 | ||||
-rw-r--r-- | security/keys/compat.c | 3 | ||||
-rw-r--r-- | security/keys/gc.c | 1 | ||||
-rw-r--r-- | security/keys/internal.h | 1 | ||||
-rw-r--r-- | security/keys/keyctl.c | 102 | ||||
-rw-r--r-- | security/keys/process_keys.c | 49 | ||||
-rw-r--r-- | security/security.c | 17 | ||||
-rw-r--r-- | security/selinux/hooks.c | 28 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 30 | ||||
-rw-r--r-- | security/tomoyo/tomoyo.c | 17 |
10 files changed, 267 insertions, 0 deletions
diff --git a/security/capability.c b/security/capability.c index 06400cf07757..93a2ffe65905 100644 --- a/security/capability.c +++ b/security/capability.c | |||
@@ -373,6 +373,11 @@ static int cap_task_create(unsigned long clone_flags) | |||
373 | return 0; | 373 | return 0; |
374 | } | 374 | } |
375 | 375 | ||
376 | static int cap_cred_alloc_blank(struct cred *cred, gfp_t gfp) | ||
377 | { | ||
378 | return 0; | ||
379 | } | ||
380 | |||
376 | static void cap_cred_free(struct cred *cred) | 381 | static void cap_cred_free(struct cred *cred) |
377 | { | 382 | { |
378 | } | 383 | } |
@@ -386,6 +391,10 @@ static void cap_cred_commit(struct cred *new, const struct cred *old) | |||
386 | { | 391 | { |
387 | } | 392 | } |
388 | 393 | ||
394 | static void cap_cred_transfer(struct cred *new, const struct cred *old) | ||
395 | { | ||
396 | } | ||
397 | |||
389 | static int cap_kernel_act_as(struct cred *new, u32 secid) | 398 | static int cap_kernel_act_as(struct cred *new, u32 secid) |
390 | { | 399 | { |
391 | return 0; | 400 | return 0; |
@@ -836,6 +845,13 @@ static int cap_key_getsecurity(struct key *key, char **_buffer) | |||
836 | return 0; | 845 | return 0; |
837 | } | 846 | } |
838 | 847 | ||
848 | static int cap_key_session_to_parent(const struct cred *cred, | ||
849 | const struct cred *parent_cred, | ||
850 | struct key *key) | ||
851 | { | ||
852 | return 0; | ||
853 | } | ||
854 | |||
839 | #endif /* CONFIG_KEYS */ | 855 | #endif /* CONFIG_KEYS */ |
840 | 856 | ||
841 | #ifdef CONFIG_AUDIT | 857 | #ifdef CONFIG_AUDIT |
@@ -961,9 +977,11 @@ void security_fixup_ops(struct security_operations *ops) | |||
961 | set_to_cap_if_null(ops, file_receive); | 977 | set_to_cap_if_null(ops, file_receive); |
962 | set_to_cap_if_null(ops, dentry_open); | 978 | set_to_cap_if_null(ops, dentry_open); |
963 | set_to_cap_if_null(ops, task_create); | 979 | set_to_cap_if_null(ops, task_create); |
980 | set_to_cap_if_null(ops, cred_alloc_blank); | ||
964 | set_to_cap_if_null(ops, cred_free); | 981 | set_to_cap_if_null(ops, cred_free); |
965 | set_to_cap_if_null(ops, cred_prepare); | 982 | set_to_cap_if_null(ops, cred_prepare); |
966 | set_to_cap_if_null(ops, cred_commit); | 983 | set_to_cap_if_null(ops, cred_commit); |
984 | set_to_cap_if_null(ops, cred_transfer); | ||
967 | set_to_cap_if_null(ops, kernel_act_as); | 985 | set_to_cap_if_null(ops, kernel_act_as); |
968 | set_to_cap_if_null(ops, kernel_create_files_as); | 986 | set_to_cap_if_null(ops, kernel_create_files_as); |
969 | set_to_cap_if_null(ops, kernel_module_request); | 987 | set_to_cap_if_null(ops, kernel_module_request); |
@@ -1063,6 +1081,7 @@ void security_fixup_ops(struct security_operations *ops) | |||
1063 | set_to_cap_if_null(ops, key_free); | 1081 | set_to_cap_if_null(ops, key_free); |
1064 | set_to_cap_if_null(ops, key_permission); | 1082 | set_to_cap_if_null(ops, key_permission); |
1065 | set_to_cap_if_null(ops, key_getsecurity); | 1083 | set_to_cap_if_null(ops, key_getsecurity); |
1084 | set_to_cap_if_null(ops, key_session_to_parent); | ||
1066 | #endif /* CONFIG_KEYS */ | 1085 | #endif /* CONFIG_KEYS */ |
1067 | #ifdef CONFIG_AUDIT | 1086 | #ifdef CONFIG_AUDIT |
1068 | set_to_cap_if_null(ops, audit_rule_init); | 1087 | set_to_cap_if_null(ops, audit_rule_init); |
diff --git a/security/keys/compat.c b/security/keys/compat.c index c766c68a63bc..792c0a611a6d 100644 --- a/security/keys/compat.c +++ b/security/keys/compat.c | |||
@@ -82,6 +82,9 @@ asmlinkage long compat_sys_keyctl(u32 option, | |||
82 | case KEYCTL_GET_SECURITY: | 82 | case KEYCTL_GET_SECURITY: |
83 | return keyctl_get_security(arg2, compat_ptr(arg3), arg4); | 83 | return keyctl_get_security(arg2, compat_ptr(arg3), arg4); |
84 | 84 | ||
85 | case KEYCTL_SESSION_TO_PARENT: | ||
86 | return keyctl_session_to_parent(); | ||
87 | |||
85 | default: | 88 | default: |
86 | return -EOPNOTSUPP; | 89 | return -EOPNOTSUPP; |
87 | } | 90 | } |
diff --git a/security/keys/gc.c b/security/keys/gc.c index 44adc325e15c..1e616aef55fd 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c | |||
@@ -65,6 +65,7 @@ static void key_gc_timer_func(unsigned long data) | |||
65 | * - return true if we altered the keyring | 65 | * - return true if we altered the keyring |
66 | */ | 66 | */ |
67 | static bool key_gc_keyring(struct key *keyring, time_t limit) | 67 | static bool key_gc_keyring(struct key *keyring, time_t limit) |
68 | __releases(key_serial_lock) | ||
68 | { | 69 | { |
69 | struct keyring_list *klist; | 70 | struct keyring_list *klist; |
70 | struct key *key; | 71 | struct key *key; |
diff --git a/security/keys/internal.h b/security/keys/internal.h index fb830514c337..24ba0307b7ad 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
@@ -201,6 +201,7 @@ extern long keyctl_set_timeout(key_serial_t, unsigned); | |||
201 | extern long keyctl_assume_authority(key_serial_t); | 201 | extern long keyctl_assume_authority(key_serial_t); |
202 | extern long keyctl_get_security(key_serial_t keyid, char __user *buffer, | 202 | extern long keyctl_get_security(key_serial_t keyid, char __user *buffer, |
203 | size_t buflen); | 203 | size_t buflen); |
204 | extern long keyctl_session_to_parent(void); | ||
204 | 205 | ||
205 | /* | 206 | /* |
206 | * debugging key validation | 207 | * debugging key validation |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 736d7800f97f..74c968524592 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -1228,6 +1228,105 @@ long keyctl_get_security(key_serial_t keyid, | |||
1228 | return ret; | 1228 | return ret; |
1229 | } | 1229 | } |
1230 | 1230 | ||
1231 | /* | ||
1232 | * attempt to install the calling process's session keyring on the process's | ||
1233 | * parent process | ||
1234 | * - the keyring must exist and must grant us LINK permission | ||
1235 | * - implements keyctl(KEYCTL_SESSION_TO_PARENT) | ||
1236 | */ | ||
1237 | long keyctl_session_to_parent(void) | ||
1238 | { | ||
1239 | struct task_struct *me, *parent; | ||
1240 | const struct cred *mycred, *pcred; | ||
1241 | struct cred *cred, *oldcred; | ||
1242 | key_ref_t keyring_r; | ||
1243 | int ret; | ||
1244 | |||
1245 | keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_LINK); | ||
1246 | if (IS_ERR(keyring_r)) | ||
1247 | return PTR_ERR(keyring_r); | ||
1248 | |||
1249 | /* our parent is going to need a new cred struct, a new tgcred struct | ||
1250 | * and new security data, so we allocate them here to prevent ENOMEM in | ||
1251 | * our parent */ | ||
1252 | ret = -ENOMEM; | ||
1253 | cred = cred_alloc_blank(); | ||
1254 | if (!cred) | ||
1255 | goto error_keyring; | ||
1256 | |||
1257 | cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r); | ||
1258 | keyring_r = NULL; | ||
1259 | |||
1260 | me = current; | ||
1261 | write_lock_irq(&tasklist_lock); | ||
1262 | |||
1263 | parent = me->real_parent; | ||
1264 | ret = -EPERM; | ||
1265 | |||
1266 | /* the parent mustn't be init and mustn't be a kernel thread */ | ||
1267 | if (parent->pid <= 1 || !parent->mm) | ||
1268 | goto not_permitted; | ||
1269 | |||
1270 | /* the parent must be single threaded */ | ||
1271 | if (atomic_read(&parent->signal->count) != 1) | ||
1272 | goto not_permitted; | ||
1273 | |||
1274 | /* the parent and the child must have different session keyrings or | ||
1275 | * there's no point */ | ||
1276 | mycred = current_cred(); | ||
1277 | pcred = __task_cred(parent); | ||
1278 | if (mycred == pcred || | ||
1279 | mycred->tgcred->session_keyring == pcred->tgcred->session_keyring) | ||
1280 | goto already_same; | ||
1281 | |||
1282 | /* the parent must have the same effective ownership and mustn't be | ||
1283 | * SUID/SGID */ | ||
1284 | if (pcred-> uid != mycred->euid || | ||
1285 | pcred->euid != mycred->euid || | ||
1286 | pcred->suid != mycred->euid || | ||
1287 | pcred-> gid != mycred->egid || | ||
1288 | pcred->egid != mycred->egid || | ||
1289 | pcred->sgid != mycred->egid) | ||
1290 | goto not_permitted; | ||
1291 | |||
1292 | /* the keyrings must have the same UID */ | ||
1293 | if (pcred ->tgcred->session_keyring->uid != mycred->euid || | ||
1294 | mycred->tgcred->session_keyring->uid != mycred->euid) | ||
1295 | goto not_permitted; | ||
1296 | |||
1297 | /* the LSM must permit the replacement of the parent's keyring with the | ||
1298 | * keyring from this process */ | ||
1299 | ret = security_key_session_to_parent(mycred, pcred, | ||
1300 | key_ref_to_ptr(keyring_r)); | ||
1301 | if (ret < 0) | ||
1302 | goto not_permitted; | ||
1303 | |||
1304 | /* if there's an already pending keyring replacement, then we replace | ||
1305 | * that */ | ||
1306 | oldcred = parent->replacement_session_keyring; | ||
1307 | |||
1308 | /* the replacement session keyring is applied just prior to userspace | ||
1309 | * restarting */ | ||
1310 | parent->replacement_session_keyring = cred; | ||
1311 | cred = NULL; | ||
1312 | set_ti_thread_flag(task_thread_info(parent), TIF_NOTIFY_RESUME); | ||
1313 | |||
1314 | write_unlock_irq(&tasklist_lock); | ||
1315 | if (oldcred) | ||
1316 | put_cred(oldcred); | ||
1317 | return 0; | ||
1318 | |||
1319 | already_same: | ||
1320 | ret = 0; | ||
1321 | not_permitted: | ||
1322 | put_cred(cred); | ||
1323 | return ret; | ||
1324 | |||
1325 | error_keyring: | ||
1326 | key_ref_put(keyring_r); | ||
1327 | return ret; | ||
1328 | } | ||
1329 | |||
1231 | /*****************************************************************************/ | 1330 | /*****************************************************************************/ |
1232 | /* | 1331 | /* |
1233 | * the key control system call | 1332 | * the key control system call |
@@ -1313,6 +1412,9 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3, | |||
1313 | (char __user *) arg3, | 1412 | (char __user *) arg3, |
1314 | (size_t) arg4); | 1413 | (size_t) arg4); |
1315 | 1414 | ||
1415 | case KEYCTL_SESSION_TO_PARENT: | ||
1416 | return keyctl_session_to_parent(); | ||
1417 | |||
1316 | default: | 1418 | default: |
1317 | return -EOPNOTSUPP; | 1419 | return -EOPNOTSUPP; |
1318 | } | 1420 | } |
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 4739cfbb41b7..5c23afb31ece 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
20 | #include <linux/security.h> | ||
20 | #include <linux/user_namespace.h> | 21 | #include <linux/user_namespace.h> |
21 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
22 | #include "internal.h" | 23 | #include "internal.h" |
@@ -768,3 +769,51 @@ error: | |||
768 | abort_creds(new); | 769 | abort_creds(new); |
769 | return ret; | 770 | return ret; |
770 | } | 771 | } |
772 | |||
773 | /* | ||
774 | * Replace a process's session keyring when that process resumes userspace on | ||
775 | * behalf of one of its children | ||
776 | */ | ||
777 | void key_replace_session_keyring(void) | ||
778 | { | ||
779 | const struct cred *old; | ||
780 | struct cred *new; | ||
781 | |||
782 | if (!current->replacement_session_keyring) | ||
783 | return; | ||
784 | |||
785 | write_lock_irq(&tasklist_lock); | ||
786 | new = current->replacement_session_keyring; | ||
787 | current->replacement_session_keyring = NULL; | ||
788 | write_unlock_irq(&tasklist_lock); | ||
789 | |||
790 | if (!new) | ||
791 | return; | ||
792 | |||
793 | old = current_cred(); | ||
794 | new-> uid = old-> uid; | ||
795 | new-> euid = old-> euid; | ||
796 | new-> suid = old-> suid; | ||
797 | new->fsuid = old->fsuid; | ||
798 | new-> gid = old-> gid; | ||
799 | new-> egid = old-> egid; | ||
800 | new-> sgid = old-> sgid; | ||
801 | new->fsgid = old->fsgid; | ||
802 | new->user = get_uid(old->user); | ||
803 | new->group_info = get_group_info(old->group_info); | ||
804 | |||
805 | new->securebits = old->securebits; | ||
806 | new->cap_inheritable = old->cap_inheritable; | ||
807 | new->cap_permitted = old->cap_permitted; | ||
808 | new->cap_effective = old->cap_effective; | ||
809 | new->cap_bset = old->cap_bset; | ||
810 | |||
811 | new->jit_keyring = old->jit_keyring; | ||
812 | new->thread_keyring = key_get(old->thread_keyring); | ||
813 | new->tgcred->tgid = old->tgcred->tgid; | ||
814 | new->tgcred->process_keyring = key_get(old->tgcred->process_keyring); | ||
815 | |||
816 | security_transfer_creds(new, old); | ||
817 | |||
818 | commit_creds(new); | ||
819 | } | ||
diff --git a/security/security.c b/security/security.c index f88eaf6b14cc..d8b727637f02 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -684,6 +684,11 @@ int security_task_create(unsigned long clone_flags) | |||
684 | return security_ops->task_create(clone_flags); | 684 | return security_ops->task_create(clone_flags); |
685 | } | 685 | } |
686 | 686 | ||
687 | int security_cred_alloc_blank(struct cred *cred, gfp_t gfp) | ||
688 | { | ||
689 | return security_ops->cred_alloc_blank(cred, gfp); | ||
690 | } | ||
691 | |||
687 | void security_cred_free(struct cred *cred) | 692 | void security_cred_free(struct cred *cred) |
688 | { | 693 | { |
689 | security_ops->cred_free(cred); | 694 | security_ops->cred_free(cred); |
@@ -699,6 +704,11 @@ void security_commit_creds(struct cred *new, const struct cred *old) | |||
699 | security_ops->cred_commit(new, old); | 704 | security_ops->cred_commit(new, old); |
700 | } | 705 | } |
701 | 706 | ||
707 | void security_transfer_creds(struct cred *new, const struct cred *old) | ||
708 | { | ||
709 | security_ops->cred_transfer(new, old); | ||
710 | } | ||
711 | |||
702 | int security_kernel_act_as(struct cred *new, u32 secid) | 712 | int security_kernel_act_as(struct cred *new, u32 secid) |
703 | { | 713 | { |
704 | return security_ops->kernel_act_as(new, secid); | 714 | return security_ops->kernel_act_as(new, secid); |
@@ -1241,6 +1251,13 @@ int security_key_getsecurity(struct key *key, char **_buffer) | |||
1241 | return security_ops->key_getsecurity(key, _buffer); | 1251 | return security_ops->key_getsecurity(key, _buffer); |
1242 | } | 1252 | } |
1243 | 1253 | ||
1254 | int security_key_session_to_parent(const struct cred *cred, | ||
1255 | const struct cred *parent_cred, | ||
1256 | struct key *key) | ||
1257 | { | ||
1258 | return security_ops->key_session_to_parent(cred, parent_cred, key); | ||
1259 | } | ||
1260 | |||
1244 | #endif /* CONFIG_KEYS */ | 1261 | #endif /* CONFIG_KEYS */ |
1245 | 1262 | ||
1246 | #ifdef CONFIG_AUDIT | 1263 | #ifdef CONFIG_AUDIT |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index c3bb31ecc5aa..134a9c0d2004 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -3233,6 +3233,21 @@ static int selinux_task_create(unsigned long clone_flags) | |||
3233 | } | 3233 | } |
3234 | 3234 | ||
3235 | /* | 3235 | /* |
3236 | * allocate the SELinux part of blank credentials | ||
3237 | */ | ||
3238 | static int selinux_cred_alloc_blank(struct cred *cred, gfp_t gfp) | ||
3239 | { | ||
3240 | struct task_security_struct *tsec; | ||
3241 | |||
3242 | tsec = kzalloc(sizeof(struct task_security_struct), gfp); | ||
3243 | if (!tsec) | ||
3244 | return -ENOMEM; | ||
3245 | |||
3246 | cred->security = tsec; | ||
3247 | return 0; | ||
3248 | } | ||
3249 | |||
3250 | /* | ||
3236 | * detach and free the LSM part of a set of credentials | 3251 | * detach and free the LSM part of a set of credentials |
3237 | */ | 3252 | */ |
3238 | static void selinux_cred_free(struct cred *cred) | 3253 | static void selinux_cred_free(struct cred *cred) |
@@ -3264,6 +3279,17 @@ static int selinux_cred_prepare(struct cred *new, const struct cred *old, | |||
3264 | } | 3279 | } |
3265 | 3280 | ||
3266 | /* | 3281 | /* |
3282 | * transfer the SELinux data to a blank set of creds | ||
3283 | */ | ||
3284 | static void selinux_cred_transfer(struct cred *new, const struct cred *old) | ||
3285 | { | ||
3286 | const struct task_security_struct *old_tsec = old->security; | ||
3287 | struct task_security_struct *tsec = new->security; | ||
3288 | |||
3289 | *tsec = *old_tsec; | ||
3290 | } | ||
3291 | |||
3292 | /* | ||
3267 | * set the security data for a kernel service | 3293 | * set the security data for a kernel service |
3268 | * - all the creation contexts are set to unlabelled | 3294 | * - all the creation contexts are set to unlabelled |
3269 | */ | 3295 | */ |
@@ -5469,8 +5495,10 @@ static struct security_operations selinux_ops = { | |||
5469 | .dentry_open = selinux_dentry_open, | 5495 | .dentry_open = selinux_dentry_open, |
5470 | 5496 | ||
5471 | .task_create = selinux_task_create, | 5497 | .task_create = selinux_task_create, |
5498 | .cred_alloc_blank = selinux_cred_alloc_blank, | ||
5472 | .cred_free = selinux_cred_free, | 5499 | .cred_free = selinux_cred_free, |
5473 | .cred_prepare = selinux_cred_prepare, | 5500 | .cred_prepare = selinux_cred_prepare, |
5501 | .cred_transfer = selinux_cred_transfer, | ||
5474 | .kernel_act_as = selinux_kernel_act_as, | 5502 | .kernel_act_as = selinux_kernel_act_as, |
5475 | .kernel_create_files_as = selinux_kernel_create_files_as, | 5503 | .kernel_create_files_as = selinux_kernel_create_files_as, |
5476 | .kernel_module_request = selinux_kernel_module_request, | 5504 | .kernel_module_request = selinux_kernel_module_request, |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index c243a2b25832..969f5fee1906 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -1080,6 +1080,22 @@ static int smack_file_receive(struct file *file) | |||
1080 | */ | 1080 | */ |
1081 | 1081 | ||
1082 | /** | 1082 | /** |
1083 | * smack_cred_alloc_blank - "allocate" blank task-level security credentials | ||
1084 | * @new: the new credentials | ||
1085 | * @gfp: the atomicity of any memory allocations | ||
1086 | * | ||
1087 | * Prepare a blank set of credentials for modification. This must allocate all | ||
1088 | * the memory the LSM module might require such that cred_transfer() can | ||
1089 | * complete without error. | ||
1090 | */ | ||
1091 | static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) | ||
1092 | { | ||
1093 | cred->security = NULL; | ||
1094 | return 0; | ||
1095 | } | ||
1096 | |||
1097 | |||
1098 | /** | ||
1083 | * smack_cred_free - "free" task-level security credentials | 1099 | * smack_cred_free - "free" task-level security credentials |
1084 | * @cred: the credentials in question | 1100 | * @cred: the credentials in question |
1085 | * | 1101 | * |
@@ -1117,6 +1133,18 @@ static void smack_cred_commit(struct cred *new, const struct cred *old) | |||
1117 | } | 1133 | } |
1118 | 1134 | ||
1119 | /** | 1135 | /** |
1136 | * smack_cred_transfer - Transfer the old credentials to the new credentials | ||
1137 | * @new: the new credentials | ||
1138 | * @old: the original credentials | ||
1139 | * | ||
1140 | * Fill in a set of blank credentials from another set of credentials. | ||
1141 | */ | ||
1142 | static void smack_cred_transfer(struct cred *new, const struct cred *old) | ||
1143 | { | ||
1144 | new->security = old->security; | ||
1145 | } | ||
1146 | |||
1147 | /** | ||
1120 | * smack_kernel_act_as - Set the subjective context in a set of credentials | 1148 | * smack_kernel_act_as - Set the subjective context in a set of credentials |
1121 | * @new: points to the set of credentials to be modified. | 1149 | * @new: points to the set of credentials to be modified. |
1122 | * @secid: specifies the security ID to be set | 1150 | * @secid: specifies the security ID to be set |
@@ -3073,9 +3101,11 @@ struct security_operations smack_ops = { | |||
3073 | .file_send_sigiotask = smack_file_send_sigiotask, | 3101 | .file_send_sigiotask = smack_file_send_sigiotask, |
3074 | .file_receive = smack_file_receive, | 3102 | .file_receive = smack_file_receive, |
3075 | 3103 | ||
3104 | .cred_alloc_blank = smack_cred_alloc_blank, | ||
3076 | .cred_free = smack_cred_free, | 3105 | .cred_free = smack_cred_free, |
3077 | .cred_prepare = smack_cred_prepare, | 3106 | .cred_prepare = smack_cred_prepare, |
3078 | .cred_commit = smack_cred_commit, | 3107 | .cred_commit = smack_cred_commit, |
3108 | .cred_transfer = smack_cred_transfer, | ||
3079 | .kernel_act_as = smack_kernel_act_as, | 3109 | .kernel_act_as = smack_kernel_act_as, |
3080 | .kernel_create_files_as = smack_kernel_create_files_as, | 3110 | .kernel_create_files_as = smack_kernel_create_files_as, |
3081 | .task_setpgid = smack_task_setpgid, | 3111 | .task_setpgid = smack_task_setpgid, |
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index 35a13e7915e4..9548a0984cc4 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c | |||
@@ -14,6 +14,12 @@ | |||
14 | #include "tomoyo.h" | 14 | #include "tomoyo.h" |
15 | #include "realpath.h" | 15 | #include "realpath.h" |
16 | 16 | ||
17 | static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp) | ||
18 | { | ||
19 | new->security = NULL; | ||
20 | return 0; | ||
21 | } | ||
22 | |||
17 | static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, | 23 | static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, |
18 | gfp_t gfp) | 24 | gfp_t gfp) |
19 | { | 25 | { |
@@ -25,6 +31,15 @@ static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, | |||
25 | return 0; | 31 | return 0; |
26 | } | 32 | } |
27 | 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 | |||
28 | static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) | 43 | static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) |
29 | { | 44 | { |
30 | int rc; | 45 | int rc; |
@@ -262,7 +277,9 @@ static int tomoyo_dentry_open(struct file *f, const struct cred *cred) | |||
262 | */ | 277 | */ |
263 | static struct security_operations tomoyo_security_ops = { | 278 | static struct security_operations tomoyo_security_ops = { |
264 | .name = "tomoyo", | 279 | .name = "tomoyo", |
280 | .cred_alloc_blank = tomoyo_cred_alloc_blank, | ||
265 | .cred_prepare = tomoyo_cred_prepare, | 281 | .cred_prepare = tomoyo_cred_prepare, |
282 | .cred_transfer = tomoyo_cred_transfer, | ||
266 | .bprm_set_creds = tomoyo_bprm_set_creds, | 283 | .bprm_set_creds = tomoyo_bprm_set_creds, |
267 | .bprm_check_security = tomoyo_bprm_check_security, | 284 | .bprm_check_security = tomoyo_bprm_check_security, |
268 | #ifdef CONFIG_SYSCTL | 285 | #ifdef CONFIG_SYSCTL |