* [PATCH v1] mm: fix div by zero in bdi_ratio_from_pages
@ 2025-01-04 1:20 Stefan Roesch
2025-01-07 9:20 ` David Hildenbrand
0 siblings, 1 reply; 3+ messages in thread
From: Stefan Roesch @ 2025-01-04 1:20 UTC (permalink / raw)
To: willy, zzqq0103.hey, akpm, linux-mm, linux-fsdevel; +Cc: shr
During testing it has been detected, that it is possible to get div by
zero error in bdi_set_min_bytes. The error is caused by the function
bdi_ratio_from_pages(). bdi_ratio_from_pages() calls
global_dirty_limits. If the dirty threshold is 0, the div by zero is
raised. This can happen if the root user is setting:
echo 0 > /proc/sys/vm/dirty_ration.
The following is a test case:
echo 0 > /proc/sys/vm/dirty_ratio
cd /sys/class/bdi/<device>
echo 1 > strict_limit
echo 8192 > min_bytes
==> error is raised.
The problem is addressed by returning -EINVAL if dirty_ratio or
dirty_bytes is set to 0.
Reported-by: cheung wall <zzqq0103.hey@gmail.com>
Closes: https://lore.kernel.org/linux-mm/87pll35yd0.fsf@devkernel.io/T/#t
Signed-off-by: Stefan Roesch <shr@devkernel.io>
---
mm/page-writeback.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index d213ead95675..91aa7a5c0078 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -692,6 +692,8 @@ static unsigned long bdi_ratio_from_pages(unsigned long pages)
unsigned long ratio;
global_dirty_limits(&background_thresh, &dirty_thresh);
+ if (!dirty_thresh)
+ return -EINVAL;
ratio = div64_u64(pages * 100ULL * BDI_RATIO_SCALE, dirty_thresh);
return ratio;
base-commit: 0bc21e701a6ffacfdde7f04f87d664d82e8a13bf
--
2.47.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v1] mm: fix div by zero in bdi_ratio_from_pages
2025-01-04 1:20 [PATCH v1] mm: fix div by zero in bdi_ratio_from_pages Stefan Roesch
@ 2025-01-07 9:20 ` David Hildenbrand
2025-01-08 1:22 ` Stefan Roesch
0 siblings, 1 reply; 3+ messages in thread
From: David Hildenbrand @ 2025-01-07 9:20 UTC (permalink / raw)
To: Stefan Roesch, willy, zzqq0103.hey, akpm, linux-mm, linux-fsdevel
On 04.01.25 02:20, Stefan Roesch wrote:
> During testing it has been detected, that it is possible to get div by
> zero error in bdi_set_min_bytes. The error is caused by the function
> bdi_ratio_from_pages(). bdi_ratio_from_pages() calls
> global_dirty_limits. If the dirty threshold is 0, the div by zero is
> raised. This can happen if the root user is setting:
>
> echo 0 > /proc/sys/vm/dirty_ration.
>
> The following is a test case:
>
> echo 0 > /proc/sys/vm/dirty_ratio
> cd /sys/class/bdi/<device>
> echo 1 > strict_limit
> echo 8192 > min_bytes
>
> ==> error is raised.
>
> The problem is addressed by returning -EINVAL if dirty_ratio or
> dirty_bytes is set to 0.
>
> Reported-by: cheung wall <zzqq0103.hey@gmail.com>
> Closes: https://lore.kernel.org/linux-mm/87pll35yd0.fsf@devkernel.io/T/#t
> Signed-off-by: Stefan Roesch <shr@devkernel.io>
> ---
> mm/page-writeback.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/mm/page-writeback.c b/mm/page-writeback.c
> index d213ead95675..91aa7a5c0078 100644
> --- a/mm/page-writeback.c
> +++ b/mm/page-writeback.c
> @@ -692,6 +692,8 @@ static unsigned long bdi_ratio_from_pages(unsigned long pages)
> unsigned long ratio;
>
> global_dirty_limits(&background_thresh, &dirty_thresh);
> + if (!dirty_thresh)
> + return -EINVAL;
> ratio = div64_u64(pages * 100ULL * BDI_RATIO_SCALE, dirty_thresh);
>
> return ratio;
bdi_set_min_bytes() calls bdi_ratio_from_pages() and passes the result
to __bdi_set_min_ratio().
__bdi_set_min_ratio() expects an "unsigned int min_ratio". I assume this
will work because "max_ratio > 100 * BDI_RATIO_SCALE", but it is rather
confusing ...
Maybe we want something like:
/* Use 101% to indicate "invalid" */
#define BDI_RATIO_INVALID (101 * BDI_RATIO_SCALE)
Or alternatively, just handle it in the callers of
bdi_ratio_from_pages(), checking for -EINVAL manually.
--
Cheers,
David / dhildenb
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v1] mm: fix div by zero in bdi_ratio_from_pages
2025-01-07 9:20 ` David Hildenbrand
@ 2025-01-08 1:22 ` Stefan Roesch
0 siblings, 0 replies; 3+ messages in thread
From: Stefan Roesch @ 2025-01-08 1:22 UTC (permalink / raw)
To: David Hildenbrand; +Cc: willy, zzqq0103.hey, akpm, linux-mm, linux-fsdevel
David Hildenbrand <david@redhat.com> writes:
> On 04.01.25 02:20, Stefan Roesch wrote:
>> During testing it has been detected, that it is possible to get div by
>> zero error in bdi_set_min_bytes. The error is caused by the function
>> bdi_ratio_from_pages(). bdi_ratio_from_pages() calls
>> global_dirty_limits. If the dirty threshold is 0, the div by zero is
>> raised. This can happen if the root user is setting:
>> echo 0 > /proc/sys/vm/dirty_ration.
>> The following is a test case:
>> echo 0 > /proc/sys/vm/dirty_ratio
>> cd /sys/class/bdi/<device>
>> echo 1 > strict_limit
>> echo 8192 > min_bytes
>> ==> error is raised.
>> The problem is addressed by returning -EINVAL if dirty_ratio or
>> dirty_bytes is set to 0.
>> Reported-by: cheung wall <zzqq0103.hey@gmail.com>
>> Closes: https://lore.kernel.org/linux-mm/87pll35yd0.fsf@devkernel.io/T/#t
>> Signed-off-by: Stefan Roesch <shr@devkernel.io>
>> ---
>> mm/page-writeback.c | 2 ++
>> 1 file changed, 2 insertions(+)
>> diff --git a/mm/page-writeback.c b/mm/page-writeback.c
>> index d213ead95675..91aa7a5c0078 100644
>> --- a/mm/page-writeback.c
>> +++ b/mm/page-writeback.c
>> @@ -692,6 +692,8 @@ static unsigned long bdi_ratio_from_pages(unsigned long pages)
>> unsigned long ratio;
>> global_dirty_limits(&background_thresh, &dirty_thresh);
>> + if (!dirty_thresh)
>> + return -EINVAL;
>> ratio = div64_u64(pages * 100ULL * BDI_RATIO_SCALE, dirty_thresh);
>> return ratio;
>
> bdi_set_min_bytes() calls bdi_ratio_from_pages() and passes the result to
> __bdi_set_min_ratio().
>
> __bdi_set_min_ratio() expects an "unsigned int min_ratio". I assume this will
> work because "max_ratio > 100 * BDI_RATIO_SCALE", but it is rather confusing ...
>
> Maybe we want something like:
>
> /* Use 101% to indicate "invalid" */
> #define BDI_RATIO_INVALID (101 * BDI_RATIO_SCALE)
>
> Or alternatively, just handle it in the callers of bdi_ratio_from_pages(),
> checking for -EINVAL manually.
David, I prefer the second option, its a bit easier to follow.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-01-08 1:23 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-01-04 1:20 [PATCH v1] mm: fix div by zero in bdi_ratio_from_pages Stefan Roesch
2025-01-07 9:20 ` David Hildenbrand
2025-01-08 1:22 ` Stefan Roesch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox