Commit 6209049e authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace

Pull ucounts fix from Eric Biederman:
 "Fix a subtle locking versus reference counting bug in the ucount
  changes, found by syzbot"

* 'for-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace:
  ucounts: Fix race condition between alloc_ucounts and put_ucounts
parents 3c3e9027 345daff2
...@@ -160,6 +160,7 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid) ...@@ -160,6 +160,7 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid)
{ {
struct hlist_head *hashent = ucounts_hashentry(ns, uid); struct hlist_head *hashent = ucounts_hashentry(ns, uid);
struct ucounts *ucounts, *new; struct ucounts *ucounts, *new;
long overflow;
spin_lock_irq(&ucounts_lock); spin_lock_irq(&ucounts_lock);
ucounts = find_ucounts(ns, uid, hashent); ucounts = find_ucounts(ns, uid, hashent);
...@@ -184,8 +185,12 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid) ...@@ -184,8 +185,12 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid)
return new; return new;
} }
} }
overflow = atomic_add_negative(1, &ucounts->count);
spin_unlock_irq(&ucounts_lock); spin_unlock_irq(&ucounts_lock);
ucounts = get_ucounts(ucounts); if (overflow) {
put_ucounts(ucounts);
return NULL;
}
return ucounts; return ucounts;
} }
...@@ -193,8 +198,7 @@ void put_ucounts(struct ucounts *ucounts) ...@@ -193,8 +198,7 @@ void put_ucounts(struct ucounts *ucounts)
{ {
unsigned long flags; unsigned long flags;
if (atomic_dec_and_test(&ucounts->count)) { if (atomic_dec_and_lock_irqsave(&ucounts->count, &ucounts_lock, flags)) {
spin_lock_irqsave(&ucounts_lock, flags);
hlist_del_init(&ucounts->node); hlist_del_init(&ucounts->node);
spin_unlock_irqrestore(&ucounts_lock, flags); spin_unlock_irqrestore(&ucounts_lock, flags);
kfree(ucounts); kfree(ucounts);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment