aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2018-06-04 22:44:59 -0400
committerJohn Johansen <john.johansen@canonical.com>2018-06-07 04:50:49 -0400
commita4c3f89c9b5a9fab5a8e4ea05399acd6e23072df (patch)
tree7a92b037adce16071b0ca0207115b7d8f434c5c6
parent99cc45e486786c7215a7e39824c3bbaf7cf2fc08 (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.h4
-rw-r--r--security/apparmor/label.c3
-rw-r--r--security/apparmor/lsm.c2
-rw-r--r--security/apparmor/secid.c28
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);
28void apparmor_release_secctx(char *secdata, u32 seclen); 28void apparmor_release_secctx(char *secdata, u32 seclen);
29 29
30 30
31u32 aa_alloc_secid(struct aa_label *label, gfp_t gfp); 31int aa_alloc_secid(struct aa_label *label, gfp_t gfp);
32void aa_free_secid(u32 secid); 32void aa_free_secid(u32 secid);
33void aa_secid_update(u32 secid, struct aa_label *label); 33void aa_secid_update(u32 secid, struct aa_label *label);
34 34
35void 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
36static DEFINE_IDR(aa_secids); 38static DEFINE_IDR(aa_secids);
37static DEFINE_SPINLOCK(secid_lock); 39static 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 */
124u32 aa_alloc_secid(struct aa_label *label, gfp_t gfp) 131int 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
165void aa_secids_init(void)
166{
167 idr_init_base(&aa_secids, AA_FIRST_SECID);
168}