Merge branch 'ucount-rlimit-fixes-for-v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull ucount fix from Eric Biederman: "This fixes a silly logic bug in the ucount rlimits code, where it was comparing against the wrong limit" * 'ucount-rlimit-fixes-for-v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: ucounts: Fix rlimit max values check
This commit is contained in:
commit
7fe2bc1b64
|
@ -264,15 +264,16 @@ void dec_ucount(struct ucounts *ucounts, enum ucount_type type)
|
|||
long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v)
|
||||
{
|
||||
struct ucounts *iter;
|
||||
long max = LONG_MAX;
|
||||
long ret = 0;
|
||||
|
||||
for (iter = ucounts; iter; iter = iter->ns->ucounts) {
|
||||
long max = READ_ONCE(iter->ns->ucount_max[type]);
|
||||
long new = atomic_long_add_return(v, &iter->ucount[type]);
|
||||
if (new < 0 || new > max)
|
||||
ret = LONG_MAX;
|
||||
else if (iter == ucounts)
|
||||
ret = new;
|
||||
max = READ_ONCE(iter->ns->ucount_max[type]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -312,15 +313,16 @@ long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type)
|
|||
{
|
||||
/* Caller must hold a reference to ucounts */
|
||||
struct ucounts *iter;
|
||||
long max = LONG_MAX;
|
||||
long dec, ret = 0;
|
||||
|
||||
for (iter = ucounts; iter; iter = iter->ns->ucounts) {
|
||||
long max = READ_ONCE(iter->ns->ucount_max[type]);
|
||||
long new = atomic_long_add_return(1, &iter->ucount[type]);
|
||||
if (new < 0 || new > max)
|
||||
goto unwind;
|
||||
if (iter == ucounts)
|
||||
ret = new;
|
||||
max = READ_ONCE(iter->ns->ucount_max[type]);
|
||||
/*
|
||||
* Grab an extra ucount reference for the caller when
|
||||
* the rlimit count was previously 0.
|
||||
|
@ -339,15 +341,16 @@ unwind:
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max)
|
||||
bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long rlimit)
|
||||
{
|
||||
struct ucounts *iter;
|
||||
if (get_ucounts_value(ucounts, type) > max)
|
||||
return true;
|
||||
long max = rlimit;
|
||||
if (rlimit > LONG_MAX)
|
||||
max = LONG_MAX;
|
||||
for (iter = ucounts; iter; iter = iter->ns->ucounts) {
|
||||
max = READ_ONCE(iter->ns->ucount_max[type]);
|
||||
if (get_ucounts_value(iter, type) > max)
|
||||
return true;
|
||||
max = READ_ONCE(iter->ns->ucount_max[type]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue