Increase size of ucounts to atomic_long_t
authorAlexey Gladkov <legion@kernel.org>
Thu, 22 Apr 2021 12:27:08 +0000 (14:27 +0200)
committerEric W. Biederman <ebiederm@xmission.com>
Fri, 30 Apr 2021 19:14:00 +0000 (14:14 -0500)
RLIMIT_MSGQUEUE and RLIMIT_MEMLOCK use unsigned long to store their
counters. As a preparation for moving rlimits based on ucounts, we need
to increase the size of the variable to long.

Signed-off-by: Alexey Gladkov <legion@kernel.org>
Link: https://lkml.kernel.org/r/257aa5fb1a7d81cf0f4c34f39ada2320c4284771.1619094428.git.legion@kernel.org
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
include/linux/user_namespace.h
kernel/ucount.c

index f6c5f78..c242c10 100644 (file)
@@ -88,7 +88,7 @@ struct user_namespace {
        struct ctl_table_header *sysctls;
 #endif
        struct ucounts          *ucounts;
-       int ucount_max[UCOUNT_COUNTS];
+       long ucount_max[UCOUNT_COUNTS];
 } __randomize_layout;
 
 struct ucounts {
@@ -96,7 +96,7 @@ struct ucounts {
        struct user_namespace *ns;
        kuid_t uid;
        int count;
-       atomic_t ucount[UCOUNT_COUNTS];
+       atomic_long_t ucount[UCOUNT_COUNTS];
 };
 
 extern struct user_namespace init_user_ns;
index 11b1596..04c5617 100644 (file)
@@ -175,14 +175,14 @@ static void put_ucounts(struct ucounts *ucounts)
        kfree(ucounts);
 }
 
-static inline bool atomic_inc_below(atomic_t *v, int u)
+static inline bool atomic_long_inc_below(atomic_long_t *v, int u)
 {
-       int c, old;
-       c = atomic_read(v);
+       long c, old;
+       c = atomic_long_read(v);
        for (;;) {
                if (unlikely(c >= u))
                        return false;
-               old = atomic_cmpxchg(v, c, c+1);
+               old = atomic_long_cmpxchg(v, c, c+1);
                if (likely(old == c))
                        return true;
                c = old;
@@ -196,17 +196,17 @@ struct ucounts *inc_ucount(struct user_namespace *ns, kuid_t uid,
        struct user_namespace *tns;
        ucounts = get_ucounts(ns, uid);
        for (iter = ucounts; iter; iter = tns->ucounts) {
-               int max;
+               long max;
                tns = iter->ns;
                max = READ_ONCE(tns->ucount_max[type]);
-               if (!atomic_inc_below(&iter->ucount[type], max))
+               if (!atomic_long_inc_below(&iter->ucount[type], max))
                        goto fail;
        }
        return ucounts;
 fail:
        bad = iter;
        for (iter = ucounts; iter != bad; iter = iter->ns->ucounts)
-               atomic_dec(&iter->ucount[type]);
+               atomic_long_dec(&iter->ucount[type]);
 
        put_ucounts(ucounts);
        return NULL;
@@ -216,7 +216,7 @@ void dec_ucount(struct ucounts *ucounts, enum ucount_type type)
 {
        struct ucounts *iter;
        for (iter = ucounts; iter; iter = iter->ns->ucounts) {
-               int dec = atomic_dec_if_positive(&iter->ucount[type]);
+               long dec = atomic_long_dec_if_positive(&iter->ucount[type]);
                WARN_ON_ONCE(dec < 0);
        }
        put_ucounts(ucounts);