Skip to content

Commit df43909

Browse files
Matthew Wilcoxjrjohansen
authored andcommitted
apparmor: Convert secid mapping to XArrays instead of IDR
XArrays are a better match than IDR for how AppArmor is mapping secids. Specifically AppArmor is trying to keep the allocation dense. XArrays also have the advantage of avoiding the complexity IDRs preallocation. In addition this avoids/fixes a lockdep issue raised in the LKML thread "Linux 5.18-rc4" where there is a report of an interaction between apparmor and IPC, this warning may have been spurious as the reported issue is in a per-cpu local lock taken by the IDR. With the one side in the IPC id allocation and the other in AppArmor's secid allocation. Description by John Johansen <[email protected]> Message-Id: <[email protected]> Signed-off-by: Matthew Wilcox <[email protected]> Signed-off-by: John Johansen <[email protected]>
1 parent 95c0581 commit df43909

File tree

3 files changed

+13
-32
lines changed

3 files changed

+13
-32
lines changed

security/apparmor/include/secid.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,4 @@ int aa_alloc_secid(struct aa_label *label, gfp_t gfp);
3131
void aa_free_secid(u32 secid);
3232
void aa_secid_update(u32 secid, struct aa_label *label);
3333

34-
void aa_secids_init(void);
35-
3634
#endif /* __AA_SECID_H */

security/apparmor/lsm.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1857,8 +1857,6 @@ static int __init apparmor_init(void)
18571857
{
18581858
int error;
18591859

1860-
aa_secids_init();
1861-
18621860
error = aa_setup_dfa_engine();
18631861
if (error) {
18641862
AA_ERROR("Unable to setup dfa engine\n");

security/apparmor/secid.c

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
#include <linux/errno.h>
1414
#include <linux/err.h>
1515
#include <linux/gfp.h>
16-
#include <linux/idr.h>
1716
#include <linux/slab.h>
1817
#include <linux/spinlock.h>
18+
#include <linux/xarray.h>
1919

2020
#include "include/cred.h"
2121
#include "include/lib.h"
@@ -29,8 +29,7 @@
2929
*/
3030
#define AA_FIRST_SECID 2
3131

32-
static DEFINE_IDR(aa_secids);
33-
static DEFINE_SPINLOCK(secid_lock);
32+
static DEFINE_XARRAY_FLAGS(aa_secids, XA_FLAGS_LOCK_IRQ | XA_FLAGS_TRACK_FREE);
3433

3534
/*
3635
* TODO: allow policy to reserve a secid range?
@@ -47,9 +46,9 @@ void aa_secid_update(u32 secid, struct aa_label *label)
4746
{
4847
unsigned long flags;
4948

50-
spin_lock_irqsave(&secid_lock, flags);
51-
idr_replace(&aa_secids, label, secid);
52-
spin_unlock_irqrestore(&secid_lock, flags);
49+
xa_lock_irqsave(&aa_secids, flags);
50+
__xa_store(&aa_secids, secid, label, 0);
51+
xa_unlock_irqrestore(&aa_secids, flags);
5352
}
5453

5554
/**
@@ -58,13 +57,7 @@ void aa_secid_update(u32 secid, struct aa_label *label)
5857
*/
5958
struct aa_label *aa_secid_to_label(u32 secid)
6059
{
61-
struct aa_label *label;
62-
63-
rcu_read_lock();
64-
label = idr_find(&aa_secids, secid);
65-
rcu_read_unlock();
66-
67-
return label;
60+
return xa_load(&aa_secids, secid);
6861
}
6962

7063
int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
@@ -126,19 +119,16 @@ int aa_alloc_secid(struct aa_label *label, gfp_t gfp)
126119
unsigned long flags;
127120
int ret;
128121

129-
idr_preload(gfp);
130-
spin_lock_irqsave(&secid_lock, flags);
131-
ret = idr_alloc(&aa_secids, label, AA_FIRST_SECID, 0, GFP_ATOMIC);
132-
spin_unlock_irqrestore(&secid_lock, flags);
133-
idr_preload_end();
122+
xa_lock_irqsave(&aa_secids, flags);
123+
ret = __xa_alloc(&aa_secids, &label->secid, label,
124+
XA_LIMIT(AA_FIRST_SECID, INT_MAX), gfp);
125+
xa_unlock_irqrestore(&aa_secids, flags);
134126

135127
if (ret < 0) {
136128
label->secid = AA_SECID_INVALID;
137129
return ret;
138130
}
139131

140-
AA_BUG(ret == AA_SECID_INVALID);
141-
label->secid = ret;
142132
return 0;
143133
}
144134

@@ -150,12 +140,7 @@ void aa_free_secid(u32 secid)
150140
{
151141
unsigned long flags;
152142

153-
spin_lock_irqsave(&secid_lock, flags);
154-
idr_remove(&aa_secids, secid);
155-
spin_unlock_irqrestore(&secid_lock, flags);
156-
}
157-
158-
void aa_secids_init(void)
159-
{
160-
idr_init_base(&aa_secids, AA_FIRST_SECID);
143+
xa_lock_irqsave(&aa_secids, flags);
144+
__xa_erase(&aa_secids, secid);
145+
xa_unlock_irqrestore(&aa_secids, flags);
161146
}

0 commit comments

Comments
 (0)