mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
dm-bufio: fix a race leading to an unsigned integer underflow
The function __scan tests "count - freed <= retain_target" and then sets
"atomic_long_set(&c->need_shrink, 0);" It exits with the condition "if
(!atomic_long_read(&c->need_shrink)) break;" It may be possible that
between these two statements, another thread sets &c->need_shrink to a
non-zero value. In this case, the function __scan continues and it may
possibly the "freed" variable is larger than the "count" variable. The
expression "count - freed" underflows and the function __scan will
continue to free all the buffers, even those that are below
retain_target.
Fix this bug by immediatelly exiting if we set
"atomic_long_set(&c->need_shrink, 0)"; and don't attempt to re-read
c->need_shrink afterwards.
Fixes: 450e8dee51 ("dm bufio: improve concurrent IO performance")
Cc: stable@vger.kernel.org
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Assisted-by: Claude:claude-opus-5
This commit is contained in:
parent
1190dbeaea
commit
005d2ec572
|
|
@ -2426,8 +2426,10 @@ static void __scan(struct dm_bufio_client *c)
|
|||
|
||||
for (l = 0; l < LIST_SIZE; l++) {
|
||||
while (true) {
|
||||
if (count - freed <= retain_target)
|
||||
if (count - freed <= retain_target) {
|
||||
atomic_long_set(&c->need_shrink, 0);
|
||||
break;
|
||||
}
|
||||
if (!atomic_long_read(&c->need_shrink))
|
||||
break;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user