diff options
author | John Johansen <john.johansen@canonical.com> | 2018-06-04 22:44:59 -0400 |
---|---|---|
committer | John Johansen <john.johansen@canonical.com> | 2018-06-07 04:50:49 -0400 |
commit | a4c3f89c9b5a9fab5a8e4ea05399acd6e23072df (patch) | |
tree | 7a92b037adce16071b0ca0207115b7d8f434c5c6 | |
parent | 99cc45e486786c7215a7e39824c3bbaf7cf2fc08 (diff) |
apparmor: fixup secid map conversion to using IDR
The IDR conversion did not handle an error case for when allocating a
mapping fails, and it did not ensure that mappings did not allocate or
use a 0 value, which is used as an invalid secid. Which is used when a
mapping fails.
Fixes: 3ae7eb49a2be ("apparmor: Use an IDR to allocate apparmor secids")
Signed-off-by: John Johansen <john.johansen@canonical.com>
-rw-r--r-- | security/apparmor/include/secid.h | 4 | ||||
-rw-r--r-- | security/apparmor/label.c | 3 | ||||
-rw-r--r-- | security/apparmor/lsm.c | 2 | ||||
-rw-r--r-- | security/apparmor/secid.c | 28 |
4 files changed, 29 insertions, 8 deletions
diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h index 686de8e50a79..dee6fa3b6081 100644 --- a/security/apparmor/include/secid.h +++ b/security/apparmor/include/secid.h | |||
@@ -28,8 +28,10 @@ int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); | |||
28 | void apparmor_release_secctx(char *secdata, u32 seclen); | 28 | void apparmor_release_secctx(char *secdata, u32 seclen); |
29 | 29 | ||
30 | 30 | ||
31 | u32 aa_alloc_secid(struct aa_label *label, gfp_t gfp); | 31 | int aa_alloc_secid(struct aa_label *label, gfp_t gfp); |
32 | void aa_free_secid(u32 secid); | 32 | void aa_free_secid(u32 secid); |
33 | void aa_secid_update(u32 secid, struct aa_label *label); | 33 | void aa_secid_update(u32 secid, struct aa_label *label); |
34 | 34 | ||
35 | void aa_secids_init(void); | ||
36 | |||
35 | #endif /* __AA_SECID_H */ | 37 | #endif /* __AA_SECID_H */ |
diff --git a/security/apparmor/label.c b/security/apparmor/label.c index a17574df611b..ba11bdf9043a 100644 --- a/security/apparmor/label.c +++ b/security/apparmor/label.c | |||
@@ -407,8 +407,7 @@ bool aa_label_init(struct aa_label *label, int size, gfp_t gfp) | |||
407 | AA_BUG(!label); | 407 | AA_BUG(!label); |
408 | AA_BUG(size < 1); | 408 | AA_BUG(size < 1); |
409 | 409 | ||
410 | label->secid = aa_alloc_secid(label, gfp); | 410 | if (aa_alloc_secid(label, gfp) < 0) |
411 | if (label->secid == AA_SECID_INVALID) | ||
412 | return false; | 411 | return false; |
413 | 412 | ||
414 | label->size = size; /* doesn't include null */ | 413 | label->size = size; /* doesn't include null */ |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 10bf36aa477d..e35d12883990 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -1547,6 +1547,8 @@ static int __init apparmor_init(void) | |||
1547 | return 0; | 1547 | return 0; |
1548 | } | 1548 | } |
1549 | 1549 | ||
1550 | aa_secids_init(); | ||
1551 | |||
1550 | error = aa_setup_dfa_engine(); | 1552 | error = aa_setup_dfa_engine(); |
1551 | if (error) { | 1553 | if (error) { |
1552 | AA_ERROR("Unable to setup dfa engine\n"); | 1554 | AA_ERROR("Unable to setup dfa engine\n"); |
diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c index 3ad94b2ffbb2..f2f22d00db18 100644 --- a/security/apparmor/secid.c +++ b/security/apparmor/secid.c | |||
@@ -33,6 +33,8 @@ | |||
33 | * properly updating/freeing them | 33 | * properly updating/freeing them |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #define AA_FIRST_SECID 1 | ||
37 | |||
36 | static DEFINE_IDR(aa_secids); | 38 | static DEFINE_IDR(aa_secids); |
37 | static DEFINE_SPINLOCK(secid_lock); | 39 | static DEFINE_SPINLOCK(secid_lock); |
38 | 40 | ||
@@ -120,20 +122,31 @@ void apparmor_release_secctx(char *secdata, u32 seclen) | |||
120 | 122 | ||
121 | /** | 123 | /** |
122 | * aa_alloc_secid - allocate a new secid for a profile | 124 | * aa_alloc_secid - allocate a new secid for a profile |
125 | * @label: the label to allocate a secid for | ||
126 | * @gfp: memory allocation flags | ||
127 | * | ||
128 | * Returns: 0 with @label->secid initialized | ||
129 | * <0 returns error with @label->secid set to AA_SECID_INVALID | ||
123 | */ | 130 | */ |
124 | u32 aa_alloc_secid(struct aa_label *label, gfp_t gfp) | 131 | int aa_alloc_secid(struct aa_label *label, gfp_t gfp) |
125 | { | 132 | { |
126 | unsigned long flags; | 133 | unsigned long flags; |
127 | u32 secid; | 134 | int ret; |
128 | 135 | ||
129 | idr_preload(gfp); | 136 | idr_preload(gfp); |
130 | spin_lock_irqsave(&secid_lock, flags); | 137 | spin_lock_irqsave(&secid_lock, flags); |
131 | secid = idr_alloc(&aa_secids, label, 0, 0, GFP_ATOMIC); | 138 | ret = idr_alloc(&aa_secids, label, AA_FIRST_SECID, 0, GFP_ATOMIC); |
132 | /* XXX: Can return -ENOMEM */ | ||
133 | spin_unlock_irqrestore(&secid_lock, flags); | 139 | spin_unlock_irqrestore(&secid_lock, flags); |
134 | idr_preload_end(); | 140 | idr_preload_end(); |
135 | 141 | ||
136 | return secid; | 142 | if (ret < 0) { |
143 | label->secid = AA_SECID_INVALID; | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | AA_BUG(ret == AA_SECID_INVALID); | ||
148 | label->secid = ret; | ||
149 | return 0; | ||
137 | } | 150 | } |
138 | 151 | ||
139 | /** | 152 | /** |
@@ -148,3 +161,8 @@ void aa_free_secid(u32 secid) | |||
148 | idr_remove(&aa_secids, secid); | 161 | idr_remove(&aa_secids, secid); |
149 | spin_unlock_irqrestore(&secid_lock, flags); | 162 | spin_unlock_irqrestore(&secid_lock, flags); |
150 | } | 163 | } |
164 | |||
165 | void aa_secids_init(void) | ||
166 | { | ||
167 | idr_init_base(&aa_secids, AA_FIRST_SECID); | ||
168 | } | ||