diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-08-09 09:03:47 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-08-09 09:03:47 +0200 |
commit | bd935a7b21340e2e37f51a7f2d3188145e2fcf1f (patch) | |
tree | ac8af4e6ea552d32839c415b2f36d416ee327ea4 /kernel/ucount.c | |
parent | 96ba6c6e8922e89ca4908c650072d8f8d7b39cbc (diff) | |
parent | 36a21d51725af2ce0700c6ebcb6b9594aac658a6 (diff) | |
download | linux-bd935a7b21340e2e37f51a7f2d3188145e2fcf1f.tar.gz linux-bd935a7b21340e2e37f51a7f2d3188145e2fcf1f.tar.bz2 linux-bd935a7b21340e2e37f51a7f2d3188145e2fcf1f.zip |
Merge 5.14-rc5 into driver-core-next
We need the driver core fixes in here as well.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel/ucount.c')
-rw-r--r-- | kernel/ucount.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/kernel/ucount.c b/kernel/ucount.c index 87799e2379bd..77be3bbe3cc4 100644 --- a/kernel/ucount.c +++ b/kernel/ucount.c @@ -160,6 +160,7 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid) { struct hlist_head *hashent = ucounts_hashentry(ns, uid); struct ucounts *ucounts, *new; + long overflow; spin_lock_irq(&ucounts_lock); ucounts = find_ucounts(ns, uid, hashent); @@ -184,8 +185,12 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid) return new; } } + overflow = atomic_add_negative(1, &ucounts->count); spin_unlock_irq(&ucounts_lock); - ucounts = get_ucounts(ucounts); + if (overflow) { + put_ucounts(ucounts); + return NULL; + } return ucounts; } @@ -193,8 +198,7 @@ void put_ucounts(struct ucounts *ucounts) { unsigned long flags; - if (atomic_dec_and_test(&ucounts->count)) { - spin_lock_irqsave(&ucounts_lock, flags); + if (atomic_dec_and_lock_irqsave(&ucounts->count, &ucounts_lock, flags)) { hlist_del_init(&ucounts->node); spin_unlock_irqrestore(&ucounts_lock, flags); kfree(ucounts); |