[v3,1/2] Make loop indexes unsigned

Message ID 20230927164715.76744-2-joao@overdrivepizza.com
State New
Headers
Series Prevent potential write out of bounds |

Commit Message

Joao Moreira Sept. 27, 2023, 4:47 p.m. UTC
  From: Joao Moreira <joao.moreira@intel.com>

Both flow_rule_alloc and offload_action_alloc functions received an
unsigned num_actions parameters which are then operated within a loop.
The index of this loop is declared as a signed int. If it was possible
to pass a large enough num_actions to these functions, it would lead to
an out of bounds write.

After checking with maintainers, it was mentioned that front-end will
cap the num_actions value and that it is not possible to reach this
function with such a large number. Yet, for correctness, it is still
better to fix this.

This issue was observed by the commit author while reviewing a write-up
regarding a CVE within the same subsystem [1].

1 - https://nickgregory.me/post/2022/03/12/cve-2022-25636/

Signed-off-by: Joao Moreira <joao.moreira@intel.com>
---
 net/core/flow_offload.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
  

Comments

Pablo Neira Ayuso Sept. 28, 2023, 1:40 p.m. UTC | #1
On Wed, Sep 27, 2023 at 09:47:14AM -0700, joao@overdrivepizza.com wrote:
> From: Joao Moreira <joao.moreira@intel.com>
> 
> Both flow_rule_alloc and offload_action_alloc functions received an
> unsigned num_actions parameters which are then operated within a loop.
> The index of this loop is declared as a signed int. If it was possible
> to pass a large enough num_actions to these functions, it would lead to
> an out of bounds write.
> 
> After checking with maintainers, it was mentioned that front-end will
> cap the num_actions value and that it is not possible to reach this
> function with such a large number. Yet, for correctness, it is still
> better to fix this.
> 
> This issue was observed by the commit author while reviewing a write-up
> regarding a CVE within the same subsystem [1].
> 
> 1 - https://nickgregory.me/post/2022/03/12/cve-2022-25636/
> 
> Signed-off-by: Joao Moreira <joao.moreira@intel.com>
> ---
>  net/core/flow_offload.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c
> index bc5169482710..bc3f53a09d8f 100644
> --- a/net/core/flow_offload.c
> +++ b/net/core/flow_offload.c
> @@ -10,7 +10,7 @@
>  struct flow_rule *flow_rule_alloc(unsigned int num_actions)
>  {
>  	struct flow_rule *rule;
> -	int i;
> +	unsigned int i;

With the 2^8 cap, I don't think this patch is required anymore.

>  
>  	rule = kzalloc(struct_size(rule, action.entries, num_actions),
>  		       GFP_KERNEL);
> @@ -31,7 +31,7 @@ EXPORT_SYMBOL(flow_rule_alloc);
>  struct flow_offload_action *offload_action_alloc(unsigned int num_actions)
>  {
>  	struct flow_offload_action *fl_action;
> -	int i;
> +	unsigned int i;
>  
>  	fl_action = kzalloc(struct_size(fl_action, action.entries, num_actions),
>  			    GFP_KERNEL);
> -- 
> 2.42.0
>
  
Joao Moreira Sept. 29, 2023, 2:53 a.m. UTC | #2
On 2023-09-28 06:40, Pablo Neira Ayuso wrote:
> On Wed, Sep 27, 2023 at 09:47:14AM -0700, joao@overdrivepizza.com 
> wrote:
>> From: Joao Moreira <joao.moreira@intel.com>
>> 
>> Both flow_rule_alloc and offload_action_alloc functions received an
>> unsigned num_actions parameters which are then operated within a loop.
>> The index of this loop is declared as a signed int. If it was possible
>> to pass a large enough num_actions to these functions, it would lead 
>> to
>> an out of bounds write.
>> 
>> After checking with maintainers, it was mentioned that front-end will
>> cap the num_actions value and that it is not possible to reach this
>> function with such a large number. Yet, for correctness, it is still
>> better to fix this.
>> 
>> This issue was observed by the commit author while reviewing a 
>> write-up
>> regarding a CVE within the same subsystem [1].
>> 
>> 1 - https://nickgregory.me/post/2022/03/12/cve-2022-25636/
>> 
>> Signed-off-by: Joao Moreira <joao.moreira@intel.com>
>> ---
>>  net/core/flow_offload.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>> 
>> diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c
>> index bc5169482710..bc3f53a09d8f 100644
>> --- a/net/core/flow_offload.c
>> +++ b/net/core/flow_offload.c
>> @@ -10,7 +10,7 @@
>>  struct flow_rule *flow_rule_alloc(unsigned int num_actions)
>>  {
>>  	struct flow_rule *rule;
>> -	int i;
>> +	unsigned int i;
> 
> With the 2^8 cap, I don't think this patch is required anymore.

Hm. While I understand that there is not a significant menace haunting 
this... would it be good for (1) type correctness and (2) prevent that 
things blow up if something changes and someone misses this spot?

> 
>> 
>>  	rule = kzalloc(struct_size(rule, action.entries, num_actions),
>>  		       GFP_KERNEL);
>> @@ -31,7 +31,7 @@ EXPORT_SYMBOL(flow_rule_alloc);
>>  struct flow_offload_action *offload_action_alloc(unsigned int 
>> num_actions)
>>  {
>>  	struct flow_offload_action *fl_action;
>> -	int i;
>> +	unsigned int i;
>> 
>>  	fl_action = kzalloc(struct_size(fl_action, action.entries, 
>> num_actions),
>>  			    GFP_KERNEL);
>> --
>> 2.42.0
>>
  
Pablo Neira Ayuso Sept. 29, 2023, 8:05 a.m. UTC | #3
On Thu, Sep 28, 2023 at 07:53:14PM -0700, Joao Moreira wrote:
> On 2023-09-28 06:40, Pablo Neira Ayuso wrote:
> > On Wed, Sep 27, 2023 at 09:47:14AM -0700, joao@overdrivepizza.com wrote:
> > > From: Joao Moreira <joao.moreira@intel.com>
> > > 
> > > Both flow_rule_alloc and offload_action_alloc functions received an
> > > unsigned num_actions parameters which are then operated within a loop.
> > > The index of this loop is declared as a signed int. If it was possible
> > > to pass a large enough num_actions to these functions, it would lead
> > > to
> > > an out of bounds write.
> > > 
> > > After checking with maintainers, it was mentioned that front-end will
> > > cap the num_actions value and that it is not possible to reach this
> > > function with such a large number. Yet, for correctness, it is still
> > > better to fix this.
> > > 
> > > This issue was observed by the commit author while reviewing a
> > > write-up
> > > regarding a CVE within the same subsystem [1].
> > > 
> > > 1 - https://nickgregory.me/post/2022/03/12/cve-2022-25636/
> > > 
> > > Signed-off-by: Joao Moreira <joao.moreira@intel.com>
> > > ---
> > >  net/core/flow_offload.c | 4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c
> > > index bc5169482710..bc3f53a09d8f 100644
> > > --- a/net/core/flow_offload.c
> > > +++ b/net/core/flow_offload.c
> > > @@ -10,7 +10,7 @@
> > >  struct flow_rule *flow_rule_alloc(unsigned int num_actions)
> > >  {
> > >  	struct flow_rule *rule;
> > > -	int i;
> > > +	unsigned int i;
> > 
> > With the 2^8 cap, I don't think this patch is required anymore.
> 
> Hm. While I understand that there is not a significant menace haunting
> this... would it be good for (1) type correctness and (2) prevent that
> things blow up if something changes and someone misses this spot?

Nothing is going to change, please remove unnecesary updates. Capping
to 2^8 for all hardware offload subsystems is sufficient by now. If
someone needs more than that, it will have to justify it.
  

Patch

diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c
index bc5169482710..bc3f53a09d8f 100644
--- a/net/core/flow_offload.c
+++ b/net/core/flow_offload.c
@@ -10,7 +10,7 @@ 
 struct flow_rule *flow_rule_alloc(unsigned int num_actions)
 {
 	struct flow_rule *rule;
-	int i;
+	unsigned int i;
 
 	rule = kzalloc(struct_size(rule, action.entries, num_actions),
 		       GFP_KERNEL);
@@ -31,7 +31,7 @@  EXPORT_SYMBOL(flow_rule_alloc);
 struct flow_offload_action *offload_action_alloc(unsigned int num_actions)
 {
 	struct flow_offload_action *fl_action;
-	int i;
+	unsigned int i;
 
 	fl_action = kzalloc(struct_size(fl_action, action.entries, num_actions),
 			    GFP_KERNEL);