diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/Kconfig | 2 | ||||
-rw-r--r-- | security/capability.c | 5 | ||||
-rw-r--r-- | security/device_cgroup.c | 7 | ||||
-rw-r--r-- | security/keys/internal.h | 11 | ||||
-rw-r--r-- | security/keys/key.c | 6 | ||||
-rw-r--r-- | security/keys/keyctl.c | 44 | ||||
-rw-r--r-- | security/keys/keyring.c | 14 | ||||
-rw-r--r-- | security/keys/permission.c | 4 | ||||
-rw-r--r-- | security/keys/persistent.c | 4 | ||||
-rw-r--r-- | security/keys/proc.c | 2 | ||||
-rw-r--r-- | security/keys/sysctl.c | 2 | ||||
-rw-r--r-- | security/security.c | 8 | ||||
-rw-r--r-- | security/selinux/hooks.c | 35 | ||||
-rw-r--r-- | security/selinux/include/objsec.h | 5 | ||||
-rw-r--r-- | security/selinux/include/security.h | 2 | ||||
-rw-r--r-- | security/selinux/include/xfrm.h | 3 | ||||
-rw-r--r-- | security/selinux/nlmsgtab.c | 2 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 28 | ||||
-rw-r--r-- | security/selinux/ss/policydb.c | 8 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 22 | ||||
-rw-r--r-- | security/selinux/xfrm.c | 14 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 14 |
22 files changed, 139 insertions, 103 deletions
diff --git a/security/Kconfig b/security/Kconfig index e9c6ac724fef..beb86b500adf 100644 --- a/security/Kconfig +++ b/security/Kconfig | |||
@@ -103,7 +103,7 @@ config INTEL_TXT | |||
103 | config LSM_MMAP_MIN_ADDR | 103 | config LSM_MMAP_MIN_ADDR |
104 | int "Low address space for LSM to protect from user allocation" | 104 | int "Low address space for LSM to protect from user allocation" |
105 | depends on SECURITY && SECURITY_SELINUX | 105 | depends on SECURITY && SECURITY_SELINUX |
106 | default 32768 if ARM | 106 | default 32768 if ARM || (ARM64 && COMPAT) |
107 | default 65536 | 107 | default 65536 |
108 | help | 108 | help |
109 | This is the portion of low virtual memory which should be protected | 109 | This is the portion of low virtual memory which should be protected |
diff --git a/security/capability.c b/security/capability.c index 9323bbeba296..e76373de3129 100644 --- a/security/capability.c +++ b/security/capability.c | |||
@@ -757,7 +757,8 @@ static void cap_skb_owned_by(struct sk_buff *skb, struct sock *sk) | |||
757 | 757 | ||
758 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 758 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
759 | static int cap_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp, | 759 | static int cap_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp, |
760 | struct xfrm_user_sec_ctx *sec_ctx) | 760 | struct xfrm_user_sec_ctx *sec_ctx, |
761 | gfp_t gfp) | ||
761 | { | 762 | { |
762 | return 0; | 763 | return 0; |
763 | } | 764 | } |
@@ -878,7 +879,7 @@ static void cap_key_free(struct key *key) | |||
878 | } | 879 | } |
879 | 880 | ||
880 | static int cap_key_permission(key_ref_t key_ref, const struct cred *cred, | 881 | static int cap_key_permission(key_ref_t key_ref, const struct cred *cred, |
881 | key_perm_t perm) | 882 | unsigned perm) |
882 | { | 883 | { |
883 | return 0; | 884 | return 0; |
884 | } | 885 | } |
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 7c2a0a71049e..d3b6d2cd3a06 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c | |||
@@ -274,10 +274,9 @@ static void set_majmin(char *str, unsigned m) | |||
274 | sprintf(str, "%u", m); | 274 | sprintf(str, "%u", m); |
275 | } | 275 | } |
276 | 276 | ||
277 | static int devcgroup_seq_read(struct cgroup_subsys_state *css, | 277 | static int devcgroup_seq_show(struct seq_file *m, void *v) |
278 | struct cftype *cft, struct seq_file *m) | ||
279 | { | 278 | { |
280 | struct dev_cgroup *devcgroup = css_to_devcgroup(css); | 279 | struct dev_cgroup *devcgroup = css_to_devcgroup(seq_css(m)); |
281 | struct dev_exception_item *ex; | 280 | struct dev_exception_item *ex; |
282 | char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN]; | 281 | char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN]; |
283 | 282 | ||
@@ -679,7 +678,7 @@ static struct cftype dev_cgroup_files[] = { | |||
679 | }, | 678 | }, |
680 | { | 679 | { |
681 | .name = "list", | 680 | .name = "list", |
682 | .read_seq_string = devcgroup_seq_read, | 681 | .seq_show = devcgroup_seq_show, |
683 | .private = DEVCG_LIST, | 682 | .private = DEVCG_LIST, |
684 | }, | 683 | }, |
685 | { } /* terminate */ | 684 | { } /* terminate */ |
diff --git a/security/keys/internal.h b/security/keys/internal.h index 80b2aac4f50c..5f20da01fd8d 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
@@ -176,20 +176,11 @@ extern int key_task_permission(const key_ref_t key_ref, | |||
176 | /* | 176 | /* |
177 | * Check to see whether permission is granted to use a key in the desired way. | 177 | * Check to see whether permission is granted to use a key in the desired way. |
178 | */ | 178 | */ |
179 | static inline int key_permission(const key_ref_t key_ref, key_perm_t perm) | 179 | static inline int key_permission(const key_ref_t key_ref, unsigned perm) |
180 | { | 180 | { |
181 | return key_task_permission(key_ref, current_cred(), perm); | 181 | return key_task_permission(key_ref, current_cred(), perm); |
182 | } | 182 | } |
183 | 183 | ||
184 | /* required permissions */ | ||
185 | #define KEY_VIEW 0x01 /* require permission to view attributes */ | ||
186 | #define KEY_READ 0x02 /* require permission to read content */ | ||
187 | #define KEY_WRITE 0x04 /* require permission to update / modify */ | ||
188 | #define KEY_SEARCH 0x08 /* require permission to search (keyring) or find (key) */ | ||
189 | #define KEY_LINK 0x10 /* require permission to link */ | ||
190 | #define KEY_SETATTR 0x20 /* require permission to change attributes */ | ||
191 | #define KEY_ALL 0x3f /* all the above permissions */ | ||
192 | |||
193 | /* | 184 | /* |
194 | * Authorisation record for request_key(). | 185 | * Authorisation record for request_key(). |
195 | */ | 186 | */ |
diff --git a/security/keys/key.c b/security/keys/key.c index 6e21c11e48bc..2048a110e7f1 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -714,7 +714,7 @@ static inline key_ref_t __key_update(key_ref_t key_ref, | |||
714 | int ret; | 714 | int ret; |
715 | 715 | ||
716 | /* need write permission on the key to update it */ | 716 | /* need write permission on the key to update it */ |
717 | ret = key_permission(key_ref, KEY_WRITE); | 717 | ret = key_permission(key_ref, KEY_NEED_WRITE); |
718 | if (ret < 0) | 718 | if (ret < 0) |
719 | goto error; | 719 | goto error; |
720 | 720 | ||
@@ -838,7 +838,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
838 | 838 | ||
839 | /* if we're going to allocate a new key, we're going to have | 839 | /* if we're going to allocate a new key, we're going to have |
840 | * to modify the keyring */ | 840 | * to modify the keyring */ |
841 | ret = key_permission(keyring_ref, KEY_WRITE); | 841 | ret = key_permission(keyring_ref, KEY_NEED_WRITE); |
842 | if (ret < 0) { | 842 | if (ret < 0) { |
843 | key_ref = ERR_PTR(ret); | 843 | key_ref = ERR_PTR(ret); |
844 | goto error_link_end; | 844 | goto error_link_end; |
@@ -928,7 +928,7 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) | |||
928 | key_check(key); | 928 | key_check(key); |
929 | 929 | ||
930 | /* the key must be writable */ | 930 | /* the key must be writable */ |
931 | ret = key_permission(key_ref, KEY_WRITE); | 931 | ret = key_permission(key_ref, KEY_NEED_WRITE); |
932 | if (ret < 0) | 932 | if (ret < 0) |
933 | goto error; | 933 | goto error; |
934 | 934 | ||
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index cee72ce64222..cd5bd0cef25d 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -111,7 +111,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type, | |||
111 | } | 111 | } |
112 | 112 | ||
113 | /* find the target keyring (which must be writable) */ | 113 | /* find the target keyring (which must be writable) */ |
114 | keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); | 114 | keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE); |
115 | if (IS_ERR(keyring_ref)) { | 115 | if (IS_ERR(keyring_ref)) { |
116 | ret = PTR_ERR(keyring_ref); | 116 | ret = PTR_ERR(keyring_ref); |
117 | goto error3; | 117 | goto error3; |
@@ -195,7 +195,7 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type, | |||
195 | dest_ref = NULL; | 195 | dest_ref = NULL; |
196 | if (destringid) { | 196 | if (destringid) { |
197 | dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE, | 197 | dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE, |
198 | KEY_WRITE); | 198 | KEY_NEED_WRITE); |
199 | if (IS_ERR(dest_ref)) { | 199 | if (IS_ERR(dest_ref)) { |
200 | ret = PTR_ERR(dest_ref); | 200 | ret = PTR_ERR(dest_ref); |
201 | goto error3; | 201 | goto error3; |
@@ -253,7 +253,7 @@ long keyctl_get_keyring_ID(key_serial_t id, int create) | |||
253 | long ret; | 253 | long ret; |
254 | 254 | ||
255 | lflags = create ? KEY_LOOKUP_CREATE : 0; | 255 | lflags = create ? KEY_LOOKUP_CREATE : 0; |
256 | key_ref = lookup_user_key(id, lflags, KEY_SEARCH); | 256 | key_ref = lookup_user_key(id, lflags, KEY_NEED_SEARCH); |
257 | if (IS_ERR(key_ref)) { | 257 | if (IS_ERR(key_ref)) { |
258 | ret = PTR_ERR(key_ref); | 258 | ret = PTR_ERR(key_ref); |
259 | goto error; | 259 | goto error; |
@@ -334,7 +334,7 @@ long keyctl_update_key(key_serial_t id, | |||
334 | } | 334 | } |
335 | 335 | ||
336 | /* find the target key (which must be writable) */ | 336 | /* find the target key (which must be writable) */ |
337 | key_ref = lookup_user_key(id, 0, KEY_WRITE); | 337 | key_ref = lookup_user_key(id, 0, KEY_NEED_WRITE); |
338 | if (IS_ERR(key_ref)) { | 338 | if (IS_ERR(key_ref)) { |
339 | ret = PTR_ERR(key_ref); | 339 | ret = PTR_ERR(key_ref); |
340 | goto error2; | 340 | goto error2; |
@@ -365,12 +365,12 @@ long keyctl_revoke_key(key_serial_t id) | |||
365 | key_ref_t key_ref; | 365 | key_ref_t key_ref; |
366 | long ret; | 366 | long ret; |
367 | 367 | ||
368 | key_ref = lookup_user_key(id, 0, KEY_WRITE); | 368 | key_ref = lookup_user_key(id, 0, KEY_NEED_WRITE); |
369 | if (IS_ERR(key_ref)) { | 369 | if (IS_ERR(key_ref)) { |
370 | ret = PTR_ERR(key_ref); | 370 | ret = PTR_ERR(key_ref); |
371 | if (ret != -EACCES) | 371 | if (ret != -EACCES) |
372 | goto error; | 372 | goto error; |
373 | key_ref = lookup_user_key(id, 0, KEY_SETATTR); | 373 | key_ref = lookup_user_key(id, 0, KEY_NEED_SETATTR); |
374 | if (IS_ERR(key_ref)) { | 374 | if (IS_ERR(key_ref)) { |
375 | ret = PTR_ERR(key_ref); | 375 | ret = PTR_ERR(key_ref); |
376 | goto error; | 376 | goto error; |
@@ -401,7 +401,7 @@ long keyctl_invalidate_key(key_serial_t id) | |||
401 | 401 | ||
402 | kenter("%d", id); | 402 | kenter("%d", id); |
403 | 403 | ||
404 | key_ref = lookup_user_key(id, 0, KEY_SEARCH); | 404 | key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH); |
405 | if (IS_ERR(key_ref)) { | 405 | if (IS_ERR(key_ref)) { |
406 | ret = PTR_ERR(key_ref); | 406 | ret = PTR_ERR(key_ref); |
407 | goto error; | 407 | goto error; |
@@ -428,7 +428,7 @@ long keyctl_keyring_clear(key_serial_t ringid) | |||
428 | key_ref_t keyring_ref; | 428 | key_ref_t keyring_ref; |
429 | long ret; | 429 | long ret; |
430 | 430 | ||
431 | keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); | 431 | keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE); |
432 | if (IS_ERR(keyring_ref)) { | 432 | if (IS_ERR(keyring_ref)) { |
433 | ret = PTR_ERR(keyring_ref); | 433 | ret = PTR_ERR(keyring_ref); |
434 | 434 | ||
@@ -470,13 +470,13 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid) | |||
470 | key_ref_t keyring_ref, key_ref; | 470 | key_ref_t keyring_ref, key_ref; |
471 | long ret; | 471 | long ret; |
472 | 472 | ||
473 | keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); | 473 | keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE); |
474 | if (IS_ERR(keyring_ref)) { | 474 | if (IS_ERR(keyring_ref)) { |
475 | ret = PTR_ERR(keyring_ref); | 475 | ret = PTR_ERR(keyring_ref); |
476 | goto error; | 476 | goto error; |
477 | } | 477 | } |
478 | 478 | ||
479 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE, KEY_LINK); | 479 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE, KEY_NEED_LINK); |
480 | if (IS_ERR(key_ref)) { | 480 | if (IS_ERR(key_ref)) { |
481 | ret = PTR_ERR(key_ref); | 481 | ret = PTR_ERR(key_ref); |
482 | goto error2; | 482 | goto error2; |
@@ -505,7 +505,7 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid) | |||
505 | key_ref_t keyring_ref, key_ref; | 505 | key_ref_t keyring_ref, key_ref; |
506 | long ret; | 506 | long ret; |
507 | 507 | ||
508 | keyring_ref = lookup_user_key(ringid, 0, KEY_WRITE); | 508 | keyring_ref = lookup_user_key(ringid, 0, KEY_NEED_WRITE); |
509 | if (IS_ERR(keyring_ref)) { | 509 | if (IS_ERR(keyring_ref)) { |
510 | ret = PTR_ERR(keyring_ref); | 510 | ret = PTR_ERR(keyring_ref); |
511 | goto error; | 511 | goto error; |
@@ -548,7 +548,7 @@ long keyctl_describe_key(key_serial_t keyid, | |||
548 | char *tmpbuf; | 548 | char *tmpbuf; |
549 | long ret; | 549 | long ret; |
550 | 550 | ||
551 | key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_VIEW); | 551 | key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_VIEW); |
552 | if (IS_ERR(key_ref)) { | 552 | if (IS_ERR(key_ref)) { |
553 | /* viewing a key under construction is permitted if we have the | 553 | /* viewing a key under construction is permitted if we have the |
554 | * authorisation token handy */ | 554 | * authorisation token handy */ |
@@ -639,7 +639,7 @@ long keyctl_keyring_search(key_serial_t ringid, | |||
639 | } | 639 | } |
640 | 640 | ||
641 | /* get the keyring at which to begin the search */ | 641 | /* get the keyring at which to begin the search */ |
642 | keyring_ref = lookup_user_key(ringid, 0, KEY_SEARCH); | 642 | keyring_ref = lookup_user_key(ringid, 0, KEY_NEED_SEARCH); |
643 | if (IS_ERR(keyring_ref)) { | 643 | if (IS_ERR(keyring_ref)) { |
644 | ret = PTR_ERR(keyring_ref); | 644 | ret = PTR_ERR(keyring_ref); |
645 | goto error2; | 645 | goto error2; |
@@ -649,7 +649,7 @@ long keyctl_keyring_search(key_serial_t ringid, | |||
649 | dest_ref = NULL; | 649 | dest_ref = NULL; |
650 | if (destringid) { | 650 | if (destringid) { |
651 | dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE, | 651 | dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE, |
652 | KEY_WRITE); | 652 | KEY_NEED_WRITE); |
653 | if (IS_ERR(dest_ref)) { | 653 | if (IS_ERR(dest_ref)) { |
654 | ret = PTR_ERR(dest_ref); | 654 | ret = PTR_ERR(dest_ref); |
655 | goto error3; | 655 | goto error3; |
@@ -676,7 +676,7 @@ long keyctl_keyring_search(key_serial_t ringid, | |||
676 | 676 | ||
677 | /* link the resulting key to the destination keyring if we can */ | 677 | /* link the resulting key to the destination keyring if we can */ |
678 | if (dest_ref) { | 678 | if (dest_ref) { |
679 | ret = key_permission(key_ref, KEY_LINK); | 679 | ret = key_permission(key_ref, KEY_NEED_LINK); |
680 | if (ret < 0) | 680 | if (ret < 0) |
681 | goto error6; | 681 | goto error6; |
682 | 682 | ||
@@ -727,7 +727,7 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) | |||
727 | key = key_ref_to_ptr(key_ref); | 727 | key = key_ref_to_ptr(key_ref); |
728 | 728 | ||
729 | /* see if we can read it directly */ | 729 | /* see if we can read it directly */ |
730 | ret = key_permission(key_ref, KEY_READ); | 730 | ret = key_permission(key_ref, KEY_NEED_READ); |
731 | if (ret == 0) | 731 | if (ret == 0) |
732 | goto can_read_key; | 732 | goto can_read_key; |
733 | if (ret != -EACCES) | 733 | if (ret != -EACCES) |
@@ -799,7 +799,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group) | |||
799 | goto error; | 799 | goto error; |
800 | 800 | ||
801 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, | 801 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, |
802 | KEY_SETATTR); | 802 | KEY_NEED_SETATTR); |
803 | if (IS_ERR(key_ref)) { | 803 | if (IS_ERR(key_ref)) { |
804 | ret = PTR_ERR(key_ref); | 804 | ret = PTR_ERR(key_ref); |
805 | goto error; | 805 | goto error; |
@@ -905,7 +905,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm) | |||
905 | goto error; | 905 | goto error; |
906 | 906 | ||
907 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, | 907 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, |
908 | KEY_SETATTR); | 908 | KEY_NEED_SETATTR); |
909 | if (IS_ERR(key_ref)) { | 909 | if (IS_ERR(key_ref)) { |
910 | ret = PTR_ERR(key_ref); | 910 | ret = PTR_ERR(key_ref); |
911 | goto error; | 911 | goto error; |
@@ -947,7 +947,7 @@ static long get_instantiation_keyring(key_serial_t ringid, | |||
947 | 947 | ||
948 | /* if a specific keyring is nominated by ID, then use that */ | 948 | /* if a specific keyring is nominated by ID, then use that */ |
949 | if (ringid > 0) { | 949 | if (ringid > 0) { |
950 | dkref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); | 950 | dkref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE); |
951 | if (IS_ERR(dkref)) | 951 | if (IS_ERR(dkref)) |
952 | return PTR_ERR(dkref); | 952 | return PTR_ERR(dkref); |
953 | *_dest_keyring = key_ref_to_ptr(dkref); | 953 | *_dest_keyring = key_ref_to_ptr(dkref); |
@@ -1315,7 +1315,7 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout) | |||
1315 | long ret; | 1315 | long ret; |
1316 | 1316 | ||
1317 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, | 1317 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, |
1318 | KEY_SETATTR); | 1318 | KEY_NEED_SETATTR); |
1319 | if (IS_ERR(key_ref)) { | 1319 | if (IS_ERR(key_ref)) { |
1320 | /* setting the timeout on a key under construction is permitted | 1320 | /* setting the timeout on a key under construction is permitted |
1321 | * if we have the authorisation token handy */ | 1321 | * if we have the authorisation token handy */ |
@@ -1418,7 +1418,7 @@ long keyctl_get_security(key_serial_t keyid, | |||
1418 | char *context; | 1418 | char *context; |
1419 | long ret; | 1419 | long ret; |
1420 | 1420 | ||
1421 | key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_VIEW); | 1421 | key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_VIEW); |
1422 | if (IS_ERR(key_ref)) { | 1422 | if (IS_ERR(key_ref)) { |
1423 | if (PTR_ERR(key_ref) != -EACCES) | 1423 | if (PTR_ERR(key_ref) != -EACCES) |
1424 | return PTR_ERR(key_ref); | 1424 | return PTR_ERR(key_ref); |
@@ -1482,7 +1482,7 @@ long keyctl_session_to_parent(void) | |||
1482 | struct cred *cred; | 1482 | struct cred *cred; |
1483 | int ret; | 1483 | int ret; |
1484 | 1484 | ||
1485 | keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_LINK); | 1485 | keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_NEED_LINK); |
1486 | if (IS_ERR(keyring_r)) | 1486 | if (IS_ERR(keyring_r)) |
1487 | return PTR_ERR(keyring_r); | 1487 | return PTR_ERR(keyring_r); |
1488 | 1488 | ||
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index d46cbc5e335e..9cf2575f0d97 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -541,7 +541,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data) | |||
541 | /* key must have search permissions */ | 541 | /* key must have search permissions */ |
542 | if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM) && | 542 | if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM) && |
543 | key_task_permission(make_key_ref(key, ctx->possessed), | 543 | key_task_permission(make_key_ref(key, ctx->possessed), |
544 | ctx->cred, KEY_SEARCH) < 0) { | 544 | ctx->cred, KEY_NEED_SEARCH) < 0) { |
545 | ctx->result = ERR_PTR(-EACCES); | 545 | ctx->result = ERR_PTR(-EACCES); |
546 | kleave(" = %d [!perm]", ctx->skipped_ret); | 546 | kleave(" = %d [!perm]", ctx->skipped_ret); |
547 | goto skipped; | 547 | goto skipped; |
@@ -721,7 +721,7 @@ ascend_to_node: | |||
721 | /* Search a nested keyring */ | 721 | /* Search a nested keyring */ |
722 | if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM) && | 722 | if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM) && |
723 | key_task_permission(make_key_ref(key, ctx->possessed), | 723 | key_task_permission(make_key_ref(key, ctx->possessed), |
724 | ctx->cred, KEY_SEARCH) < 0) | 724 | ctx->cred, KEY_NEED_SEARCH) < 0) |
725 | continue; | 725 | continue; |
726 | 726 | ||
727 | /* stack the current position */ | 727 | /* stack the current position */ |
@@ -843,7 +843,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, | |||
843 | return ERR_PTR(-ENOTDIR); | 843 | return ERR_PTR(-ENOTDIR); |
844 | 844 | ||
845 | if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM)) { | 845 | if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM)) { |
846 | err = key_task_permission(keyring_ref, ctx->cred, KEY_SEARCH); | 846 | err = key_task_permission(keyring_ref, ctx->cred, KEY_NEED_SEARCH); |
847 | if (err < 0) | 847 | if (err < 0) |
848 | return ERR_PTR(err); | 848 | return ERR_PTR(err); |
849 | } | 849 | } |
@@ -973,7 +973,7 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check) | |||
973 | 973 | ||
974 | if (!skip_perm_check && | 974 | if (!skip_perm_check && |
975 | key_permission(make_key_ref(keyring, 0), | 975 | key_permission(make_key_ref(keyring, 0), |
976 | KEY_SEARCH) < 0) | 976 | KEY_NEED_SEARCH) < 0) |
977 | continue; | 977 | continue; |
978 | 978 | ||
979 | /* we've got a match but we might end up racing with | 979 | /* we've got a match but we might end up racing with |
@@ -1000,7 +1000,11 @@ static int keyring_detect_cycle_iterator(const void *object, | |||
1000 | 1000 | ||
1001 | kenter("{%d}", key->serial); | 1001 | kenter("{%d}", key->serial); |
1002 | 1002 | ||
1003 | BUG_ON(key != ctx->match_data); | 1003 | /* We might get a keyring with matching index-key that is nonetheless a |
1004 | * different keyring. */ | ||
1005 | if (key != ctx->match_data) | ||
1006 | return 0; | ||
1007 | |||
1004 | ctx->result = ERR_PTR(-EDEADLK); | 1008 | ctx->result = ERR_PTR(-EDEADLK); |
1005 | return 1; | 1009 | return 1; |
1006 | } | 1010 | } |
diff --git a/security/keys/permission.c b/security/keys/permission.c index efcc0c855a0d..732cc0beffdf 100644 --- a/security/keys/permission.c +++ b/security/keys/permission.c | |||
@@ -28,7 +28,7 @@ | |||
28 | * permissions bits or the LSM check. | 28 | * permissions bits or the LSM check. |
29 | */ | 29 | */ |
30 | int key_task_permission(const key_ref_t key_ref, const struct cred *cred, | 30 | int key_task_permission(const key_ref_t key_ref, const struct cred *cred, |
31 | key_perm_t perm) | 31 | unsigned perm) |
32 | { | 32 | { |
33 | struct key *key; | 33 | struct key *key; |
34 | key_perm_t kperm; | 34 | key_perm_t kperm; |
@@ -68,7 +68,7 @@ use_these_perms: | |||
68 | if (is_key_possessed(key_ref)) | 68 | if (is_key_possessed(key_ref)) |
69 | kperm |= key->perm >> 24; | 69 | kperm |= key->perm >> 24; |
70 | 70 | ||
71 | kperm = kperm & perm & KEY_ALL; | 71 | kperm = kperm & perm & KEY_NEED_ALL; |
72 | 72 | ||
73 | if (kperm != perm) | 73 | if (kperm != perm) |
74 | return -EACCES; | 74 | return -EACCES; |
diff --git a/security/keys/persistent.c b/security/keys/persistent.c index 0ad3ee283781..c9fae5ea89fe 100644 --- a/security/keys/persistent.c +++ b/security/keys/persistent.c | |||
@@ -108,7 +108,7 @@ static long key_get_persistent(struct user_namespace *ns, kuid_t uid, | |||
108 | return PTR_ERR(persistent_ref); | 108 | return PTR_ERR(persistent_ref); |
109 | 109 | ||
110 | found: | 110 | found: |
111 | ret = key_task_permission(persistent_ref, current_cred(), KEY_LINK); | 111 | ret = key_task_permission(persistent_ref, current_cred(), KEY_NEED_LINK); |
112 | if (ret == 0) { | 112 | if (ret == 0) { |
113 | persistent = key_ref_to_ptr(persistent_ref); | 113 | persistent = key_ref_to_ptr(persistent_ref); |
114 | ret = key_link(key_ref_to_ptr(dest_ref), persistent); | 114 | ret = key_link(key_ref_to_ptr(dest_ref), persistent); |
@@ -151,7 +151,7 @@ long keyctl_get_persistent(uid_t _uid, key_serial_t destid) | |||
151 | } | 151 | } |
152 | 152 | ||
153 | /* There must be a destination keyring */ | 153 | /* There must be a destination keyring */ |
154 | dest_ref = lookup_user_key(destid, KEY_LOOKUP_CREATE, KEY_WRITE); | 154 | dest_ref = lookup_user_key(destid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE); |
155 | if (IS_ERR(dest_ref)) | 155 | if (IS_ERR(dest_ref)) |
156 | return PTR_ERR(dest_ref); | 156 | return PTR_ERR(dest_ref); |
157 | if (key_ref_to_ptr(dest_ref)->type != &key_type_keyring) { | 157 | if (key_ref_to_ptr(dest_ref)->type != &key_type_keyring) { |
diff --git a/security/keys/proc.c b/security/keys/proc.c index 88e9a466940f..d3f6f2fd21db 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c | |||
@@ -218,7 +218,7 @@ static int proc_keys_show(struct seq_file *m, void *v) | |||
218 | * - the caller holds a spinlock, and thus the RCU read lock, making our | 218 | * - the caller holds a spinlock, and thus the RCU read lock, making our |
219 | * access to __current_cred() safe | 219 | * access to __current_cred() safe |
220 | */ | 220 | */ |
221 | rc = key_task_permission(key_ref, ctx.cred, KEY_VIEW); | 221 | rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW); |
222 | if (rc < 0) | 222 | if (rc < 0) |
223 | return 0; | 223 | return 0; |
224 | 224 | ||
diff --git a/security/keys/sysctl.c b/security/keys/sysctl.c index 8c0af08760c8..b68faa1a5cfd 100644 --- a/security/keys/sysctl.c +++ b/security/keys/sysctl.c | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | static const int zero, one = 1, max = INT_MAX; | 16 | static const int zero, one = 1, max = INT_MAX; |
17 | 17 | ||
18 | ctl_table key_sysctls[] = { | 18 | struct ctl_table key_sysctls[] = { |
19 | { | 19 | { |
20 | .procname = "maxkeys", | 20 | .procname = "maxkeys", |
21 | .data = &key_quota_maxkeys, | 21 | .data = &key_quota_maxkeys, |
diff --git a/security/security.c b/security/security.c index 15b6928592ef..d91fec458e90 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -1317,9 +1317,11 @@ void security_skb_owned_by(struct sk_buff *skb, struct sock *sk) | |||
1317 | 1317 | ||
1318 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1318 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
1319 | 1319 | ||
1320 | int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx) | 1320 | int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, |
1321 | struct xfrm_user_sec_ctx *sec_ctx, | ||
1322 | gfp_t gfp) | ||
1321 | { | 1323 | { |
1322 | return security_ops->xfrm_policy_alloc_security(ctxp, sec_ctx); | 1324 | return security_ops->xfrm_policy_alloc_security(ctxp, sec_ctx, gfp); |
1323 | } | 1325 | } |
1324 | EXPORT_SYMBOL(security_xfrm_policy_alloc); | 1326 | EXPORT_SYMBOL(security_xfrm_policy_alloc); |
1325 | 1327 | ||
@@ -1405,7 +1407,7 @@ void security_key_free(struct key *key) | |||
1405 | } | 1407 | } |
1406 | 1408 | ||
1407 | int security_key_permission(key_ref_t key_ref, | 1409 | int security_key_permission(key_ref_t key_ref, |
1408 | const struct cred *cred, key_perm_t perm) | 1410 | const struct cred *cred, unsigned perm) |
1409 | { | 1411 | { |
1410 | return security_ops->key_permission(key_ref, cred, perm); | 1412 | return security_ops->key_permission(key_ref, cred, perm); |
1411 | } | 1413 | } |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d5d67c93b65c..6ab22720c277 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -233,6 +233,14 @@ static int inode_alloc_security(struct inode *inode) | |||
233 | return 0; | 233 | return 0; |
234 | } | 234 | } |
235 | 235 | ||
236 | static void inode_free_rcu(struct rcu_head *head) | ||
237 | { | ||
238 | struct inode_security_struct *isec; | ||
239 | |||
240 | isec = container_of(head, struct inode_security_struct, rcu); | ||
241 | kmem_cache_free(sel_inode_cache, isec); | ||
242 | } | ||
243 | |||
236 | static void inode_free_security(struct inode *inode) | 244 | static void inode_free_security(struct inode *inode) |
237 | { | 245 | { |
238 | struct inode_security_struct *isec = inode->i_security; | 246 | struct inode_security_struct *isec = inode->i_security; |
@@ -243,8 +251,16 @@ static void inode_free_security(struct inode *inode) | |||
243 | list_del_init(&isec->list); | 251 | list_del_init(&isec->list); |
244 | spin_unlock(&sbsec->isec_lock); | 252 | spin_unlock(&sbsec->isec_lock); |
245 | 253 | ||
246 | inode->i_security = NULL; | 254 | /* |
247 | kmem_cache_free(sel_inode_cache, isec); | 255 | * The inode may still be referenced in a path walk and |
256 | * a call to selinux_inode_permission() can be made | ||
257 | * after inode_free_security() is called. Ideally, the VFS | ||
258 | * wouldn't do this, but fixing that is a much harder | ||
259 | * job. For now, simply free the i_security via RCU, and | ||
260 | * leave the current inode->i_security pointer intact. | ||
261 | * The inode will be freed after the RCU grace period too. | ||
262 | */ | ||
263 | call_rcu(&isec->rcu, inode_free_rcu); | ||
248 | } | 264 | } |
249 | 265 | ||
250 | static int file_alloc_security(struct file *file) | 266 | static int file_alloc_security(struct file *file) |
@@ -652,7 +668,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
652 | if (flags[i] == SBLABEL_MNT) | 668 | if (flags[i] == SBLABEL_MNT) |
653 | continue; | 669 | continue; |
654 | rc = security_context_to_sid(mount_options[i], | 670 | rc = security_context_to_sid(mount_options[i], |
655 | strlen(mount_options[i]), &sid); | 671 | strlen(mount_options[i]), &sid, GFP_KERNEL); |
656 | if (rc) { | 672 | if (rc) { |
657 | printk(KERN_WARNING "SELinux: security_context_to_sid" | 673 | printk(KERN_WARNING "SELinux: security_context_to_sid" |
658 | "(%s) failed for (dev %s, type %s) errno=%d\n", | 674 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
@@ -2491,7 +2507,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data) | |||
2491 | if (flags[i] == SBLABEL_MNT) | 2507 | if (flags[i] == SBLABEL_MNT) |
2492 | continue; | 2508 | continue; |
2493 | len = strlen(mount_options[i]); | 2509 | len = strlen(mount_options[i]); |
2494 | rc = security_context_to_sid(mount_options[i], len, &sid); | 2510 | rc = security_context_to_sid(mount_options[i], len, &sid, |
2511 | GFP_KERNEL); | ||
2495 | if (rc) { | 2512 | if (rc) { |
2496 | printk(KERN_WARNING "SELinux: security_context_to_sid" | 2513 | printk(KERN_WARNING "SELinux: security_context_to_sid" |
2497 | "(%s) failed for (dev %s, type %s) errno=%d\n", | 2514 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
@@ -2895,7 +2912,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2895 | if (rc) | 2912 | if (rc) |
2896 | return rc; | 2913 | return rc; |
2897 | 2914 | ||
2898 | rc = security_context_to_sid(value, size, &newsid); | 2915 | rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL); |
2899 | if (rc == -EINVAL) { | 2916 | if (rc == -EINVAL) { |
2900 | if (!capable(CAP_MAC_ADMIN)) { | 2917 | if (!capable(CAP_MAC_ADMIN)) { |
2901 | struct audit_buffer *ab; | 2918 | struct audit_buffer *ab; |
@@ -3052,7 +3069,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, | |||
3052 | if (!value || !size) | 3069 | if (!value || !size) |
3053 | return -EACCES; | 3070 | return -EACCES; |
3054 | 3071 | ||
3055 | rc = security_context_to_sid((void *)value, size, &newsid); | 3072 | rc = security_context_to_sid((void *)value, size, &newsid, GFP_KERNEL); |
3056 | if (rc) | 3073 | if (rc) |
3057 | return rc; | 3074 | return rc; |
3058 | 3075 | ||
@@ -5527,7 +5544,7 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5527 | str[size-1] = 0; | 5544 | str[size-1] = 0; |
5528 | size--; | 5545 | size--; |
5529 | } | 5546 | } |
5530 | error = security_context_to_sid(value, size, &sid); | 5547 | error = security_context_to_sid(value, size, &sid, GFP_KERNEL); |
5531 | if (error == -EINVAL && !strcmp(name, "fscreate")) { | 5548 | if (error == -EINVAL && !strcmp(name, "fscreate")) { |
5532 | if (!capable(CAP_MAC_ADMIN)) { | 5549 | if (!capable(CAP_MAC_ADMIN)) { |
5533 | struct audit_buffer *ab; | 5550 | struct audit_buffer *ab; |
@@ -5636,7 +5653,7 @@ static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | |||
5636 | 5653 | ||
5637 | static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) | 5654 | static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) |
5638 | { | 5655 | { |
5639 | return security_context_to_sid(secdata, seclen, secid); | 5656 | return security_context_to_sid(secdata, seclen, secid, GFP_KERNEL); |
5640 | } | 5657 | } |
5641 | 5658 | ||
5642 | static void selinux_release_secctx(char *secdata, u32 seclen) | 5659 | static void selinux_release_secctx(char *secdata, u32 seclen) |
@@ -5702,7 +5719,7 @@ static void selinux_key_free(struct key *k) | |||
5702 | 5719 | ||
5703 | static int selinux_key_permission(key_ref_t key_ref, | 5720 | static int selinux_key_permission(key_ref_t key_ref, |
5704 | const struct cred *cred, | 5721 | const struct cred *cred, |
5705 | key_perm_t perm) | 5722 | unsigned perm) |
5706 | { | 5723 | { |
5707 | struct key *key; | 5724 | struct key *key; |
5708 | struct key_security_struct *ksec; | 5725 | struct key_security_struct *ksec; |
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index b1dfe1049450..078e553f52f2 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
@@ -38,7 +38,10 @@ struct task_security_struct { | |||
38 | 38 | ||
39 | struct inode_security_struct { | 39 | struct inode_security_struct { |
40 | struct inode *inode; /* back pointer to inode object */ | 40 | struct inode *inode; /* back pointer to inode object */ |
41 | struct list_head list; /* list of inode_security_struct */ | 41 | union { |
42 | struct list_head list; /* list of inode_security_struct */ | ||
43 | struct rcu_head rcu; /* for freeing the inode_security_struct */ | ||
44 | }; | ||
42 | u32 task_sid; /* SID of creating task */ | 45 | u32 task_sid; /* SID of creating task */ |
43 | u32 sid; /* SID of this object */ | 46 | u32 sid; /* SID of this object */ |
44 | u16 sclass; /* security class of this object */ | 47 | u16 sclass; /* security class of this object */ |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 8ed8daf7f1ee..ce7852cf526b 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -134,7 +134,7 @@ int security_sid_to_context(u32 sid, char **scontext, | |||
134 | int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len); | 134 | int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len); |
135 | 135 | ||
136 | int security_context_to_sid(const char *scontext, u32 scontext_len, | 136 | int security_context_to_sid(const char *scontext, u32 scontext_len, |
137 | u32 *out_sid); | 137 | u32 *out_sid, gfp_t gfp); |
138 | 138 | ||
139 | int security_context_to_sid_default(const char *scontext, u32 scontext_len, | 139 | int security_context_to_sid_default(const char *scontext, u32 scontext_len, |
140 | u32 *out_sid, u32 def_sid, gfp_t gfp_flags); | 140 | u32 *out_sid, u32 def_sid, gfp_t gfp_flags); |
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 48c3cc94c168..9f0584710c85 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h | |||
@@ -10,7 +10,8 @@ | |||
10 | #include <net/flow.h> | 10 | #include <net/flow.h> |
11 | 11 | ||
12 | int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, | 12 | int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, |
13 | struct xfrm_user_sec_ctx *uctx); | 13 | struct xfrm_user_sec_ctx *uctx, |
14 | gfp_t gfp); | ||
14 | int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, | 15 | int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, |
15 | struct xfrm_sec_ctx **new_ctxp); | 16 | struct xfrm_sec_ctx **new_ctxp); |
16 | void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx); | 17 | void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx); |
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c index 332ac8a80cf5..2df7b900e259 100644 --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/inet_diag.h> | 17 | #include <linux/inet_diag.h> |
18 | #include <linux/xfrm.h> | 18 | #include <linux/xfrm.h> |
19 | #include <linux/audit.h> | 19 | #include <linux/audit.h> |
20 | #include <linux/sock_diag.h> | ||
20 | 21 | ||
21 | #include "flask.h" | 22 | #include "flask.h" |
22 | #include "av_permissions.h" | 23 | #include "av_permissions.h" |
@@ -78,6 +79,7 @@ static struct nlmsg_perm nlmsg_tcpdiag_perms[] = | |||
78 | { | 79 | { |
79 | { TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, | 80 | { TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, |
80 | { DCCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, | 81 | { DCCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, |
82 | { SOCK_DIAG_BY_FAMILY, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, | ||
81 | }; | 83 | }; |
82 | 84 | ||
83 | static struct nlmsg_perm nlmsg_xfrm_perms[] = | 85 | static struct nlmsg_perm nlmsg_xfrm_perms[] = |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 170b4b123acc..c71737f6d1cc 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -576,7 +576,7 @@ static ssize_t sel_write_context(struct file *file, char *buf, size_t size) | |||
576 | if (length) | 576 | if (length) |
577 | goto out; | 577 | goto out; |
578 | 578 | ||
579 | length = security_context_to_sid(buf, size, &sid); | 579 | length = security_context_to_sid(buf, size, &sid, GFP_KERNEL); |
580 | if (length) | 580 | if (length) |
581 | goto out; | 581 | goto out; |
582 | 582 | ||
@@ -731,11 +731,13 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) | |||
731 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) | 731 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) |
732 | goto out; | 732 | goto out; |
733 | 733 | ||
734 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); | 734 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, |
735 | GFP_KERNEL); | ||
735 | if (length) | 736 | if (length) |
736 | goto out; | 737 | goto out; |
737 | 738 | ||
738 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); | 739 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, |
740 | GFP_KERNEL); | ||
739 | if (length) | 741 | if (length) |
740 | goto out; | 742 | goto out; |
741 | 743 | ||
@@ -817,11 +819,13 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) | |||
817 | objname = namebuf; | 819 | objname = namebuf; |
818 | } | 820 | } |
819 | 821 | ||
820 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); | 822 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, |
823 | GFP_KERNEL); | ||
821 | if (length) | 824 | if (length) |
822 | goto out; | 825 | goto out; |
823 | 826 | ||
824 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); | 827 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, |
828 | GFP_KERNEL); | ||
825 | if (length) | 829 | if (length) |
826 | goto out; | 830 | goto out; |
827 | 831 | ||
@@ -878,11 +882,13 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size) | |||
878 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) | 882 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) |
879 | goto out; | 883 | goto out; |
880 | 884 | ||
881 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); | 885 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, |
886 | GFP_KERNEL); | ||
882 | if (length) | 887 | if (length) |
883 | goto out; | 888 | goto out; |
884 | 889 | ||
885 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); | 890 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, |
891 | GFP_KERNEL); | ||
886 | if (length) | 892 | if (length) |
887 | goto out; | 893 | goto out; |
888 | 894 | ||
@@ -934,7 +940,7 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size) | |||
934 | if (sscanf(buf, "%s %s", con, user) != 2) | 940 | if (sscanf(buf, "%s %s", con, user) != 2) |
935 | goto out; | 941 | goto out; |
936 | 942 | ||
937 | length = security_context_to_sid(con, strlen(con) + 1, &sid); | 943 | length = security_context_to_sid(con, strlen(con) + 1, &sid, GFP_KERNEL); |
938 | if (length) | 944 | if (length) |
939 | goto out; | 945 | goto out; |
940 | 946 | ||
@@ -994,11 +1000,13 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size) | |||
994 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) | 1000 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) |
995 | goto out; | 1001 | goto out; |
996 | 1002 | ||
997 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); | 1003 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, |
1004 | GFP_KERNEL); | ||
998 | if (length) | 1005 | if (length) |
999 | goto out; | 1006 | goto out; |
1000 | 1007 | ||
1001 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); | 1008 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, |
1009 | GFP_KERNEL); | ||
1002 | if (length) | 1010 | if (length) |
1003 | goto out; | 1011 | goto out; |
1004 | 1012 | ||
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index c0f498842129..9c5cdc2caaef 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -3338,10 +3338,10 @@ static int filename_write_helper(void *key, void *data, void *ptr) | |||
3338 | if (rc) | 3338 | if (rc) |
3339 | return rc; | 3339 | return rc; |
3340 | 3340 | ||
3341 | buf[0] = ft->stype; | 3341 | buf[0] = cpu_to_le32(ft->stype); |
3342 | buf[1] = ft->ttype; | 3342 | buf[1] = cpu_to_le32(ft->ttype); |
3343 | buf[2] = ft->tclass; | 3343 | buf[2] = cpu_to_le32(ft->tclass); |
3344 | buf[3] = otype->otype; | 3344 | buf[3] = cpu_to_le32(otype->otype); |
3345 | 3345 | ||
3346 | rc = put_entry(buf, sizeof(u32), 4, fp); | 3346 | rc = put_entry(buf, sizeof(u32), 4, fp); |
3347 | if (rc) | 3347 | if (rc) |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index fc5a63a05a1c..4bca49414a40 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -1232,6 +1232,10 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, | |||
1232 | struct context context; | 1232 | struct context context; |
1233 | int rc = 0; | 1233 | int rc = 0; |
1234 | 1234 | ||
1235 | /* An empty security context is never valid. */ | ||
1236 | if (!scontext_len) | ||
1237 | return -EINVAL; | ||
1238 | |||
1235 | if (!ss_initialized) { | 1239 | if (!ss_initialized) { |
1236 | int i; | 1240 | int i; |
1237 | 1241 | ||
@@ -1285,16 +1289,18 @@ out: | |||
1285 | * @scontext: security context | 1289 | * @scontext: security context |
1286 | * @scontext_len: length in bytes | 1290 | * @scontext_len: length in bytes |
1287 | * @sid: security identifier, SID | 1291 | * @sid: security identifier, SID |
1292 | * @gfp: context for the allocation | ||
1288 | * | 1293 | * |
1289 | * Obtains a SID associated with the security context that | 1294 | * Obtains a SID associated with the security context that |
1290 | * has the string representation specified by @scontext. | 1295 | * has the string representation specified by @scontext. |
1291 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient | 1296 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient |
1292 | * memory is available, or 0 on success. | 1297 | * memory is available, or 0 on success. |
1293 | */ | 1298 | */ |
1294 | int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid) | 1299 | int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid, |
1300 | gfp_t gfp) | ||
1295 | { | 1301 | { |
1296 | return security_context_to_sid_core(scontext, scontext_len, | 1302 | return security_context_to_sid_core(scontext, scontext_len, |
1297 | sid, SECSID_NULL, GFP_KERNEL, 0); | 1303 | sid, SECSID_NULL, gfp, 0); |
1298 | } | 1304 | } |
1299 | 1305 | ||
1300 | /** | 1306 | /** |
@@ -2948,25 +2954,21 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, | |||
2948 | struct selinux_audit_rule *rule = vrule; | 2954 | struct selinux_audit_rule *rule = vrule; |
2949 | int match = 0; | 2955 | int match = 0; |
2950 | 2956 | ||
2951 | if (!rule) { | 2957 | if (unlikely(!rule)) { |
2952 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | 2958 | WARN_ONCE(1, "selinux_audit_rule_match: missing rule\n"); |
2953 | "selinux_audit_rule_match: missing rule\n"); | ||
2954 | return -ENOENT; | 2959 | return -ENOENT; |
2955 | } | 2960 | } |
2956 | 2961 | ||
2957 | read_lock(&policy_rwlock); | 2962 | read_lock(&policy_rwlock); |
2958 | 2963 | ||
2959 | if (rule->au_seqno < latest_granting) { | 2964 | if (rule->au_seqno < latest_granting) { |
2960 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | ||
2961 | "selinux_audit_rule_match: stale rule\n"); | ||
2962 | match = -ESTALE; | 2965 | match = -ESTALE; |
2963 | goto out; | 2966 | goto out; |
2964 | } | 2967 | } |
2965 | 2968 | ||
2966 | ctxt = sidtab_search(&sidtab, sid); | 2969 | ctxt = sidtab_search(&sidtab, sid); |
2967 | if (!ctxt) { | 2970 | if (unlikely(!ctxt)) { |
2968 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | 2971 | WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n", |
2969 | "selinux_audit_rule_match: unrecognized SID %d\n", | ||
2970 | sid); | 2972 | sid); |
2971 | match = -ENOENT; | 2973 | match = -ENOENT; |
2972 | goto out; | 2974 | goto out; |
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 0462cb3ff0a7..98b042630a9e 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
@@ -78,7 +78,8 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x) | |||
78 | * xfrm_user_sec_ctx context. | 78 | * xfrm_user_sec_ctx context. |
79 | */ | 79 | */ |
80 | static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, | 80 | static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, |
81 | struct xfrm_user_sec_ctx *uctx) | 81 | struct xfrm_user_sec_ctx *uctx, |
82 | gfp_t gfp) | ||
82 | { | 83 | { |
83 | int rc; | 84 | int rc; |
84 | const struct task_security_struct *tsec = current_security(); | 85 | const struct task_security_struct *tsec = current_security(); |
@@ -94,7 +95,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, | |||
94 | if (str_len >= PAGE_SIZE) | 95 | if (str_len >= PAGE_SIZE) |
95 | return -ENOMEM; | 96 | return -ENOMEM; |
96 | 97 | ||
97 | ctx = kmalloc(sizeof(*ctx) + str_len + 1, GFP_KERNEL); | 98 | ctx = kmalloc(sizeof(*ctx) + str_len + 1, gfp); |
98 | if (!ctx) | 99 | if (!ctx) |
99 | return -ENOMEM; | 100 | return -ENOMEM; |
100 | 101 | ||
@@ -103,7 +104,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, | |||
103 | ctx->ctx_len = str_len; | 104 | ctx->ctx_len = str_len; |
104 | memcpy(ctx->ctx_str, &uctx[1], str_len); | 105 | memcpy(ctx->ctx_str, &uctx[1], str_len); |
105 | ctx->ctx_str[str_len] = '\0'; | 106 | ctx->ctx_str[str_len] = '\0'; |
106 | rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid); | 107 | rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid, gfp); |
107 | if (rc) | 108 | if (rc) |
108 | goto err; | 109 | goto err; |
109 | 110 | ||
@@ -282,9 +283,10 @@ int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid) | |||
282 | * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy. | 283 | * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy. |
283 | */ | 284 | */ |
284 | int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, | 285 | int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, |
285 | struct xfrm_user_sec_ctx *uctx) | 286 | struct xfrm_user_sec_ctx *uctx, |
287 | gfp_t gfp) | ||
286 | { | 288 | { |
287 | return selinux_xfrm_alloc_user(ctxp, uctx); | 289 | return selinux_xfrm_alloc_user(ctxp, uctx, gfp); |
288 | } | 290 | } |
289 | 291 | ||
290 | /* | 292 | /* |
@@ -332,7 +334,7 @@ int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) | |||
332 | int selinux_xfrm_state_alloc(struct xfrm_state *x, | 334 | int selinux_xfrm_state_alloc(struct xfrm_state *x, |
333 | struct xfrm_user_sec_ctx *uctx) | 335 | struct xfrm_user_sec_ctx *uctx) |
334 | { | 336 | { |
335 | return selinux_xfrm_alloc_user(&x->security, uctx); | 337 | return selinux_xfrm_alloc_user(&x->security, uctx, GFP_KERNEL); |
336 | } | 338 | } |
337 | 339 | ||
338 | /* | 340 | /* |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 9cb7559d60b2..f2c30801ce41 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -3624,11 +3624,12 @@ static void smack_key_free(struct key *key) | |||
3624 | * an error code otherwise | 3624 | * an error code otherwise |
3625 | */ | 3625 | */ |
3626 | static int smack_key_permission(key_ref_t key_ref, | 3626 | static int smack_key_permission(key_ref_t key_ref, |
3627 | const struct cred *cred, key_perm_t perm) | 3627 | const struct cred *cred, unsigned perm) |
3628 | { | 3628 | { |
3629 | struct key *keyp; | 3629 | struct key *keyp; |
3630 | struct smk_audit_info ad; | 3630 | struct smk_audit_info ad; |
3631 | struct smack_known *tkp = smk_of_task(cred->security); | 3631 | struct smack_known *tkp = smk_of_task(cred->security); |
3632 | int request = 0; | ||
3632 | 3633 | ||
3633 | keyp = key_ref_to_ptr(key_ref); | 3634 | keyp = key_ref_to_ptr(key_ref); |
3634 | if (keyp == NULL) | 3635 | if (keyp == NULL) |
@@ -3649,7 +3650,11 @@ static int smack_key_permission(key_ref_t key_ref, | |||
3649 | ad.a.u.key_struct.key = keyp->serial; | 3650 | ad.a.u.key_struct.key = keyp->serial; |
3650 | ad.a.u.key_struct.key_desc = keyp->description; | 3651 | ad.a.u.key_struct.key_desc = keyp->description; |
3651 | #endif | 3652 | #endif |
3652 | return smk_access(tkp, keyp->security, MAY_READWRITE, &ad); | 3653 | if (perm & KEY_NEED_READ) |
3654 | request = MAY_READ; | ||
3655 | if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR)) | ||
3656 | request = MAY_WRITE; | ||
3657 | return smk_access(tkp, keyp->security, request, &ad); | ||
3653 | } | 3658 | } |
3654 | #endif /* CONFIG_KEYS */ | 3659 | #endif /* CONFIG_KEYS */ |
3655 | 3660 | ||
@@ -3734,9 +3739,8 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, | |||
3734 | struct smack_known *skp; | 3739 | struct smack_known *skp; |
3735 | char *rule = vrule; | 3740 | char *rule = vrule; |
3736 | 3741 | ||
3737 | if (!rule) { | 3742 | if (unlikely(!rule)) { |
3738 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | 3743 | WARN_ONCE(1, "Smack: missing rule\n"); |
3739 | "Smack: missing rule\n"); | ||
3740 | return -ENOENT; | 3744 | return -ENOENT; |
3741 | } | 3745 | } |
3742 | 3746 | ||