diff mbox series

[v2,next] RDMA/core: Use size_{add,mul}() in calls to struct_size()

Message ID ZP+if342EMhModzZ@work (mailing list archive)
State Changes Requested
Headers show
Series [v2,next] RDMA/core: Use size_{add,mul}() in calls to struct_size() | expand

Commit Message

Gustavo A. R. Silva Sept. 11, 2023, 11:27 p.m. UTC
Harden calls to struct_size() with size_add() and size_mul().

Fixes: 467f432a521a ("RDMA/core: Split port and device counter sysfs attributes")
Fixes: a4676388e2e2 ("RDMA/core: Simplify how the gid_attrs sysfs is created")
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
---
Changes in v2:
 - Update changelog text: remove the part about binary differences (it
   was added by mistake).

 drivers/infiniband/core/sysfs.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Comments

Kees Cook Sept. 15, 2023, 3:29 a.m. UTC | #1
On Mon, Sep 11, 2023 at 05:27:59PM -0600, Gustavo A. R. Silva wrote:
> Harden calls to struct_size() with size_add() and size_mul().

Specifically, make sure that open-coded arithmetic cannot cause an
overflow/wraparound. (i.e. it will stay saturated at SIZE_MAX.)

> 
> Fixes: 467f432a521a ("RDMA/core: Split port and device counter sysfs attributes")
> Fixes: a4676388e2e2 ("RDMA/core: Simplify how the gid_attrs sysfs is created")
> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>

Reviewed-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
> Changes in v2:
>  - Update changelog text: remove the part about binary differences (it
>    was added by mistake).
> 
>  drivers/infiniband/core/sysfs.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
> index ee59d7391568..ec5efdc16660 100644
> --- a/drivers/infiniband/core/sysfs.c
> +++ b/drivers/infiniband/core/sysfs.c
> @@ -903,7 +903,7 @@ alloc_hw_stats_device(struct ib_device *ibdev)
>  	 * Two extra attribue elements here, one for the lifespan entry and
>  	 * one to NULL terminate the list for the sysfs core code
>  	 */
> -	data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
> +	data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
>  		       GFP_KERNEL);
>  	if (!data)
>  		goto err_free_stats;
> @@ -1009,7 +1009,7 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group)
>  	 * Two extra attribue elements here, one for the lifespan entry and
>  	 * one to NULL terminate the list for the sysfs core code
>  	 */
> -	data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
> +	data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
>  		       GFP_KERNEL);
>  	if (!data)
>  		goto err_free_stats;
> @@ -1140,7 +1140,7 @@ static int setup_gid_attrs(struct ib_port *port,
>  	int ret;
>  
>  	gid_attr_group = kzalloc(struct_size(gid_attr_group, attrs_list,
> -					     attr->gid_tbl_len * 2),
> +					     size_mul(attr->gid_tbl_len, 2)),
>  				 GFP_KERNEL);
>  	if (!gid_attr_group)
>  		return -ENOMEM;
> @@ -1205,8 +1205,8 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
>  	int ret;
>  
>  	p = kvzalloc(struct_size(p, attrs_list,
> -				attr->gid_tbl_len + attr->pkey_tbl_len),
> -		    GFP_KERNEL);
> +				size_add(attr->gid_tbl_len, attr->pkey_tbl_len)),
> +		     GFP_KERNEL);
>  	if (!p)
>  		return ERR_PTR(-ENOMEM);
>  	p->ibdev = device;
> -- 
> 2.34.1
>
Gustavo A. R. Silva Sept. 15, 2023, 6:06 p.m. UTC | #2
On 9/14/23 21:29, Kees Cook wrote:
> On Mon, Sep 11, 2023 at 05:27:59PM -0600, Gustavo A. R. Silva wrote:
>> Harden calls to struct_size() with size_add() and size_mul().
> 
> Specifically, make sure that open-coded arithmetic cannot cause an
> overflow/wraparound. (i.e. it will stay saturated at SIZE_MAX.)

Yep; I have another patch where I explain this in similar terms.

I'll send it, shortly.

> 
>>
>> Fixes: 467f432a521a ("RDMA/core: Split port and device counter sysfs attributes")
>> Fixes: a4676388e2e2 ("RDMA/core: Simplify how the gid_attrs sysfs is created")
>> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> 
> Reviewed-by: Kees Cook <keescook@chromium.org>

Thanks!

--
Gustavo

> 
> -Kees
> 
>> ---
>> Changes in v2:
>>   - Update changelog text: remove the part about binary differences (it
>>     was added by mistake).
>>
>>   drivers/infiniband/core/sysfs.c | 10 +++++-----
>>   1 file changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
>> index ee59d7391568..ec5efdc16660 100644
>> --- a/drivers/infiniband/core/sysfs.c
>> +++ b/drivers/infiniband/core/sysfs.c
>> @@ -903,7 +903,7 @@ alloc_hw_stats_device(struct ib_device *ibdev)
>>   	 * Two extra attribue elements here, one for the lifespan entry and
>>   	 * one to NULL terminate the list for the sysfs core code
>>   	 */
>> -	data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
>> +	data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
>>   		       GFP_KERNEL);
>>   	if (!data)
>>   		goto err_free_stats;
>> @@ -1009,7 +1009,7 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group)
>>   	 * Two extra attribue elements here, one for the lifespan entry and
>>   	 * one to NULL terminate the list for the sysfs core code
>>   	 */
>> -	data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
>> +	data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
>>   		       GFP_KERNEL);
>>   	if (!data)
>>   		goto err_free_stats;
>> @@ -1140,7 +1140,7 @@ static int setup_gid_attrs(struct ib_port *port,
>>   	int ret;
>>   
>>   	gid_attr_group = kzalloc(struct_size(gid_attr_group, attrs_list,
>> -					     attr->gid_tbl_len * 2),
>> +					     size_mul(attr->gid_tbl_len, 2)),
>>   				 GFP_KERNEL);
>>   	if (!gid_attr_group)
>>   		return -ENOMEM;
>> @@ -1205,8 +1205,8 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
>>   	int ret;
>>   
>>   	p = kvzalloc(struct_size(p, attrs_list,
>> -				attr->gid_tbl_len + attr->pkey_tbl_len),
>> -		    GFP_KERNEL);
>> +				size_add(attr->gid_tbl_len, attr->pkey_tbl_len)),
>> +		     GFP_KERNEL);
>>   	if (!p)
>>   		return ERR_PTR(-ENOMEM);
>>   	p->ibdev = device;
>> -- 
>> 2.34.1
>>
>
Gustavo A. R. Silva Sept. 17, 2023, 7:59 p.m. UTC | #3
On 9/18/23 04:49, Leon Romanovsky wrote:
> On Fri, Sep 15, 2023 at 12:06:21PM -0600, Gustavo A. R. Silva wrote:
>>
>>
>> On 9/14/23 21:29, Kees Cook wrote:
>>> On Mon, Sep 11, 2023 at 05:27:59PM -0600, Gustavo A. R. Silva wrote:
>>>> Harden calls to struct_size() with size_add() and size_mul().
>>>
>>> Specifically, make sure that open-coded arithmetic cannot cause an
>>> overflow/wraparound. (i.e. it will stay saturated at SIZE_MAX.)
>>
>> Yep; I have another patch where I explain this in similar terms.
>>
>> I'll send it, shortly.
> 
> You missed other places with similar arithmetic.
> drivers/infiniband/core/device.c:       pdata_rcu = kzalloc(struct_size(pdata_rcu, pdata,
> drivers/infiniband/core/device.c-                                       rdma_end_port(device) + 1),
> drivers/infiniband/core/device.c-                           GFP_KERNEL);
> 
> drivers/infiniband/core/sa_query.c:     sa_dev = kzalloc(struct_size(sa_dev, port, e - s + 1), GFP_KERNEL);
> drivers/infiniband/core/user_mad.c:     umad_dev = kzalloc(struct_size(umad_dev, ports, e - s + 1), GFP_KERNEL);

I haven't sent all my patches.

--
Gustavo
Gustavo A. R. Silva Sept. 18, 2023, 1:58 a.m. UTC | #4
On 9/18/23 06:41, Leon Romanovsky wrote:
> On Sun, Sep 17, 2023 at 01:59:26PM -0600, Gustavo A. R. Silva wrote:
>>
>>
>> On 9/18/23 04:49, Leon Romanovsky wrote:
>>> On Fri, Sep 15, 2023 at 12:06:21PM -0600, Gustavo A. R. Silva wrote:
>>>>
>>>>
>>>> On 9/14/23 21:29, Kees Cook wrote:
>>>>> On Mon, Sep 11, 2023 at 05:27:59PM -0600, Gustavo A. R. Silva wrote:
>>>>>> Harden calls to struct_size() with size_add() and size_mul().
>>>>>
>>>>> Specifically, make sure that open-coded arithmetic cannot cause an
>>>>> overflow/wraparound. (i.e. it will stay saturated at SIZE_MAX.)
>>>>
>>>> Yep; I have another patch where I explain this in similar terms.
>>>>
>>>> I'll send it, shortly.
>>>
>>> You missed other places with similar arithmetic.
>>> drivers/infiniband/core/device.c:       pdata_rcu = kzalloc(struct_size(pdata_rcu, pdata,
>>> drivers/infiniband/core/device.c-                                       rdma_end_port(device) + 1),
>>> drivers/infiniband/core/device.c-                           GFP_KERNEL);
>>>
>>> drivers/infiniband/core/sa_query.c:     sa_dev = kzalloc(struct_size(sa_dev, port, e - s + 1), GFP_KERNEL);
>>> drivers/infiniband/core/user_mad.c:     umad_dev = kzalloc(struct_size(umad_dev, ports, e - s + 1), GFP_KERNEL);
>>
>> I haven't sent all my patches.
> 
> Please sent one patch for whole drivers/infiniband/core/ folder as your
> title: "RDMA/core ..." suggests.

OK. Done:

https://lore.kernel.org/linux-hardening/ZQdt4NsJFwwOYxUR@work/

Thanks
--
Gustavo
Leon Romanovsky Sept. 18, 2023, 10:49 a.m. UTC | #5
On Fri, Sep 15, 2023 at 12:06:21PM -0600, Gustavo A. R. Silva wrote:
> 
> 
> On 9/14/23 21:29, Kees Cook wrote:
> > On Mon, Sep 11, 2023 at 05:27:59PM -0600, Gustavo A. R. Silva wrote:
> > > Harden calls to struct_size() with size_add() and size_mul().
> > 
> > Specifically, make sure that open-coded arithmetic cannot cause an
> > overflow/wraparound. (i.e. it will stay saturated at SIZE_MAX.)
> 
> Yep; I have another patch where I explain this in similar terms.
> 
> I'll send it, shortly.

You missed other places with similar arithmetic.
drivers/infiniband/core/device.c:       pdata_rcu = kzalloc(struct_size(pdata_rcu, pdata,
drivers/infiniband/core/device.c-                                       rdma_end_port(device) + 1),
drivers/infiniband/core/device.c-                           GFP_KERNEL);

drivers/infiniband/core/sa_query.c:     sa_dev = kzalloc(struct_size(sa_dev, port, e - s + 1), GFP_KERNEL);
drivers/infiniband/core/user_mad.c:     umad_dev = kzalloc(struct_size(umad_dev, ports, e - s + 1), GFP_KERNEL);

Thanks

> 
> > 
> > > 
> > > Fixes: 467f432a521a ("RDMA/core: Split port and device counter sysfs attributes")
> > > Fixes: a4676388e2e2 ("RDMA/core: Simplify how the gid_attrs sysfs is created")
> > > Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> > 
> > Reviewed-by: Kees Cook <keescook@chromium.org>
> 
> Thanks!
> 
> --
> Gustavo
> 
> > 
> > -Kees
> > 
> > > ---
> > > Changes in v2:
> > >   - Update changelog text: remove the part about binary differences (it
> > >     was added by mistake).
> > > 
> > >   drivers/infiniband/core/sysfs.c | 10 +++++-----
> > >   1 file changed, 5 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
> > > index ee59d7391568..ec5efdc16660 100644
> > > --- a/drivers/infiniband/core/sysfs.c
> > > +++ b/drivers/infiniband/core/sysfs.c
> > > @@ -903,7 +903,7 @@ alloc_hw_stats_device(struct ib_device *ibdev)
> > >   	 * Two extra attribue elements here, one for the lifespan entry and
> > >   	 * one to NULL terminate the list for the sysfs core code
> > >   	 */
> > > -	data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
> > > +	data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
> > >   		       GFP_KERNEL);
> > >   	if (!data)
> > >   		goto err_free_stats;
> > > @@ -1009,7 +1009,7 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group)
> > >   	 * Two extra attribue elements here, one for the lifespan entry and
> > >   	 * one to NULL terminate the list for the sysfs core code
> > >   	 */
> > > -	data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
> > > +	data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
> > >   		       GFP_KERNEL);
> > >   	if (!data)
> > >   		goto err_free_stats;
> > > @@ -1140,7 +1140,7 @@ static int setup_gid_attrs(struct ib_port *port,
> > >   	int ret;
> > >   	gid_attr_group = kzalloc(struct_size(gid_attr_group, attrs_list,
> > > -					     attr->gid_tbl_len * 2),
> > > +					     size_mul(attr->gid_tbl_len, 2)),
> > >   				 GFP_KERNEL);
> > >   	if (!gid_attr_group)
> > >   		return -ENOMEM;
> > > @@ -1205,8 +1205,8 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
> > >   	int ret;
> > >   	p = kvzalloc(struct_size(p, attrs_list,
> > > -				attr->gid_tbl_len + attr->pkey_tbl_len),
> > > -		    GFP_KERNEL);
> > > +				size_add(attr->gid_tbl_len, attr->pkey_tbl_len)),
> > > +		     GFP_KERNEL);
> > >   	if (!p)
> > >   		return ERR_PTR(-ENOMEM);
> > >   	p->ibdev = device;
> > > -- 
> > > 2.34.1
> > > 
> >
Leon Romanovsky Sept. 18, 2023, 12:41 p.m. UTC | #6
On Sun, Sep 17, 2023 at 01:59:26PM -0600, Gustavo A. R. Silva wrote:
> 
> 
> On 9/18/23 04:49, Leon Romanovsky wrote:
> > On Fri, Sep 15, 2023 at 12:06:21PM -0600, Gustavo A. R. Silva wrote:
> > > 
> > > 
> > > On 9/14/23 21:29, Kees Cook wrote:
> > > > On Mon, Sep 11, 2023 at 05:27:59PM -0600, Gustavo A. R. Silva wrote:
> > > > > Harden calls to struct_size() with size_add() and size_mul().
> > > > 
> > > > Specifically, make sure that open-coded arithmetic cannot cause an
> > > > overflow/wraparound. (i.e. it will stay saturated at SIZE_MAX.)
> > > 
> > > Yep; I have another patch where I explain this in similar terms.
> > > 
> > > I'll send it, shortly.
> > 
> > You missed other places with similar arithmetic.
> > drivers/infiniband/core/device.c:       pdata_rcu = kzalloc(struct_size(pdata_rcu, pdata,
> > drivers/infiniband/core/device.c-                                       rdma_end_port(device) + 1),
> > drivers/infiniband/core/device.c-                           GFP_KERNEL);
> > 
> > drivers/infiniband/core/sa_query.c:     sa_dev = kzalloc(struct_size(sa_dev, port, e - s + 1), GFP_KERNEL);
> > drivers/infiniband/core/user_mad.c:     umad_dev = kzalloc(struct_size(umad_dev, ports, e - s + 1), GFP_KERNEL);
> 
> I haven't sent all my patches.

Please sent one patch for whole drivers/infiniband/core/ folder as your
title: "RDMA/core ..." suggests.

Thanks

> 
> --
> Gustavo
diff mbox series

Patch

diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index ee59d7391568..ec5efdc16660 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -903,7 +903,7 @@  alloc_hw_stats_device(struct ib_device *ibdev)
 	 * Two extra attribue elements here, one for the lifespan entry and
 	 * one to NULL terminate the list for the sysfs core code
 	 */
-	data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
+	data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
 		       GFP_KERNEL);
 	if (!data)
 		goto err_free_stats;
@@ -1009,7 +1009,7 @@  alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group)
 	 * Two extra attribue elements here, one for the lifespan entry and
 	 * one to NULL terminate the list for the sysfs core code
 	 */
-	data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
+	data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
 		       GFP_KERNEL);
 	if (!data)
 		goto err_free_stats;
@@ -1140,7 +1140,7 @@  static int setup_gid_attrs(struct ib_port *port,
 	int ret;
 
 	gid_attr_group = kzalloc(struct_size(gid_attr_group, attrs_list,
-					     attr->gid_tbl_len * 2),
+					     size_mul(attr->gid_tbl_len, 2)),
 				 GFP_KERNEL);
 	if (!gid_attr_group)
 		return -ENOMEM;
@@ -1205,8 +1205,8 @@  static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
 	int ret;
 
 	p = kvzalloc(struct_size(p, attrs_list,
-				attr->gid_tbl_len + attr->pkey_tbl_len),
-		    GFP_KERNEL);
+				size_add(attr->gid_tbl_len, attr->pkey_tbl_len)),
+		     GFP_KERNEL);
 	if (!p)
 		return ERR_PTR(-ENOMEM);
 	p->ibdev = device;