Skip to content

Commit 7fe2bc1

Browse files
committed
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
2 parents 76657ea + 59ec715 commit 7fe2bc1

1 file changed

Lines changed: 9 additions & 6 deletions

File tree

kernel/ucount.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,15 +264,16 @@ void dec_ucount(struct ucounts *ucounts, enum ucount_type type)
264264
long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v)
265265
{
266266
struct ucounts *iter;
267+
long max = LONG_MAX;
267268
long ret = 0;
268269

269270
for (iter = ucounts; iter; iter = iter->ns->ucounts) {
270-
long max = READ_ONCE(iter->ns->ucount_max[type]);
271271
long new = atomic_long_add_return(v, &iter->ucount[type]);
272272
if (new < 0 || new > max)
273273
ret = LONG_MAX;
274274
else if (iter == ucounts)
275275
ret = new;
276+
max = READ_ONCE(iter->ns->ucount_max[type]);
276277
}
277278
return ret;
278279
}
@@ -312,15 +313,16 @@ long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type)
312313
{
313314
/* Caller must hold a reference to ucounts */
314315
struct ucounts *iter;
316+
long max = LONG_MAX;
315317
long dec, ret = 0;
316318

317319
for (iter = ucounts; iter; iter = iter->ns->ucounts) {
318-
long max = READ_ONCE(iter->ns->ucount_max[type]);
319320
long new = atomic_long_add_return(1, &iter->ucount[type]);
320321
if (new < 0 || new > max)
321322
goto unwind;
322323
if (iter == ucounts)
323324
ret = new;
325+
max = READ_ONCE(iter->ns->ucount_max[type]);
324326
/*
325327
* Grab an extra ucount reference for the caller when
326328
* the rlimit count was previously 0.
@@ -339,15 +341,16 @@ long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type)
339341
return 0;
340342
}
341343

342-
bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max)
344+
bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long rlimit)
343345
{
344346
struct ucounts *iter;
345-
if (get_ucounts_value(ucounts, type) > max)
346-
return true;
347+
long max = rlimit;
348+
if (rlimit > LONG_MAX)
349+
max = LONG_MAX;
347350
for (iter = ucounts; iter; iter = iter->ns->ucounts) {
348-
max = READ_ONCE(iter->ns->ucount_max[type]);
349351
if (get_ucounts_value(iter, type) > max)
350352
return true;
353+
max = READ_ONCE(iter->ns->ucount_max[type]);
351354
}
352355
return false;
353356
}

0 commit comments

Comments
 (0)