public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net v3 1/2] net/sched: sch_hfsc: fix divide-by-zero in rtsc_min()
@ 2026-03-26 20:43 Xiang Mei
  2026-03-26 20:43 ` [PATCH net v3 2/2] selftests/tc-testing: add test for HFSC " Xiang Mei
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Xiang Mei @ 2026-03-26 20:43 UTC (permalink / raw)
  To: security
  Cc: netdev, pabeni, jhs, jiri, davem, edumazet, kuba, horms,
	bestswngs, Xiang Mei

m2sm() converts a u32 slope to a u64 scaled value.  For large inputs
(e.g. m1=4000000000), the result can reach 2^32.  rtsc_min() stores
the difference of two such u64 values in a u32 variable `dsm` and
uses it as a divisor.  When the difference is exactly 2^32 the
truncation yields zero, causing a divide-by-zero oops in the
concave-curve intersection path:

  Oops: divide error: 0000
  RIP: 0010:rtsc_min (net/sched/sch_hfsc.c:601)
  Call Trace:
   init_ed (net/sched/sch_hfsc.c:629)
   hfsc_enqueue (net/sched/sch_hfsc.c:1569)
   [...]

Widen `dsm` to u64 and replace do_div() with div64_u64() so the full
difference is preserved.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Xiang Mei <xmei5@asu.edu>
---
v2: resend to netdev ML
v3: append selftest in 2/2
 
 net/sched/sch_hfsc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index b5657ffbbf84..83b2ca2e37fc 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -555,7 +555,7 @@ static void
 rtsc_min(struct runtime_sc *rtsc, struct internal_sc *isc, u64 x, u64 y)
 {
 	u64 y1, y2, dx, dy;
-	u32 dsm;
+	u64 dsm;
 
 	if (isc->sm1 <= isc->sm2) {
 		/* service curve is convex */
@@ -598,7 +598,7 @@ rtsc_min(struct runtime_sc *rtsc, struct internal_sc *isc, u64 x, u64 y)
 	 */
 	dx = (y1 - y) << SM_SHIFT;
 	dsm = isc->sm1 - isc->sm2;
-	do_div(dx, dsm);
+	dx = div64_u64(dx, dsm);
 	/*
 	 * check if (x, y1) belongs to the 1st segment of rtsc.
 	 * if so, add the offset.
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net v3 2/2] selftests/tc-testing: add test for HFSC divide-by-zero in rtsc_min()
  2026-03-26 20:43 [PATCH net v3 1/2] net/sched: sch_hfsc: fix divide-by-zero in rtsc_min() Xiang Mei
@ 2026-03-26 20:43 ` Xiang Mei
  2026-03-27 14:02   ` Jamal Hadi Salim
  2026-03-27 14:03   ` Victor Nogueira
  2026-03-27 14:01 ` [PATCH net v3 1/2] net/sched: sch_hfsc: fix " Jamal Hadi Salim
  2026-03-28  3:50 ` patchwork-bot+netdevbpf
  2 siblings, 2 replies; 6+ messages in thread
From: Xiang Mei @ 2026-03-26 20:43 UTC (permalink / raw)
  To: security
  Cc: netdev, pabeni, jhs, jiri, davem, edumazet, kuba, horms,
	bestswngs, Xiang Mei

Add a regression test for the divide-by-zero in rtsc_min() triggered
when m2sm() converts a large m1 value (e.g. 32gbit) to a u64 scaled
slope reaching 2^32. rtsc_min() stores the difference of two such u64
values (sm1 - sm2) in a u32 variable `dsm`, truncating 2^32 to zero
and causing a divide-by-zero oops in the concave-curve intersection
path. The test configures an HFSC class with m1=32gbit d=1ms m2=0bit,
sends a packet to activate the class, waits for it to drain and go
idle, then sends another packet to trigger reactivation through
rtsc_min().

Signed-off-by: Xiang Mei <xmei5@asu.edu>
---
v3: append selftest in 2/2

 .../tc-testing/tc-tests/infra/qdiscs.json     | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json b/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json
index 6a39640aa2a8..1e5efb2a31eb 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json
@@ -1111,5 +1111,30 @@
         "teardown": [
             "$TC qdisc del dev $DUMMY root handle 1:"
         ]
+    },
+    {
+        "id": "a3d7",
+        "name": "HFSC with large m1 - no divide-by-zero on class reactivation",
+        "category": [
+            "qdisc",
+            "hfsc"
+        ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
+        "setup": [
+            "$TC qdisc replace dev $DUMMY root handle 1: hfsc default 1",
+            "$TC class replace dev $DUMMY parent 1: classid 1:1 hfsc rt m1 32gbit d 1ms m2 0bit ls m1 32gbit d 1ms m2 0bit",
+            "ping -I$DUMMY -f -c1 -s64 -W1 10.10.10.1 || true",
+            "sleep 1"
+        ],
+        "cmdUnderTest": "ping -I$DUMMY -f -c1 -s64 -W1 10.10.10.1 || true",
+        "expExitCode": "0",
+        "verifyCmd": "$TC qdisc show dev $DUMMY",
+        "matchPattern": "qdisc hfsc 1: root",
+        "matchCount": "1",
+        "teardown": [
+            "$TC qdisc del dev $DUMMY handle 1: root"
+        ]
     }
 ]
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH net v3 1/2] net/sched: sch_hfsc: fix divide-by-zero in rtsc_min()
  2026-03-26 20:43 [PATCH net v3 1/2] net/sched: sch_hfsc: fix divide-by-zero in rtsc_min() Xiang Mei
  2026-03-26 20:43 ` [PATCH net v3 2/2] selftests/tc-testing: add test for HFSC " Xiang Mei
@ 2026-03-27 14:01 ` Jamal Hadi Salim
  2026-03-28  3:50 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 6+ messages in thread
From: Jamal Hadi Salim @ 2026-03-27 14:01 UTC (permalink / raw)
  To: Xiang Mei
  Cc: security, netdev, pabeni, jiri, davem, edumazet, kuba, horms,
	bestswngs

On Thu, Mar 26, 2026 at 4:43 PM Xiang Mei <xmei5@asu.edu> wrote:
>
> m2sm() converts a u32 slope to a u64 scaled value.  For large inputs
> (e.g. m1=4000000000), the result can reach 2^32.  rtsc_min() stores
> the difference of two such u64 values in a u32 variable `dsm` and
> uses it as a divisor.  When the difference is exactly 2^32 the
> truncation yields zero, causing a divide-by-zero oops in the
> concave-curve intersection path:
>
>   Oops: divide error: 0000
>   RIP: 0010:rtsc_min (net/sched/sch_hfsc.c:601)
>   Call Trace:
>    init_ed (net/sched/sch_hfsc.c:629)
>    hfsc_enqueue (net/sched/sch_hfsc.c:1569)
>    [...]
>
> Widen `dsm` to u64 and replace do_div() with div64_u64() so the full
> difference is preserved.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Reported-by: Weiming Shi <bestswngs@gmail.com>
> Signed-off-by: Xiang Mei <xmei5@asu.edu>

Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>

cheers,
jamal
> ---
> v2: resend to netdev ML
> v3: append selftest in 2/2
>
>  net/sched/sch_hfsc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
> index b5657ffbbf84..83b2ca2e37fc 100644
> --- a/net/sched/sch_hfsc.c
> +++ b/net/sched/sch_hfsc.c
> @@ -555,7 +555,7 @@ static void
>  rtsc_min(struct runtime_sc *rtsc, struct internal_sc *isc, u64 x, u64 y)
>  {
>         u64 y1, y2, dx, dy;
> -       u32 dsm;
> +       u64 dsm;
>
>         if (isc->sm1 <= isc->sm2) {
>                 /* service curve is convex */
> @@ -598,7 +598,7 @@ rtsc_min(struct runtime_sc *rtsc, struct internal_sc *isc, u64 x, u64 y)
>          */
>         dx = (y1 - y) << SM_SHIFT;
>         dsm = isc->sm1 - isc->sm2;
> -       do_div(dx, dsm);
> +       dx = div64_u64(dx, dsm);
>         /*
>          * check if (x, y1) belongs to the 1st segment of rtsc.
>          * if so, add the offset.
> --
> 2.43.0
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net v3 2/2] selftests/tc-testing: add test for HFSC divide-by-zero in rtsc_min()
  2026-03-26 20:43 ` [PATCH net v3 2/2] selftests/tc-testing: add test for HFSC " Xiang Mei
@ 2026-03-27 14:02   ` Jamal Hadi Salim
  2026-03-27 14:03   ` Victor Nogueira
  1 sibling, 0 replies; 6+ messages in thread
From: Jamal Hadi Salim @ 2026-03-27 14:02 UTC (permalink / raw)
  To: Xiang Mei
  Cc: security, netdev, pabeni, jiri, davem, edumazet, kuba, horms,
	bestswngs

On Thu, Mar 26, 2026 at 4:43 PM Xiang Mei <xmei5@asu.edu> wrote:
>
> Add a regression test for the divide-by-zero in rtsc_min() triggered
> when m2sm() converts a large m1 value (e.g. 32gbit) to a u64 scaled
> slope reaching 2^32. rtsc_min() stores the difference of two such u64
> values (sm1 - sm2) in a u32 variable `dsm`, truncating 2^32 to zero
> and causing a divide-by-zero oops in the concave-curve intersection
> path. The test configures an HFSC class with m1=32gbit d=1ms m2=0bit,
> sends a packet to activate the class, waits for it to drain and go
> idle, then sends another packet to trigger reactivation through
> rtsc_min().
>
> Signed-off-by: Xiang Mei <xmei5@asu.edu>

Thanks for doing this.

Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>

cheers,
jamal

> ---
> v3: append selftest in 2/2
>
>  .../tc-testing/tc-tests/infra/qdiscs.json     | 25 +++++++++++++++++++
>  1 file changed, 25 insertions(+)
>
> diff --git a/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json b/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json
> index 6a39640aa2a8..1e5efb2a31eb 100644
> --- a/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json
> +++ b/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json
> @@ -1111,5 +1111,30 @@
>          "teardown": [
>              "$TC qdisc del dev $DUMMY root handle 1:"
>          ]
> +    },
> +    {
> +        "id": "a3d7",
> +        "name": "HFSC with large m1 - no divide-by-zero on class reactivation",
> +        "category": [
> +            "qdisc",
> +            "hfsc"
> +        ],
> +        "plugins": {
> +            "requires": "nsPlugin"
> +        },
> +        "setup": [
> +            "$TC qdisc replace dev $DUMMY root handle 1: hfsc default 1",
> +            "$TC class replace dev $DUMMY parent 1: classid 1:1 hfsc rt m1 32gbit d 1ms m2 0bit ls m1 32gbit d 1ms m2 0bit",
> +            "ping -I$DUMMY -f -c1 -s64 -W1 10.10.10.1 || true",
> +            "sleep 1"
> +        ],
> +        "cmdUnderTest": "ping -I$DUMMY -f -c1 -s64 -W1 10.10.10.1 || true",
> +        "expExitCode": "0",
> +        "verifyCmd": "$TC qdisc show dev $DUMMY",
> +        "matchPattern": "qdisc hfsc 1: root",
> +        "matchCount": "1",
> +        "teardown": [
> +            "$TC qdisc del dev $DUMMY handle 1: root"
> +        ]
>      }
>  ]
> --
> 2.43.0
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net v3 2/2] selftests/tc-testing: add test for HFSC divide-by-zero in rtsc_min()
  2026-03-26 20:43 ` [PATCH net v3 2/2] selftests/tc-testing: add test for HFSC " Xiang Mei
  2026-03-27 14:02   ` Jamal Hadi Salim
@ 2026-03-27 14:03   ` Victor Nogueira
  1 sibling, 0 replies; 6+ messages in thread
From: Victor Nogueira @ 2026-03-27 14:03 UTC (permalink / raw)
  To: Xiang Mei, security
  Cc: netdev, pabeni, jhs, jiri, davem, edumazet, kuba, horms,
	bestswngs

On 26/03/2026 17:43, Xiang Mei wrote:
> Add a regression test for the divide-by-zero in rtsc_min() triggered
> when m2sm() converts a large m1 value (e.g. 32gbit) to a u64 scaled
> slope reaching 2^32. rtsc_min() stores the difference of two such u64
> values (sm1 - sm2) in a u32 variable `dsm`, truncating 2^32 to zero
> and causing a divide-by-zero oops in the concave-curve intersection
> path. The test configures an HFSC class with m1=32gbit d=1ms m2=0bit,
> sends a packet to activate the class, waits for it to drain and go
> idle, then sends another packet to trigger reactivation through
> rtsc_min().
> 
> Signed-off-by: Xiang Mei <xmei5@asu.edu>

Reviewed-by: Victor Nogueira <victor@mojatatu.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net v3 1/2] net/sched: sch_hfsc: fix divide-by-zero in rtsc_min()
  2026-03-26 20:43 [PATCH net v3 1/2] net/sched: sch_hfsc: fix divide-by-zero in rtsc_min() Xiang Mei
  2026-03-26 20:43 ` [PATCH net v3 2/2] selftests/tc-testing: add test for HFSC " Xiang Mei
  2026-03-27 14:01 ` [PATCH net v3 1/2] net/sched: sch_hfsc: fix " Jamal Hadi Salim
@ 2026-03-28  3:50 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-03-28  3:50 UTC (permalink / raw)
  To: Xiang Mei
  Cc: security, netdev, pabeni, jhs, jiri, davem, edumazet, kuba, horms,
	bestswngs

Hello:

This series was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Thu, 26 Mar 2026 13:43:09 -0700 you wrote:
> m2sm() converts a u32 slope to a u64 scaled value.  For large inputs
> (e.g. m1=4000000000), the result can reach 2^32.  rtsc_min() stores
> the difference of two such u64 values in a u32 variable `dsm` and
> uses it as a divisor.  When the difference is exactly 2^32 the
> truncation yields zero, causing a divide-by-zero oops in the
> concave-curve intersection path:
> 
> [...]

Here is the summary with links:
  - [net,v3,1/2] net/sched: sch_hfsc: fix divide-by-zero in rtsc_min()
    https://git.kernel.org/netdev/net/c/4576100b8cd0
  - [net,v3,2/2] selftests/tc-testing: add test for HFSC divide-by-zero in rtsc_min()
    https://git.kernel.org/netdev/net/c/5d17af9eb2dd

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-03-28  3:50 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-26 20:43 [PATCH net v3 1/2] net/sched: sch_hfsc: fix divide-by-zero in rtsc_min() Xiang Mei
2026-03-26 20:43 ` [PATCH net v3 2/2] selftests/tc-testing: add test for HFSC " Xiang Mei
2026-03-27 14:02   ` Jamal Hadi Salim
2026-03-27 14:03   ` Victor Nogueira
2026-03-27 14:01 ` [PATCH net v3 1/2] net/sched: sch_hfsc: fix " Jamal Hadi Salim
2026-03-28  3:50 ` patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox