netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] net/sched: taprio: fix slab-out-of-bounds Read in taprio_dequeue_from_txq
@ 2023-06-06 12:10 Zhengchao Shao
  2023-06-06 15:10 ` Pedro Tammela
  0 siblings, 1 reply; 6+ messages in thread
From: Zhengchao Shao @ 2023-06-06 12:10 UTC (permalink / raw)
  To: netdev, vinicius.gomes, jhs, xiyou.wangcong, jiri, davem,
	edumazet, kuba, pabeni
  Cc: vladimir.oltean, weiyongjun1, yuehaibing, shaozhengchao

As shown in [1], when qdisc of the taprio type is set, count and offset in
tc_to_txq can be set to 0. In this case, the value of *txq in
taprio_next_tc_txq() will increases continuously. When the number of
accessed queues exceeds the number of queues on the device, out-of-bounds
access occurs. Now the restriction on the queue number is added.

[1] https://groups.google.com/g/syzkaller-bugs/c/_lYOKgkBVMg
Fixes: 2f530df76c8c ("net/sched: taprio: give higher priority to higher TCs in software dequeue mode")
Reported-by: syzbot+04afcb3d2c840447559a@syzkaller.appspotmail.com
Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
---
 net/sched/sch_taprio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index 3c4c2c334878..dccb64425852 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -801,7 +801,7 @@ static struct sk_buff *taprio_dequeue_tc_priority(struct Qdisc *sch,
 
 			if (skb)
 				return skb;
-		} while (q->cur_txq[tc] != first_txq);
+		} while (q->cur_txq[tc] != first_txq && q->cur_txq[tc] < dev->num_tx_queues);
 	}
 
 	return NULL;
-- 
2.34.1


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

* Re: [PATCH net] net/sched: taprio: fix slab-out-of-bounds Read in taprio_dequeue_from_txq
  2023-06-06 12:10 [PATCH net] net/sched: taprio: fix slab-out-of-bounds Read in taprio_dequeue_from_txq Zhengchao Shao
@ 2023-06-06 15:10 ` Pedro Tammela
  2023-06-07  1:15   ` shaozhengchao
  0 siblings, 1 reply; 6+ messages in thread
From: Pedro Tammela @ 2023-06-06 15:10 UTC (permalink / raw)
  To: Zhengchao Shao, netdev, vinicius.gomes, jhs, xiyou.wangcong,
	jiri, davem, edumazet, kuba, pabeni
  Cc: vladimir.oltean, weiyongjun1, yuehaibing

On 06/06/2023 09:10, Zhengchao Shao wrote:
> As shown in [1], when qdisc of the taprio type is set, count and offset in
> tc_to_txq can be set to 0. In this case, the value of *txq in
> taprio_next_tc_txq() will increases continuously. When the number of
> accessed queues exceeds the number of queues on the device, out-of-bounds
> access occurs. Now the restriction on the queue number is added.
> 
> [1] https://groups.google.com/g/syzkaller-bugs/c/_lYOKgkBVMg
> Fixes: 2f530df76c8c ("net/sched: taprio: give higher priority to higher TCs in software dequeue mode")
> Reported-by: syzbot+04afcb3d2c840447559a@syzkaller.appspotmail.com
> Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
> ---
>   net/sched/sch_taprio.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
> index 3c4c2c334878..dccb64425852 100644
> --- a/net/sched/sch_taprio.c
> +++ b/net/sched/sch_taprio.c
> @@ -801,7 +801,7 @@ static struct sk_buff *taprio_dequeue_tc_priority(struct Qdisc *sch,
>   
>   			if (skb)
>   				return skb;
> -		} while (q->cur_txq[tc] != first_txq);
> +		} while (q->cur_txq[tc] != first_txq && q->cur_txq[tc] < dev->num_tx_queues);

I'm not sure this is the correct fix.
If q->cur_txg[tc] == dev->num_tx_queues the next call to 
taprio_dequeue_tc_priority() for the same tc index will have
first_txq set to dev->num_tx_queues (no wrap around to first_txq happens).
If count and offset are 0 it will increment q->cur_txg[tc] and then bail 
on the while condition but still growing unbounded (just slower than 
before).

>   	}
>   taprio_dequeue_tc_priority
>   	return NULL;


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

* Re: [PATCH net] net/sched: taprio: fix slab-out-of-bounds Read in taprio_dequeue_from_txq
  2023-06-06 15:10 ` Pedro Tammela
@ 2023-06-07  1:15   ` shaozhengchao
  2023-06-07  1:38     ` shaozhengchao
  2023-06-07 19:05     ` Vinicius Costa Gomes
  0 siblings, 2 replies; 6+ messages in thread
From: shaozhengchao @ 2023-06-07  1:15 UTC (permalink / raw)
  To: Pedro Tammela, netdev, vinicius.gomes, jhs, xiyou.wangcong, jiri,
	davem, edumazet, kuba, pabeni
  Cc: vladimir.oltean, weiyongjun1, yuehaibing


On 2023/6/6 23:10, Pedro Tammela wrote:
> On 06/06/2023 09:10, Zhengchao Shao wrote:
>> As shown in [1], when qdisc of the taprio type is set, count and 
>> offset in
>> tc_to_txq can be set to 0. In this case, the value of *txq in
>> taprio_next_tc_txq() will increases continuously. When the number of
>> accessed queues exceeds the number of queues on the device, out-of-bounds
>> access occurs. Now the restriction on the queue number is added.
>>
>> [1] https://groups.google.com/g/syzkaller-bugs/c/_lYOKgkBVMg
>> Fixes: 2f530df76c8c ("net/sched: taprio: give higher priority to 
>> higher TCs in software dequeue mode")
>> Reported-by: syzbot+04afcb3d2c840447559a@syzkaller.appspotmail.com
>> Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
>> ---
>>   net/sched/sch_taprio.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
>> index 3c4c2c334878..dccb64425852 100644
>> --- a/net/sched/sch_taprio.c
>> +++ b/net/sched/sch_taprio.c
>> @@ -801,7 +801,7 @@ static struct sk_buff 
>> *taprio_dequeue_tc_priority(struct Qdisc *sch,
>>               if (skb)
>>                   return skb;
>> -        } while (q->cur_txq[tc] != first_txq);
>> +        } while (q->cur_txq[tc] != first_txq && q->cur_txq[tc] < 
>> dev->num_tx_queues);
> 
Hi Pedro:
	Thank you for youe reply.
> I'm not sure this is the correct fix.
> If q->cur_txg[tc] == dev->num_tx_queues the next call to 
> taprio_dequeue_tc_priority() for the same tc index will have
> first_txq set to dev->num_tx_queues (no wrap around to first_txq happens).
yes, maybe the same problem will occur at the next dequeue skb. It can
be changed to the following:
			taprio_next_tc_txq(dev, tc, &q->cur_txq[tc]);

+                       if (q->cur_txq[tc] == dev->num_tx_queues)
+                               q->cur_txq[tc] = first_txq;
+
                         if (skb)
                                 return skb;
                 } while (q->cur_txq[tc] != first_txq);
However, I prefer to limit the value of count in taprio_change(), so 
that I don't add extra judgment to the data path.

Hi Vinicius,
	Do you have any better suggestions?
> If count and offset are 0 it will increment q->cur_txg[tc] and then bail 
> on the while condition but still growing unbounded (just slower than 
> before).
> 
>>       }
>>   taprio_dequeue_tc_priority
>>       return NULL;
> 
> 

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

* Re: [PATCH net] net/sched: taprio: fix slab-out-of-bounds Read in taprio_dequeue_from_txq
  2023-06-07  1:15   ` shaozhengchao
@ 2023-06-07  1:38     ` shaozhengchao
  2023-06-07 19:05     ` Vinicius Costa Gomes
  1 sibling, 0 replies; 6+ messages in thread
From: shaozhengchao @ 2023-06-07  1:38 UTC (permalink / raw)
  To: netdev, vinicius.gomes, jhs, xiyou.wangcong, jiri, davem,
	edumazet, kuba, pabeni
  Cc: vladimir.oltean, weiyongjun1, yuehaibing, Pedro Tammela


Hi vinicius,jamal:
	Based on this question, I'm also thinking about whether it's
appropriate to set the tc parameter for dev in taprio_change. The
taprio_change maybe will fail and .graft() will not be invoked to make
qdisc take effect. However, the tc parameter of dev has been modified,
which seems to be incorrect when dequeuing packets. I think the tc
parameter of dev should be configured in .graft() so that the new qdisc
and tc parameters of dev can take effect together. Thank you.
	
Zhengchao Shao

On 2023/6/7 9:15, shaozhengchao wrote:
> 
> On 2023/6/6 23:10, Pedro Tammela wrote:
>> On 06/06/2023 09:10, Zhengchao Shao wrote:
>>> As shown in [1], when qdisc of the taprio type is set, count and 
>>> offset in
>>> tc_to_txq can be set to 0. In this case, the value of *txq in
>>> taprio_next_tc_txq() will increases continuously. When the number of
>>> accessed queues exceeds the number of queues on the device, 
>>> out-of-bounds
>>> access occurs. Now the restriction on the queue number is added.
>>>
>>> [1] https://groups.google.com/g/syzkaller-bugs/c/_lYOKgkBVMg
>>> Fixes: 2f530df76c8c ("net/sched: taprio: give higher priority to 
>>> higher TCs in software dequeue mode")
>>> Reported-by: syzbot+04afcb3d2c840447559a@syzkaller.appspotmail.com
>>> Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
>>> ---
>>>   net/sched/sch_taprio.c | 2 +-
>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
>>> index 3c4c2c334878..dccb64425852 100644
>>> --- a/net/sched/sch_taprio.c
>>> +++ b/net/sched/sch_taprio.c
>>> @@ -801,7 +801,7 @@ static struct sk_buff 
>>> *taprio_dequeue_tc_priority(struct Qdisc *sch,
>>>               if (skb)
>>>                   return skb;
>>> -        } while (q->cur_txq[tc] != first_txq);
>>> +        } while (q->cur_txq[tc] != first_txq && q->cur_txq[tc] < 
>>> dev->num_tx_queues);
>>
> Hi Pedro:
>      Thank you for youe reply.
>> I'm not sure this is the correct fix.
>> If q->cur_txg[tc] == dev->num_tx_queues the next call to 
>> taprio_dequeue_tc_priority() for the same tc index will have
>> first_txq set to dev->num_tx_queues (no wrap around to first_txq 
>> happens).
> yes, maybe the same problem will occur at the next dequeue skb. It can
> be changed to the following:
>              taprio_next_tc_txq(dev, tc, &q->cur_txq[tc]);
> 
> +                       if (q->cur_txq[tc] == dev->num_tx_queues)
> +                               q->cur_txq[tc] = first_txq;
> +
>                          if (skb)
>                                  return skb;
>                  } while (q->cur_txq[tc] != first_txq);
> However, I prefer to limit the value of count in taprio_change(), so 
> that I don't add extra judgment to the data path.
> 
> Hi Vinicius,
>      Do you have any better suggestions?
>> If count and offset are 0 it will increment q->cur_txg[tc] and then 
>> bail on the while condition but still growing unbounded (just slower 
>> than before).
>>
>>>       }
>>>   taprio_dequeue_tc_priority
>>>       return NULL;
>>
>>

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

* Re: [PATCH net] net/sched: taprio: fix slab-out-of-bounds Read in taprio_dequeue_from_txq
  2023-06-07  1:15   ` shaozhengchao
  2023-06-07  1:38     ` shaozhengchao
@ 2023-06-07 19:05     ` Vinicius Costa Gomes
  2023-06-08  2:06       ` shaozhengchao
  1 sibling, 1 reply; 6+ messages in thread
From: Vinicius Costa Gomes @ 2023-06-07 19:05 UTC (permalink / raw)
  To: shaozhengchao, Pedro Tammela, netdev, jhs, xiyou.wangcong, jiri,
	davem, edumazet, kuba, pabeni
  Cc: vladimir.oltean, weiyongjun1, yuehaibing

shaozhengchao <shaozhengchao@huawei.com> writes:

> On 2023/6/6 23:10, Pedro Tammela wrote:
>> On 06/06/2023 09:10, Zhengchao Shao wrote:
>>> As shown in [1], when qdisc of the taprio type is set, count and 
>>> offset in
>>> tc_to_txq can be set to 0. In this case, the value of *txq in
>>> taprio_next_tc_txq() will increases continuously. When the number of
>>> accessed queues exceeds the number of queues on the device, out-of-bounds
>>> access occurs. Now the restriction on the queue number is added.
>>>
>>> [1] https://groups.google.com/g/syzkaller-bugs/c/_lYOKgkBVMg
>>> Fixes: 2f530df76c8c ("net/sched: taprio: give higher priority to 
>>> higher TCs in software dequeue mode")
>>> Reported-by: syzbot+04afcb3d2c840447559a@syzkaller.appspotmail.com
>>> Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
>>> ---
>>>   net/sched/sch_taprio.c | 2 +-
>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
>>> index 3c4c2c334878..dccb64425852 100644
>>> --- a/net/sched/sch_taprio.c
>>> +++ b/net/sched/sch_taprio.c
>>> @@ -801,7 +801,7 @@ static struct sk_buff 
>>> *taprio_dequeue_tc_priority(struct Qdisc *sch,
>>>               if (skb)
>>>                   return skb;
>>> -        } while (q->cur_txq[tc] != first_txq);
>>> +        } while (q->cur_txq[tc] != first_txq && q->cur_txq[tc] < 
>>> dev->num_tx_queues);
>> 
> Hi Pedro:
> 	Thank you for youe reply.
>> I'm not sure this is the correct fix.
>> If q->cur_txg[tc] == dev->num_tx_queues the next call to 
>> taprio_dequeue_tc_priority() for the same tc index will have
>> first_txq set to dev->num_tx_queues (no wrap around to first_txq happens).
> yes, maybe the same problem will occur at the next dequeue skb. It can
> be changed to the following:
> 			taprio_next_tc_txq(dev, tc, &q->cur_txq[tc]);
>
> +                       if (q->cur_txq[tc] == dev->num_tx_queues)
> +                               q->cur_txq[tc] = first_txq;
> +
>                          if (skb)
>                                  return skb;
>                  } while (q->cur_txq[tc] != first_txq);
> However, I prefer to limit the value of count in taprio_change(), so 
> that I don't add extra judgment to the data path.
>
> Hi Vinicius,
> 	Do you have any better suggestions?

From a very quick look at the syzkaller report, I couldn't come up with
a config to trigger the issue.

But reading your report, the problematic case is having a bunch of
'0@0' in the "queues" map in the config, right?

A '0@0' would mean, in my opinion, that the user wants that a specific
TC to not have any queues associated with it, i.e. that it should be
ignored. Either that, or a configuration error.

Am I missing something?

>> If count and offset are 0 it will increment q->cur_txg[tc] and then bail 
>> on the while condition but still growing unbounded (just slower than 
>> before).
>> 
>>>       }
>>>   taprio_dequeue_tc_priority
>>>       return NULL;
>> 
>> 

-- 
Vinicius

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

* Re: [PATCH net] net/sched: taprio: fix slab-out-of-bounds Read in taprio_dequeue_from_txq
  2023-06-07 19:05     ` Vinicius Costa Gomes
@ 2023-06-08  2:06       ` shaozhengchao
  0 siblings, 0 replies; 6+ messages in thread
From: shaozhengchao @ 2023-06-08  2:06 UTC (permalink / raw)
  To: Vinicius Costa Gomes, Pedro Tammela, netdev, jhs, xiyou.wangcong,
	jiri, davem, edumazet, kuba, pabeni
  Cc: vladimir.oltean, weiyongjun1, yuehaibing



On 2023/6/8 3:05, Vinicius Costa Gomes wrote:
> shaozhengchao <shaozhengchao@huawei.com> writes:
> 
>> On 2023/6/6 23:10, Pedro Tammela wrote:
>>> On 06/06/2023 09:10, Zhengchao Shao wrote:
>>>> As shown in [1], when qdisc of the taprio type is set, count and
>>>> offset in
>>>> tc_to_txq can be set to 0. In this case, the value of *txq in
>>>> taprio_next_tc_txq() will increases continuously. When the number of
>>>> accessed queues exceeds the number of queues on the device, out-of-bounds
>>>> access occurs. Now the restriction on the queue number is added.
>>>>
>>>> [1] https://groups.google.com/g/syzkaller-bugs/c/_lYOKgkBVMg
>>>> Fixes: 2f530df76c8c ("net/sched: taprio: give higher priority to
>>>> higher TCs in software dequeue mode")
>>>> Reported-by: syzbot+04afcb3d2c840447559a@syzkaller.appspotmail.com
>>>> Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
>>>> ---
>>>>    net/sched/sch_taprio.c | 2 +-
>>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
>>>> index 3c4c2c334878..dccb64425852 100644
>>>> --- a/net/sched/sch_taprio.c
>>>> +++ b/net/sched/sch_taprio.c
>>>> @@ -801,7 +801,7 @@ static struct sk_buff
>>>> *taprio_dequeue_tc_priority(struct Qdisc *sch,
>>>>                if (skb)
>>>>                    return skb;
>>>> -        } while (q->cur_txq[tc] != first_txq);
>>>> +        } while (q->cur_txq[tc] != first_txq && q->cur_txq[tc] <
>>>> dev->num_tx_queues);
>>>
>> Hi Pedro:
>> 	Thank you for youe reply.
>>> I'm not sure this is the correct fix.
>>> If q->cur_txg[tc] == dev->num_tx_queues the next call to
>>> taprio_dequeue_tc_priority() for the same tc index will have
>>> first_txq set to dev->num_tx_queues (no wrap around to first_txq happens).
>> yes, maybe the same problem will occur at the next dequeue skb. It can
>> be changed to the following:
>> 			taprio_next_tc_txq(dev, tc, &q->cur_txq[tc]);
>>
>> +                       if (q->cur_txq[tc] == dev->num_tx_queues)
>> +                               q->cur_txq[tc] = first_txq;
>> +
>>                           if (skb)
>>                                   return skb;
>>                   } while (q->cur_txq[tc] != first_txq);
>> However, I prefer to limit the value of count in taprio_change(), so
>> that I don't add extra judgment to the data path.
>>
>> Hi Vinicius,
>> 	Do you have any better suggestions?
> 

Hi Vinicius:
	Thank you for your reply.
>>From a very quick look at the syzkaller report, I couldn't come up with
> a config to trigger the issue.
> 
> But reading your report, the problematic case is having a bunch of
> '0@0' in the "queues" map in the config, right?
> 
Yes, it is right.
> A '0@0' would mean, in my opinion, that the user wants that a specific
> TC to not have any queues associated with it, i.e. that it should be
> ignored. Either that, or a configuration error.
> 

After verification, when the qdisc of the taprio type is used to replace
the previously configured taprio, the validity of count and offset is
not verified because tc may have been configured on the dev device.

Maybe the same issue to mqprio->num_tc? mqprio->num_tc will be set to
large than TC_MAX_QUEUE, this also will trigger out-of-bounds access in
taprio_change()?

> Am I missing something?

Zhengchao Shao
>>> If count and offset are 0 it will increment q->cur_txg[tc] and then bail
>>> on the while condition but still growing unbounded (just slower than
>>> before).
>>>
>>>>        }
>>>>    taprio_dequeue_tc_priority
>>>>        return NULL;
>>>
>>>
> 

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

end of thread, other threads:[~2023-06-08  2:06 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-06 12:10 [PATCH net] net/sched: taprio: fix slab-out-of-bounds Read in taprio_dequeue_from_txq Zhengchao Shao
2023-06-06 15:10 ` Pedro Tammela
2023-06-07  1:15   ` shaozhengchao
2023-06-07  1:38     ` shaozhengchao
2023-06-07 19:05     ` Vinicius Costa Gomes
2023-06-08  2:06       ` shaozhengchao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).