Thread (8 messages) flat view 8 messages, 4 authors, 2021-08-30

Re: [PATCH] net:sched fix array-index-out-of-bounds in taprio_change

From: Pavel Skripkin <hidden>
Date: 2021-08-11 08:30:15

On 8/11/21 10:44 AM, Eric Dumazet wrote:

On 8/11/21 7:10 AM, tcs.kernel@gmail.com wrote:
quoted
From: Haimin Zhang <redacted>

syzbot report an array-index-out-of-bounds in taprio_change
index 16 is out of range for type '__u16 [16]'
that's because mqprio->num_tc is lager than TC_MAX_QUEUE,so we check
the return value of netdev_set_num_tc.

Reported-by: syzbot+2b3e5fb6c7ef285a94f6@syzkaller.appspotmail.com
Signed-off-by: Haimin Zhang <redacted>
---
 net/sched/sch_taprio.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index 9c79374..1ab2fc9 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -1513,7 +1513,9 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
 	taprio_set_picos_per_byte(dev, q);
 
 	if (mqprio) {
-		netdev_set_num_tc(dev, mqprio->num_tc);
+		err = netdev_set_num_tc(dev, mqprio->num_tc);
+		if (err)
+			goto free_sched;
 		for (i = 0; i < mqprio->num_tc; i++)
 			netdev_set_tc_queue(dev, i,
 					    mqprio->count[i],
When was the bug added ?

Hint: Please provide a Fixes: tag

taprio_parse_mqprio_opt() already checks :

/* Verify num_tc is not out of max range */
if (qopt->num_tc > TC_MAX_QUEUE) {
     NL_SET_ERR_MSG(extack, "Number of traffic classes is outside valid range");
     return -EINVAL;
}

So what is happening exactly ?
Hi, Eric!

I've looked into this bug, but I decided to write a reproducer for it 
first. Unfortunately, I didn't finish it yesterday, but I have an idea 
about what happened:

taprio_parse_mqprio_opt() may return 0 before qopt->num_tc check:

	/* If num_tc is already set, it means that the user already
	 * configured the mqprio part
	 */
	if (dev->num_tc)
		return 0;

Then taprio_mqprio_cmp() fails here:

	if (!mqprio || mqprio->num_tc != dev->num_tc)
		return -1;

That's why we won't get shift-out-of-bound in taprio_mqprio_cmp().

And finally taprio_change() gets to buggy for with wrong mqprio->num_tc.
I don't know how to reproduce it, but I'll try to finish my reproducer 
this evening.


Does above makes any sense?



With regards,
Pavel Skripkin
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help