Re: [PATCH v2 2/2] time/jiffies: Saturate in mult_hz() instead of wrapping

From: Joel Granados

Date: Tue Sep 29 2026 - 04:15:25 EST


On Mon, Sep 28, 2026 at 10:02:05AM +0800, Zhan Xusheng wrote:
> mult_hz() converts a user-supplied seconds value to jiffies for
> proc_dointvec_jiffies(). proc_int_u2k_conv_uop() rejects a result above
> INT_MAX, but it inspects the product, so a product that wraps arrives as a
> small value and is stored.
>
> The input has to exceed ULONG_MAX / HZ for the product to wrap, so the
> value below is specific to CONFIG_HZ=1000:
>
> # echo 18446744073709552 > /proc/sys/net/ipv4/tcp_keepalive_time
> # cat /proc/sys/net/ipv4/tcp_keepalive_time
> 0
>
> 18446744073709551, one less, is correctly rejected. Dozens of sysctls
> use proc_dointvec_jiffies(), among them tcp_keepalive_time,
> tcp_fin_timeout and the conntrack timeouts.
>
> Bound the input in the shape clock_t_to_jiffies() already uses and leave
> the INT_MAX policy to the caller. The bound was open-coded as
> "*lvalp > INT_MAX / HZ" until commit 2dc164a48e6f ("sysctl: Create
Not sure where this came from, but it is not in 2dc164a48e6f.

> converter functions with two new macros").
>
> Fixes: 2dc164a48e6f ("sysctl: Create converter functions with two new macros")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Zhan Xusheng <zhanxusheng@xxxxxxxxxx>
> ---
> kernel/time/jiffies.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
> index 80c354811538..9b3487d40cd6 100644
> --- a/kernel/time/jiffies.c
> +++ b/kernel/time/jiffies.c
> @@ -101,6 +101,8 @@ void __init register_refined_jiffies(long cycles_per_second)
> #ifdef CONFIG_SYSCTL
> static ulong mult_hz(const ulong val)
> {
> + if (val >= ULONG_MAX / HZ)
> + return ULONG_MAX;
> return val * HZ;
> }
>
> --
> 2.43.0
>

I'm going to push the fix as is with a modified commit :

time/jiffies: Saturate in mult_hz() instead of wrapping

Return ULONG_MAX for values that don't fit an unsigned long.
proc_int_u2k_conv_uop() now correctly rejects a result above INT_MAX.

This is the erroneous behaviour that is being fixed. The input has to
exceed ULONG_MAX / HZ for the product to wrap, so the value below is
specific to CONFIG_HZ=1000:

# echo 18446744073709552 > /proc/sys/net/ipv4/tcp_keepalive_time
# cat /proc/sys/net/ipv4/tcp_keepalive_time
0

That value is now rejected with an error.

The original bound ("*u_ptr > INT_MAX / HZ") was removed in commit
2dc164a48e6f ("sysctl: Create converter functions with two new macros").


Thx for the patch

Best

Attachment: signature.asc
Description: PGP signature