summaryrefslogtreecommitdiff
path: root/security/selinux/ss/sidtab.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-04-09 21:51:06 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2021-04-09 21:51:06 +0300
commit60144b23c94216b4aca6fba90dca9349183f39e1 (patch)
treed8377c1d2896c0c61b955c24bdbceee7789d21c6 /security/selinux/ss/sidtab.c
parent189fefc7a4f0401d0f799de96b772319a6541fc1 (diff)
parent9ad6e9cb39c66366bf7b9aece114aca277981a1f (diff)
downloadlinux-60144b23c94216b4aca6fba90dca9349183f39e1.tar.xz
Merge tag 'selinux-pr-20210409' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux fixes from Paul Moore: "Three SELinux fixes. These fix known problems relating to (re)loading SELinux policy or changing the policy booleans, and pass our test suite without problem" * tag 'selinux-pr-20210409' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: fix race between old and new sidtab selinux: fix cond_list corruption when changing booleans selinux: make nslot handling in avtab more robust
Diffstat (limited to 'security/selinux/ss/sidtab.c')
-rw-r--r--security/selinux/ss/sidtab.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index 5ee190bd30f5..656d50b09f76 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -39,6 +39,7 @@ int sidtab_init(struct sidtab *s)
for (i = 0; i < SECINITSID_NUM; i++)
s->isids[i].set = 0;
+ s->frozen = false;
s->count = 0;
s->convert = NULL;
hash_init(s->context_to_sid);
@@ -281,6 +282,15 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context,
if (*sid)
goto out_unlock;
+ if (unlikely(s->frozen)) {
+ /*
+ * This sidtab is now frozen - tell the caller to abort and
+ * get the new one.
+ */
+ rc = -ESTALE;
+ goto out_unlock;
+ }
+
count = s->count;
convert = s->convert;
@@ -474,6 +484,17 @@ void sidtab_cancel_convert(struct sidtab *s)
spin_unlock_irqrestore(&s->lock, flags);
}
+void sidtab_freeze_begin(struct sidtab *s, unsigned long *flags) __acquires(&s->lock)
+{
+ spin_lock_irqsave(&s->lock, *flags);
+ s->frozen = true;
+ s->convert = NULL;
+}
+void sidtab_freeze_end(struct sidtab *s, unsigned long *flags) __releases(&s->lock)
+{
+ spin_unlock_irqrestore(&s->lock, *flags);
+}
+
static void sidtab_destroy_entry(struct sidtab_entry *entry)
{
context_destroy(&entry->context);