diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-06-12 22:10:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-06-12 22:10:57 -0400 |
commit | b076173a309e2ceae84257d1d52cd3cc53b00e39 (patch) | |
tree | 9d2fa88597c3f8f7c8e984598731c3a5f308f808 /security/selinux | |
parent | 35110e38e6c59b0db9618701d75c7c2a36f98d55 (diff) | |
parent | fec6375320c6399c708fa9801f8cfbf950fee623 (diff) |
Merge tag 'selinux-pr-20190612' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux fixes from Paul Moore:
"Three patches for v5.2.
One fixes a problem where we weren't correctly logging raw SELinux
labels, the other two fix problems where we weren't properly checking
calls to kmemdup()"
* tag 'selinux-pr-20190612' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
selinux: fix a missing-check bug in selinux_sb_eat_lsm_opts()
selinux: fix a missing-check bug in selinux_add_mnt_opt( )
selinux: log raw contexts as untrusted strings
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/avc.c | 10 | ||||
-rw-r--r-- | security/selinux/hooks.c | 39 |
2 files changed, 36 insertions, 13 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 8346a4f7c5d7..a99be508f93d 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -739,14 +739,20 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) | |||
739 | rc = security_sid_to_context_inval(sad->state, sad->ssid, &scontext, | 739 | rc = security_sid_to_context_inval(sad->state, sad->ssid, &scontext, |
740 | &scontext_len); | 740 | &scontext_len); |
741 | if (!rc && scontext) { | 741 | if (!rc && scontext) { |
742 | audit_log_format(ab, " srawcon=%s", scontext); | 742 | if (scontext_len && scontext[scontext_len - 1] == '\0') |
743 | scontext_len--; | ||
744 | audit_log_format(ab, " srawcon="); | ||
745 | audit_log_n_untrustedstring(ab, scontext, scontext_len); | ||
743 | kfree(scontext); | 746 | kfree(scontext); |
744 | } | 747 | } |
745 | 748 | ||
746 | rc = security_sid_to_context_inval(sad->state, sad->tsid, &scontext, | 749 | rc = security_sid_to_context_inval(sad->state, sad->tsid, &scontext, |
747 | &scontext_len); | 750 | &scontext_len); |
748 | if (!rc && scontext) { | 751 | if (!rc && scontext) { |
749 | audit_log_format(ab, " trawcon=%s", scontext); | 752 | if (scontext_len && scontext[scontext_len - 1] == '\0') |
753 | scontext_len--; | ||
754 | audit_log_format(ab, " trawcon="); | ||
755 | audit_log_n_untrustedstring(ab, scontext, scontext_len); | ||
750 | kfree(scontext); | 756 | kfree(scontext); |
751 | } | 757 | } |
752 | } | 758 | } |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 3ec702cf46ca..fea66f6b31bf 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1052,15 +1052,24 @@ static int selinux_add_mnt_opt(const char *option, const char *val, int len, | |||
1052 | if (token == Opt_error) | 1052 | if (token == Opt_error) |
1053 | return -EINVAL; | 1053 | return -EINVAL; |
1054 | 1054 | ||
1055 | if (token != Opt_seclabel) | 1055 | if (token != Opt_seclabel) { |
1056 | val = kmemdup_nul(val, len, GFP_KERNEL); | 1056 | val = kmemdup_nul(val, len, GFP_KERNEL); |
1057 | if (!val) { | ||
1058 | rc = -ENOMEM; | ||
1059 | goto free_opt; | ||
1060 | } | ||
1061 | } | ||
1057 | rc = selinux_add_opt(token, val, mnt_opts); | 1062 | rc = selinux_add_opt(token, val, mnt_opts); |
1058 | if (unlikely(rc)) { | 1063 | if (unlikely(rc)) { |
1059 | kfree(val); | 1064 | kfree(val); |
1060 | if (*mnt_opts) { | 1065 | goto free_opt; |
1061 | selinux_free_mnt_opts(*mnt_opts); | 1066 | } |
1062 | *mnt_opts = NULL; | 1067 | return rc; |
1063 | } | 1068 | |
1069 | free_opt: | ||
1070 | if (*mnt_opts) { | ||
1071 | selinux_free_mnt_opts(*mnt_opts); | ||
1072 | *mnt_opts = NULL; | ||
1064 | } | 1073 | } |
1065 | return rc; | 1074 | return rc; |
1066 | } | 1075 | } |
@@ -2616,10 +2625,11 @@ static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts) | |||
2616 | char *from = options; | 2625 | char *from = options; |
2617 | char *to = options; | 2626 | char *to = options; |
2618 | bool first = true; | 2627 | bool first = true; |
2628 | int rc; | ||
2619 | 2629 | ||
2620 | while (1) { | 2630 | while (1) { |
2621 | int len = opt_len(from); | 2631 | int len = opt_len(from); |
2622 | int token, rc; | 2632 | int token; |
2623 | char *arg = NULL; | 2633 | char *arg = NULL; |
2624 | 2634 | ||
2625 | token = match_opt_prefix(from, len, &arg); | 2635 | token = match_opt_prefix(from, len, &arg); |
@@ -2635,15 +2645,15 @@ static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts) | |||
2635 | *q++ = c; | 2645 | *q++ = c; |
2636 | } | 2646 | } |
2637 | arg = kmemdup_nul(arg, q - arg, GFP_KERNEL); | 2647 | arg = kmemdup_nul(arg, q - arg, GFP_KERNEL); |
2648 | if (!arg) { | ||
2649 | rc = -ENOMEM; | ||
2650 | goto free_opt; | ||
2651 | } | ||
2638 | } | 2652 | } |
2639 | rc = selinux_add_opt(token, arg, mnt_opts); | 2653 | rc = selinux_add_opt(token, arg, mnt_opts); |
2640 | if (unlikely(rc)) { | 2654 | if (unlikely(rc)) { |
2641 | kfree(arg); | 2655 | kfree(arg); |
2642 | if (*mnt_opts) { | 2656 | goto free_opt; |
2643 | selinux_free_mnt_opts(*mnt_opts); | ||
2644 | *mnt_opts = NULL; | ||
2645 | } | ||
2646 | return rc; | ||
2647 | } | 2657 | } |
2648 | } else { | 2658 | } else { |
2649 | if (!first) { // copy with preceding comma | 2659 | if (!first) { // copy with preceding comma |
@@ -2661,6 +2671,13 @@ static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts) | |||
2661 | } | 2671 | } |
2662 | *to = '\0'; | 2672 | *to = '\0'; |
2663 | return 0; | 2673 | return 0; |
2674 | |||
2675 | free_opt: | ||
2676 | if (*mnt_opts) { | ||
2677 | selinux_free_mnt_opts(*mnt_opts); | ||
2678 | *mnt_opts = NULL; | ||
2679 | } | ||
2680 | return rc; | ||
2664 | } | 2681 | } |
2665 | 2682 | ||
2666 | static int selinux_sb_remount(struct super_block *sb, void *mnt_opts) | 2683 | static int selinux_sb_remount(struct super_block *sb, void *mnt_opts) |