All of lore.kernel.org
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [PATCH v2] mux: convert mux_chip->mux to flexible array
@ 2024-02-26 21:29 68% Jacob Keller
  0 siblings, 0 replies; 24+ results
From: Jacob Keller @ 2024-02-26 21:29 UTC (permalink / raw)
  To: Kees Cook, linux-i2c, linux-kernel
  Cc: gustavoars, Peter Rosin, Jesse Brandeburg, Jacob Keller

The mux_chip structure size is over allocated to additionally include both
the array of mux controllers as well as a device specific private area.
The controllers array is then pointed to by assigning mux_chip->mux to the
first block of extra memory, while the private area is extracted via
mux_chip_priv() and points to the area just after the controllers.

The size of the mux_chip allocation uses direct multiplication and addition
rather than the <linux/overflow.h> helpers. In addition, the mux_chip->mux
struct member wastes space by having to store the pointer as part of the
structures.

Convert struct mux_chip to use a flexible array member for the mux
controller array. Use struct_size() and size_add() to compute the size of
the structure while protecting against overflow.

After converting the mux pointer, notice that two 4-byte holes remain in
the structure layout due to the alignment requirements for the dev
sub-structure and the ops pointer.

These can be easily fixed through re-ordering the id field to the 4-byte
hole just after the controllers member.

This changes the layout from:

struct mux_chip {
        unsigned int               controllers;          /*     0     4 */

        /* XXX 4 bytes hole, try to pack */

        struct mux_control *       mux;                  /*     8     8 */
        struct device              dev __attribute__((__aligned__(8))); /*    16  1488 */

        /* XXX last struct has 3 bytes of padding */

        /* --- cacheline 23 boundary (1472 bytes) was 32 bytes ago --- */
        int                        id;                   /*  1504     4 */

        /* XXX 4 bytes hole, try to pack */

        const struct mux_control_ops  * ops;             /*  1512     8 */

        /* size: 1520, cachelines: 24, members: 5 */
        /* sum members: 1512, holes: 2, sum holes: 8 */
        /* paddings: 1, sum paddings: 3 */
        /* forced alignments: 1 */
        /* last cacheline: 48 bytes */
} __attribute__((__aligned__(8)));

To the following:

struct mux_chip {
        unsigned int               controllers;          /*     0     4 */
        int                        id;                   /*     4     4 */
        struct device              dev __attribute__((__aligned__(8))); /*     8  1488 */

        /* XXX last struct has 3 bytes of padding */

        /* --- cacheline 23 boundary (1472 bytes) was 24 bytes ago --- */
        const struct mux_control_ops  * ops;             /*  1496     8 */
        struct mux_control         mux[];                /*  1504     0 */

        /* size: 1504, cachelines: 24, members: 5 */
        /* paddings: 1, sum paddings: 3 */
        /* forced alignments: 1 */
        /* last cacheline: 32 bytes */
} __attribute__((__aligned__(8)));

This both removes risk of overflowing and performing an under-allocation,
as well as saves 16 bytes of otherwise wasted space for every mux_chip.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
Changes since v1:
* Rebased and updated the commit message slightly.

 drivers/mux/core.c         |  7 +++----
 include/linux/mux/driver.h | 10 +++++-----
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/mux/core.c b/drivers/mux/core.c
index 775816112932..9225abca7897 100644
--- a/drivers/mux/core.c
+++ b/drivers/mux/core.c
@@ -98,13 +98,12 @@ struct mux_chip *mux_chip_alloc(struct device *dev,
 	if (WARN_ON(!dev || !controllers))
 		return ERR_PTR(-EINVAL);
 
-	mux_chip = kzalloc(sizeof(*mux_chip) +
-			   controllers * sizeof(*mux_chip->mux) +
-			   sizeof_priv, GFP_KERNEL);
+	mux_chip = kzalloc(size_add(struct_size(mux_chip, mux, controllers),
+				    sizeof_priv),
+			   GFP_KERNEL);
 	if (!mux_chip)
 		return ERR_PTR(-ENOMEM);
 
-	mux_chip->mux = (struct mux_control *)(mux_chip + 1);
 	mux_chip->dev.class = &mux_class;
 	mux_chip->dev.type = &mux_type;
 	mux_chip->dev.parent = dev;
diff --git a/include/linux/mux/driver.h b/include/linux/mux/driver.h
index 18824064f8c0..84dc0d3e79d6 100644
--- a/include/linux/mux/driver.h
+++ b/include/linux/mux/driver.h
@@ -56,18 +56,18 @@ struct mux_control {
 /**
  * struct mux_chip -	Represents a chip holding mux controllers.
  * @controllers:	Number of mux controllers handled by the chip.
- * @mux:		Array of mux controllers that are handled.
- * @dev:		Device structure.
  * @id:			Used to identify the device internally.
+ * @dev:		Device structure.
  * @ops:		Mux controller operations.
+ * @mux:		Flexible array of mux controllers that are handled.
  */
 struct mux_chip {
 	unsigned int controllers;
-	struct mux_control *mux;
-	struct device dev;
 	int id;
-
+	struct device dev;
 	const struct mux_control_ops *ops;
+
+	struct mux_control mux[];
 };
 
 #define to_mux_chip(x) container_of((x), struct mux_chip, dev)

base-commit: 45ec2f5f6ed3ec3a79ba1329ad585497cdcbe663
-- 
2.41.0


^ permalink raw reply related	[relevance 68%]

* Re: [PATCH -next] mux: convert mux_chip->mux to flexible array
  @ 2024-02-20 21:27 83%     ` Jacob Keller
  0 siblings, 0 replies; 24+ results
From: Jacob Keller @ 2024-02-20 21:27 UTC (permalink / raw)
  To: Kees Cook, Jesse Brandeburg
  Cc: Peter Rosin, gustavoars, linux-kernel, linux-i2c



On 2/18/2024 9:04 PM, Kees Cook wrote:
> On Mon, Feb 27, 2023 at 12:28:43PM -0800, Jesse Brandeburg wrote:
>> On 2/22/2023 5:42 PM, Jacob Keller wrote:
>>> The mux_chip structure size is over allocated to additionally include both
>>> the array of mux controllers as well as a device specific private area.
>>> The controllers array is then pointed to by assigning mux_chip->mux to the
>>> first block of extra memory, while the private area is extracted via
>>> mux_chip_priv() and points to the area just after the controllers.
>>>
>>> The size of the mux_chip allocation uses direct multiplication and addition
>>> rather than the <linux/overflow.h> helpers. In addition, the mux_chip->mux
>>> struct member wastes space by having to store the pointer as part of the
>>> structures.
>>>
>>> Convert struct mux_chip to use a flexible array member for the mux
>>> controller array. Use struct_size() and size_add() to compute the size of
>>> the structure while protecting against overflow.
>>>
>>> After converting the mux pointer, notice that two 4-byte holes remain in
>>> the structure layout due to the alignment requirements for the dev
>>> sub-structure and the ops pointer.
>>>
>>> These can be easily fixed through re-ordering the id field to the 4-byte
>>> hole just after the controllers member.
>>
>> Looks good to me (just a driver dev, not a mux dev!). Also added
>> linux-i2c mailing list and a couple others for more review.
>>
>> Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
>>
>> related thread (cocci script) at [1]
>>
>> [1]
>> https://lore.kernel.org/all/20230227202428.3657443-1-jacob.e.keller@intel.com/
> 
> *thread necromancy*
> 
> Can we land this? It's the last struct_size() instance that the above
> Coccinelle script flags.
> 
> Reviewed-by: Kees Cook <keescook@chromium.org>
> 

I'm happy to send a v2 if we need.

Thanks,
Jake

^ permalink raw reply	[relevance 83%]

* RE: [PATCH] coccinelle: semantic patch to check for potential struct_size calls
  @ 2024-01-17 21:54 76%   ` Keller, Jacob E
  0 siblings, 0 replies; 24+ results
From: Keller, Jacob E @ 2024-01-17 21:54 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Julia Lawall, Kees Cook, Gustavo A . R . Silva, cocci,
	linux-kernel, Harshit Mogalapalli



> -----Original Message-----
> From: Dan Carpenter <dan.carpenter@linaro.org>
> Sent: Monday, January 15, 2024 11:03 PM
> To: Keller, Jacob E <jacob.e.keller@intel.com>
> Cc: Julia Lawall <Julia.Lawall@lip6.fr>; Kees Cook <keescook@chromium.org>;
> Gustavo A . R . Silva <gustavoars@kernel.org>; cocci@systeme.lip6.fr; linux-
> kernel@vger.kernel.org; Harshit Mogalapalli <harshit.m.mogalapalli@gmail.com>
> Subject: Re: [PATCH] coccinelle: semantic patch to check for potential struct_size
> calls
> 
> What happened to this patch?  These sorts of patches go through Kees?
> 

No one replied and I got side tracked by other projects.

> Also it would be nice if it could handle char arrays.  It doesn't warn
> for the kmalloc in dg_dispatch_as_host():
> 
Yea it would be nice to handle this too.

> drivers/misc/vmw_vmci/vmci_datagram.c
>    227                          dg_info = kmalloc(sizeof(*dg_info) +
>    228                                      (size_t) dg->payload_size, GFP_ATOMIC);
> 
> The Cocci check is looking specifically for:
> 
> 	sizeof(*dg_info) + (sizeof(*dg_info->msg_payload) * dg->payload_size)
> 

I think that's a slightly different formulation.

> But since this flex array is u8 there is no multiply.  I don't know how
> are it is to add support for char arrays...
> 

A separate rule would work.

> Also another common way to write the multiply is:
> 
> 	sizeof(*dg_info) + (sizeof(dg_info->msg_payload[0]) * dg->payload_size)
> 
> That should be pretty straight forward to add.
> 
> regards,
> dan carpenter
> 

Mostly I just lost track of this because I struggled to get traction in the right lists and trees.

Thanks,
Jake


^ permalink raw reply	[relevance 76%]

* Re: [PATCH] coccinelle: semantic patch to check for potential struct_size calls
  @ 2023-08-29 19:25 72%   ` Jacob Keller
  0 siblings, 0 replies; 24+ results
From: Jacob Keller @ 2023-08-29 19:25 UTC (permalink / raw)
  To: Kees Cook
  Cc: Julia Lawall, Gustavo A . R . Silva, cocci, linux-kernel,
	linux-hardening



On 8/26/2023 6:19 PM, Kees Cook wrote:
> Hi!
> 
> I'm sorry I lost this email! I just found it while trying to clean up
> my inbox.
> 
> On Mon, Feb 27, 2023 at 12:24:28PM -0800, Jacob Keller wrote:
>> include/linux/overflow.h includes helper macros intended for calculating
>> sizes of allocations. These macros prevent accidental overflow by
>> saturating at SIZE_MAX.
>>
>> In general when calculating such sizes use of the macros is preferred. Add
>> a semantic patch which can detect code patterns which can be replaced by
>> struct_size.
>>
>> Note that I set the confidence to medium because this patch doesn't make an
>> attempt to ensure that the relevant array is actually a flexible array. The
>> struct_size macro does specifically require a flexible array. In many cases
>> the detected code could be refactored to a flexible array, but this is not
>> always possible (such as if there are multiple over-allocations).
>>
>> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
>> Cc: Julia Lawall <Julia.Lawall@lip6.fr>
>> Cc: Kees Cook <keescook@chromium.org>
>> Cc: Gustavo A. R. Silva <gustavoars@kernel.org>
>> Cc: cocci@systeme.lip6.fr
>> Cc: linux-kernel@vger.kernel.org
>>
>>  scripts/coccinelle/misc/struct_size.cocci | 74 +++++++++++++++++++++++
>>  1 file changed, 74 insertions(+)
>>  create mode 100644 scripts/coccinelle/misc/struct_size.cocci
> 
> Yes! I'd really like to get something like this into the Coccinelle
> scripts.
> 
>> diff --git a/scripts/coccinelle/misc/struct_size.cocci b/scripts/coccinelle/misc/struct_size.cocci
>> new file mode 100644
>> index 000000000000..4ede9586e3c6
>> --- /dev/null
>> +++ b/scripts/coccinelle/misc/struct_size.cocci
>> @@ -0,0 +1,74 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +///
>> +/// Check for code that could use struct_size().
>> +///
>> +// Confidence: Medium
>> +// Author: Jacob Keller <jacob.e.keller@intel.com>
>> +// Copyright: (C) 2023 Intel Corporation
>> +// Options: --no-includes --include-headers
>> +
>> +virtual patch
>> +virtual context
>> +virtual org
>> +virtual report
>> +
>> +// the overflow Kunit tests have some code which intentionally does not use
>> +// the macros, so we want to ignore this code when reporting potential
>> +// issues.
>> +@overflow_tests@
>> +identifier f = overflow_size_helpers_test;
>> +@@
>> +
>> +f
>> +
>> +//----------------------------------------------------------
>> +//  For context mode
>> +//----------------------------------------------------------
>> +
>> +@depends on !overflow_tests && context@
>> +expression E1, E2;
>> +identifier m;
>> +@@
>> +(
>> +* (sizeof(*E1) + (E2 * sizeof(*E1->m)))
>> +)
>> +
>> +//----------------------------------------------------------
>> +//  For patch mode
>> +//----------------------------------------------------------
>> +
>> +@depends on !overflow_tests && patch@
>> +expression E1, E2;
>> +identifier m;
>> +@@
>> +(
>> +- (sizeof(*E1) + (E2 * sizeof(*E1->m)))
>> ++ struct_size(E1, m, E2)
>> +)
> 
> Two notes:
> 
> This can lead to false positives (like for struct mux_chip) which
> doesn't use a flexible array member, which means struct_size() will
> actually fail to build (it requires the 2nd arg to be an array).
> 

I actually sent a fix for mux chip to refactor it to struct_size too :)

https://lore.kernel.org/all/20230223014221.1710307-1-jacob.e.keller@intel.com/

> This can miss cases that have more than a single struct depth (which is
> uncommon but happens). I don't know how to match only "substruct.member"
> from "ptr->substruct.member". (I know how to match the whole thing[1],
> though.)
> 
Yea I couldn't figure out how to get it to handle both cases here but I
actually prefer reporting cases like mux_chip, since they can usually be
refactored to use struct size properly.

> That isn't reason not to take this patch, though. It's a good start!
> 

Right. Both cases like this are why I set the confidence to only medium,
and mentioned it in the commit :D


> Thanks for writing this up!
> 
> -Kees
> 

Thanks for reviewing. I also sent some struct_size cleanups that look to
have stalled and could use some review or a re-send if necessary at this
point.

I think the full list can be found with this lore.kernel.org search:

https://lore.kernel.org/all/?q=f%3Ajacob.e.keller+AND+%28+s%3Astruct_size+OR+s%3A%22flexible+array%22+%29




^ permalink raw reply	[relevance 72%]

* [PATCH v2] wifi: qtnfmac: use struct_size and size_sub for payload length
@ 2023-03-07 23:02 70% Jacob Keller
  0 siblings, 0 replies; 24+ results
From: Jacob Keller @ 2023-03-07 23:02 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Johannes Berg, linux-wireless, Jacob Keller, Igor Mitsyanko,
	Sergey Matyukevich

Replace the calculations for the payload length in
qtnf_cmd_band_fill_iftype with struct_size() and size_sub(). While
the payload length does not get directly passed to an allocation function,
the performed calculation is still calculating the size of a flexible array
structure (minus the size of a header structure).

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Cc: Igor Mitsyanko <imitsyanko@quantenna.com>
Cc: Sergey Matyukevich <geomatsi@gmail.com>
---
This was discovered by a coccinelle patch I developed, and submitted at:
  https://lore.kernel.org/all/20230227202428.3657443-1-jacob.e.keller@intel.com/

V1: https://lore.kernel.org/linux-wireless/99a9d4a2-d032-1c9d-90c6-3a68f6b3a092@intel.com/
Changes since v1
* Split series into individual postings to avoid confusion about dependency
* Fixed subject line

 drivers/net/wireless/quantenna/qtnfmac/commands.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index b1b73478d89b..68ae9c7ea95a 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -1325,9 +1325,10 @@ static int qtnf_cmd_band_fill_iftype(const u8 *data,
 	struct ieee80211_sband_iftype_data *iftype_data;
 	const struct qlink_tlv_iftype_data *tlv =
 		(const struct qlink_tlv_iftype_data *)data;
-	size_t payload_len = tlv->n_iftype_data * sizeof(*tlv->iftype_data) +
-		sizeof(*tlv) -
-		sizeof(struct qlink_tlv_hdr);
+	size_t payload_len;
+
+	payload_len = struct_size(tlv, iftype_data, tlv->n_iftype_data);
+	payload_len = size_sub(payload_len, sizeof(struct qlink_tlv_hdr));
 
 	if (tlv->hdr.len != cpu_to_le16(payload_len)) {
 		pr_err("bad IFTYPE_DATA TLV len %u\n", tlv->hdr.len);

base-commit: 8f9850dd8d23c1290cb642ce9548a440da5771ec
-- 
2.39.1.405.gd4c25cc71f83


^ permalink raw reply related	[relevance 70%]

* [PATCH v2] wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[]
@ 2023-03-07 23:01 71% Jacob Keller
  0 siblings, 0 replies; 24+ results
From: Jacob Keller @ 2023-03-07 23:01 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Johannes Berg, linux-wireless, Jacob Keller, Stanislav Yakovlev

The ipw_fw_error structure contains a payload[] flexible array as well as
two pointers to this array area, ->elem, and ->log. The total size of the
allocated structure is computed without use of the <linux/overflow.h>
macros.

There's no reason to keep both a payload[] and an extra pointer to both the
elem and log members. Convert the elem pointer member into the flexible
array member, removing payload.

Fix the allocation of the ipw_fw_error structure to use size_add(),
struct_size(), and array_size() to compute the allocation. This ensures
that any overflow saturates at SIZE_MAX rather than overflowing and
potentially allowing an undersized allocation.

Before the structure change, the layout of ipw_fw_error was:

struct ipw_fw_error {
        long unsigned int          jiffies;              /*     0     8 */
        u32                        status;               /*     8     4 */
        u32                        config;               /*    12     4 */
        u32                        elem_len;             /*    16     4 */
        u32                        log_len;              /*    20     4 */
        struct ipw_error_elem *    elem;                 /*    24     8 */
        struct ipw_event *         log;                  /*    32     8 */
        u8                         payload[];            /*    40     0 */

        /* size: 40, cachelines: 1, members: 8 */
        /* last cacheline: 40 bytes */
};

After this change, the layout is now:

struct ipw_fw_error {
        long unsigned int          jiffies;              /*     0     8 */
        u32                        status;               /*     8     4 */
        u32                        config;               /*    12     4 */
        u32                        elem_len;             /*    16     4 */
        u32                        log_len;              /*    20     4 */
        struct ipw_event *         log;                  /*    24     8 */
        struct ipw_error_elem      elem[];               /*    32     0 */

        /* size: 32, cachelines: 1, members: 7 */
        /* last cacheline: 32 bytes */
};

This saves a total of 8 bytes for every ipw_fw_error allocation, and
removes the risk of a potential overflow on the allocation.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Cc: Stanislav Yakovlev <stas.yakovlev@gmail.com>
---
This was discovered by a coccinelle patch I developed, and submitted at:
  https://lore.kernel.org/all/20230227202428.3657443-1-jacob.e.keller@intel.com/

V1: https://lore.kernel.org/linux-wireless/99a9d4a2-d032-1c9d-90c6-3a68f6b3a092@intel.com/
Changes since v1
* Split series into individual postings to avoid confusion about dependency

 drivers/net/wireless/intel/ipw2x00/ipw2200.c | 7 +++----
 drivers/net/wireless/intel/ipw2x00/ipw2200.h | 3 +--
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
index d382f2017325..b91b1a2d0be7 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
@@ -1234,9 +1234,9 @@ static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
 	u32 base = ipw_read32(priv, IPW_ERROR_LOG);
 	u32 elem_len = ipw_read_reg32(priv, base);
 
-	error = kmalloc(sizeof(*error) +
-			sizeof(*error->elem) * elem_len +
-			sizeof(*error->log) * log_len, GFP_ATOMIC);
+	error = kmalloc(size_add(struct_size(error, elem, elem_len),
+				 array_size(sizeof(*error->log), log_len)),
+			GFP_ATOMIC);
 	if (!error) {
 		IPW_ERROR("Memory allocation for firmware error log "
 			  "failed.\n");
@@ -1247,7 +1247,6 @@ static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
 	error->config = priv->config;
 	error->elem_len = elem_len;
 	error->log_len = log_len;
-	error->elem = (struct ipw_error_elem *)error->payload;
 	error->log = (struct ipw_event *)(error->elem + elem_len);
 
 	ipw_capture_event_log(priv, log_len, error->log);
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.h b/drivers/net/wireless/intel/ipw2x00/ipw2200.h
index 09ddd21608d4..8ebf09121e17 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.h
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.h
@@ -1106,9 +1106,8 @@ struct ipw_fw_error {	 /* XXX */
 	u32 config;
 	u32 elem_len;
 	u32 log_len;
-	struct ipw_error_elem *elem;
 	struct ipw_event *log;
-	u8 payload[];
+	struct ipw_error_elem elem[];
 } __packed;
 
 #ifdef CONFIG_IPW2200_PROMISCUOUS

base-commit: 8f9850dd8d23c1290cb642ce9548a440da5771ec
-- 
2.39.1.405.gd4c25cc71f83


^ permalink raw reply related	[relevance 71%]

* [PATCH v2] ASoC: Intel: avs: Use struct_size for struct avs_modcfg_ext size
@ 2023-03-03 18:04 72% Jacob Keller
  0 siblings, 0 replies; 24+ results
From: Jacob Keller @ 2023-03-03 18:04 UTC (permalink / raw)
  To: Mark Brown
  Cc: Cezary Rojewski, alsa-devel, Jacob Keller, Amadeusz Sławiński

The struct avs_modcfg_ext structure has a flexible array member for the
pin_fmts array, and the size should be calculated using struct_size to
prevent the potential for overflow with the allocation.

Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
Reviewed-by: "Amadeusz Sławiński" <amadeuszx.slawinski@linux.intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
 sound/soc/intel/avs/path.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
index 05302ab705ae..adbe23a47847 100644
--- a/sound/soc/intel/avs/path.c
+++ b/sound/soc/intel/avs/path.c
@@ -478,7 +478,7 @@ static int avs_modext_create(struct avs_dev *adev, struct avs_path_module *mod)
 	int ret, i;
 
 	num_pins = tcfg->generic.num_input_pins + tcfg->generic.num_output_pins;
-	cfg_size = sizeof(*cfg) + sizeof(*cfg->pin_fmts) * num_pins;
+	cfg_size = struct_size(cfg, pin_fmts, num_pins);
 
 	cfg = kzalloc(cfg_size, GFP_KERNEL);
 	if (!cfg)

base-commit: ee3f96b164688dae21e2466a57f2e806b64e8a37
-- 
2.39.1.405.gd4c25cc71f83


^ permalink raw reply related	[relevance 72%]

* Re: [PATCH] ASoC: Intel: avs: Use struct_size for struct avs_modcfg_ext size
  @ 2023-03-03 17:58 72%   ` Jacob Keller
  0 siblings, 0 replies; 24+ results
From: Jacob Keller @ 2023-03-03 17:58 UTC (permalink / raw)
  To: Cezary Rojewski; +Cc: alsa-devel, Amadeusz Sławiński, Mark Brown



On 3/3/2023 1:27 AM, Cezary Rojewski wrote:
> On 2023-03-01 9:46 PM, Jacob Keller wrote:
>> The struct avs_modcfg_ext structure has a flexible array member for the
>> pin_fmts array, and the size should be calculated using struct_size to
>> prevent the potential for overflow with the allocation.
>>
>> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
>> Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
>> Reviewed-by: "Amadeusz Sławiński" <amadeuszx.slawinski@linux.intel.com>
>> Cc: Mark Brown <broonie@kernel.org>
>> Cc: alsa-devel@alsa-project.org
> 
> 
> I've explicitly asked for the Signed-off-by to be the last line in the 
> tag area. Also, while I'm the author of the driver, nothing is being 
> merged by me - Mark is the maintainer for the ASoC subsystem, so you 
> should send messages to him and keep appropriate people/list in Cc 
> (email's Cc list, no need for every entry to be represented by an 
> equivalent 'Cc:' tag within a commit message simultaneously).
> 

Will fix in v2. Sorry about this, I wasn't aware what the convention
was. I am used to thinking about the tags in order of when the event
occurred, "I signed off that this is my work and can submit it first,
then it was reviewed". The Cc tags were there because it helps me keep
track of who to send the patch to but I can do that separately and drop
them from the commit message.

Thanks,
Jake

> TLDR:
> 
> Drop both CC tags, not needed. Have both Reviewed-by _before_ Signed-off-by.
> Then update the email's --cc/--to so that it reflects the actual 
> structure of the subsystem.
> 
>> ---
>>   sound/soc/intel/avs/path.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
>> index 05302ab705ae..adbe23a47847 100644
>> --- a/sound/soc/intel/avs/path.c
>> +++ b/sound/soc/intel/avs/path.c
>> @@ -478,7 +478,7 @@ static int avs_modext_create(struct avs_dev *adev, struct avs_path_module *mod)
>>   	int ret, i;
>>   
>>   	num_pins = tcfg->generic.num_input_pins + tcfg->generic.num_output_pins;
>> -	cfg_size = sizeof(*cfg) + sizeof(*cfg->pin_fmts) * num_pins;
>> +	cfg_size = struct_size(cfg, pin_fmts, num_pins);
>>   
>>   	cfg = kzalloc(cfg_size, GFP_KERNEL);
>>   	if (!cfg)
>>
>> base-commit: ee3f96b164688dae21e2466a57f2e806b64e8a37

^ permalink raw reply	[relevance 72%]

* Re: [PATCH 1/3] wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[]
  @ 2023-03-01 21:01 83%           ` Jacob Keller
  0 siblings, 0 replies; 24+ results
From: Jacob Keller @ 2023-03-01 21:01 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Kalle Valo, linux-wireless, Stanislav Yakovlev



On 3/1/2023 12:53 PM, Johannes Berg wrote:
> On Wed, 2023-03-01 at 12:49 -0800, Jacob Keller wrote:
>>
>> I can drop this one out of the series if you don't have an intention of
>> taking it, or I can refactor to just use size_add and array_size without
>> converting it to flexible array, which would prevent that coccinelle
>> patch from complaining and at least ensure that we can't overflow size
>> and under-allocate.
>>
>> Do you have a preference?
>>
> 
> Ah, it's up to Kalle, not me :-)
> 
> I think it's OK to do, and if it gets rid of drive-by submissions from
> the coccinelle patch later, I guess it's better to take it now. And you
> already have it anyway.
> 
> I might prefer though if you sent the drivers and cfg80211 patches
> separately, since that's usually Kalle vs. me applying it, and if it's
> in a same series we tend to end up wondering if there's a dependency or
> something, which is clearly not the case here.
> 
> johannes

Sure. I'll send them separately in v2.

Thanks,
Jake

^ permalink raw reply	[relevance 83%]

* Re: [PATCH 1/3] wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[]
    2023-02-28 17:48 83%       ` Jacob Keller
@ 2023-03-01 20:49 83%       ` Jacob Keller
    1 sibling, 1 reply; 24+ results
From: Jacob Keller @ 2023-03-01 20:49 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Kalle Valo, linux-wireless, Stanislav Yakovlev



On 2/28/2023 9:46 AM, Johannes Berg wrote:
> On Tue, 2023-02-28 at 09:44 -0800, Jacob Keller wrote:
>>
>> Previous to this change, error struct has two pointers to sections of
>> memory allocated at the end of the buffer.
>>
>> The code used to be:
>>
>> -	error = kmalloc(sizeof(*error) +
>> -			sizeof(*error->elem) * elem_len +
>> -			sizeof(*error->log) * log_len, GFP_ATOMIC);
>>
>> i.e. the elem_len is multiplying sizeof(*error->elem).
>>
>> The code is essentially trying to get two flexible arrays in the same
>> allocation, and its a bit messy to do that. I don't see how elem_len
>> could be anything other than "number of elems" given this code I removed.
> 
> Yeah, you're right. I was thinking of more modern HW/FW too much I
> guess, I see now even in the driver we have an array walk here (and it
> trusts the elem_len from firmware... ahrg!)
> 
>> I posted these mainly because I was trying to resolve all of the hits
>> that were found by the coccinelle patch I made, posted at [1]. I wanted
>> to get it to run clean so that we had no more struct_size hits.
>>
>> Dropping this would just make that patch have some hits until the driver
>> is removed, eventually...
>>
>> Not really a big deal to me, I just didn't want to post a coccinelle
>> patch without also trying to fix the handful of problems it reported,
>> since the total number of reports was small.
>>
> 
> Makes sense. I don't think we'll drop the driver at any point soon, but
> I also don't see it being changed much :)
> 
> johannes

I can drop this one out of the series if you don't have an intention of
taking it, or I can refactor to just use size_add and array_size without
converting it to flexible array, which would prevent that coccinelle
patch from complaining and at least ensure that we can't overflow size
and under-allocate.

Do you have a preference?

Thanks,
Jake

^ permalink raw reply	[relevance 83%]

* [PATCH] ASoC: Intel: avs: Use struct_size for struct avs_modcfg_ext size
@ 2023-03-01 20:46 72% Jacob Keller
    0 siblings, 1 reply; 24+ results
From: Jacob Keller @ 2023-03-01 20:46 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, Jacob Keller, Amadeusz Sławiński, Mark Brown

The struct avs_modcfg_ext structure has a flexible array member for the
pin_fmts array, and the size should be calculated using struct_size to
prevent the potential for overflow with the allocation.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
Reviewed-by: "Amadeusz Sławiński" <amadeuszx.slawinski@linux.intel.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: alsa-devel@alsa-project.org
---
 sound/soc/intel/avs/path.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
index 05302ab705ae..adbe23a47847 100644
--- a/sound/soc/intel/avs/path.c
+++ b/sound/soc/intel/avs/path.c
@@ -478,7 +478,7 @@ static int avs_modext_create(struct avs_dev *adev, struct avs_path_module *mod)
 	int ret, i;
 
 	num_pins = tcfg->generic.num_input_pins + tcfg->generic.num_output_pins;
-	cfg_size = sizeof(*cfg) + sizeof(*cfg->pin_fmts) * num_pins;
+	cfg_size = struct_size(cfg, pin_fmts, num_pins);
 
 	cfg = kzalloc(cfg_size, GFP_KERNEL);
 	if (!cfg)

base-commit: ee3f96b164688dae21e2466a57f2e806b64e8a37
-- 
2.39.1.405.gd4c25cc71f83


^ permalink raw reply related	[relevance 72%]

* Re: [PATCH 1/3] wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[]
  @ 2023-02-28 17:48 83%       ` Jacob Keller
  2023-03-01 20:49 83%       ` Jacob Keller
  1 sibling, 0 replies; 24+ results
From: Jacob Keller @ 2023-02-28 17:48 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Kalle Valo, linux-wireless, Stanislav Yakovlev



On 2/28/2023 9:46 AM, Johannes Berg wrote:
> On Tue, 2023-02-28 at 09:44 -0800, Jacob Keller wrote:
>>
>> Previous to this change, error struct has two pointers to sections of
>> memory allocated at the end of the buffer.
>>
>> The code used to be:
>>
>> -	error = kmalloc(sizeof(*error) +
>> -			sizeof(*error->elem) * elem_len +
>> -			sizeof(*error->log) * log_len, GFP_ATOMIC);
>>
>> i.e. the elem_len is multiplying sizeof(*error->elem).
>>
>> The code is essentially trying to get two flexible arrays in the same
>> allocation, and its a bit messy to do that. I don't see how elem_len
>> could be anything other than "number of elems" given this code I removed.
> 
> Yeah, you're right. I was thinking of more modern HW/FW too much I
> guess, I see now even in the driver we have an array walk here (and it
> trusts the elem_len from firmware... ahrg!)
> 

Ouch.. that makes me feel better about using struct_size/size_add here
since it would help protect against an overflow with a large element size...

^ permalink raw reply	[relevance 83%]

* Re: [PATCH 1/3] wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[]
  @ 2023-02-28 17:44 81%   ` Jacob Keller
    0 siblings, 1 reply; 24+ results
From: Jacob Keller @ 2023-02-28 17:44 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Kalle Valo, linux-wireless, Stanislav Yakovlev



On 2/28/2023 9:16 AM, Johannes Berg wrote:
> On Tue, 2023-02-28 at 08:28 -0800, Jacob Keller wrote:
>>
>> @@ -1247,7 +1247,6 @@ static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
>>  	error->config = priv->config;
>>  	error->elem_len = elem_len;
>>  	error->log_len = log_len;
>> -	error->elem = (struct ipw_error_elem *)error->payload;
>>  	error->log = (struct ipw_event *)(error->elem + elem_len);
> 
> I really don't know this driver, it's ancient, but that last line looks
> wrong to me already, elem_len doesn't seem like # of elems?
> 
> But I guess this patch changes nothing here, so hey. Don't think there's
> much value in the change either, this driver isn't going to get touched
> any more, just removed eventually ;)
> 
> johannes
> 

Previous to this change, error struct has two pointers to sections of
memory allocated at the end of the buffer.

The code used to be:

-	error = kmalloc(sizeof(*error) +
-			sizeof(*error->elem) * elem_len +
-			sizeof(*error->log) * log_len, GFP_ATOMIC);

i.e. the elem_len is multiplying sizeof(*error->elem).

The code is essentially trying to get two flexible arrays in the same
allocation, and its a bit messy to do that. I don't see how elem_len
could be anything other than "number of elems" given this code I removed.

I posted these mainly because I was trying to resolve all of the hits
that were found by the coccinelle patch I made, posted at [1]. I wanted
to get it to run clean so that we had no more struct_size hits.

Dropping this would just make that patch have some hits until the driver
is removed, eventually...

Not really a big deal to me, I just didn't want to post a coccinelle
patch without also trying to fix the handful of problems it reported,
since the total number of reports was small.

Thanks,
Jake

[1]:
https://lore.kernel.org/all/20230227202428.3657443-1-jacob.e.keller@intel.com/

^ permalink raw reply	[relevance 81%]

* Re: [PATCH 0/3] net: wireless: use struct_size where appropriate
  2023-02-28 16:22 72% [PATCH 0/3] net: wireless: use struct_size where appropriate Jacob Keller
@ 2023-02-28 16:29 72% ` Jacob Keller
  0 siblings, 0 replies; 24+ results
From: Jacob Keller @ 2023-02-28 16:29 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Kalle Valo, linux-wireless



On 2/28/2023 8:22 AM, Jacob Keller wrote:
> This series fixes a few wireless drivers to use struct_size rather than open
> coding some equivalent checks. This ensures that these size calculations
> will not overflow but instead be bounded at SIZE_MAX.
> 
> In the first case, the code is first converted to a flexible array, which
> saves a few bytes of memory in addition to the fix with struct_size.
> 
> These were caught with a coccinelle patch I recently posted at [1].
> 
> [1]: https://lore.kernel.org/all/20230227202428.3657443-1-jacob.e.keller@intel.com/
> 
> Cc: Johannes Berg <johannes@sipsolutions.net>
> Cc: linux-wireless@vger.kernel.org
> 
> Jacob Keller (3):
>   wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[]
>   wifi: cfg80211: use struct_size and size_sub for payload length
>   wifi: nl80211: convert cfg80211_scan_request allocation to *_size
>     macros
> 
>  drivers/net/wireless/intel/ipw2x00/ipw2200.c  |  7 +++--
>  drivers/net/wireless/intel/ipw2x00/ipw2200.h  |  3 +--
>  .../net/wireless/quantenna/qtnfmac/commands.c |  7 ++---
>  net/wireless/nl80211.c                        | 26 ++++++++++---------
>  4 files changed, 22 insertions(+), 21 deletions(-)
> 

ugh sorry for the spam.. the actual patches didn't get cc'd to
linux-wireless. I've fixed that now.

Thanks,
Jake

^ permalink raw reply	[relevance 72%]

* [PATCH 2/3] wifi: cfg80211: use struct_size and size_sub for payload length
  2023-02-28 16:28 73% [PATCH 1/3] wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[] Jacob Keller
@ 2023-02-28 16:28 72% ` Jacob Keller
    1 sibling, 0 replies; 24+ results
From: Jacob Keller @ 2023-02-28 16:28 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Kalle Valo, linux-wireless, Jacob Keller, Igor Mitsyanko,
	Sergey Matyukevich

Replace the calculations for the payload length in
qtnf_cmd_band_fill_iftype with struct_size() and size_sub(). While
the payload length does not get directly passed to an allocation function,
the performed calculation is still calculating the size of a flexible array
structure (minus the size of a header structure).

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Cc: Igor Mitsyanko <imitsyanko@quantenna.com>
Cc: Sergey Matyukevich <geomatsi@gmail.com>
---
 drivers/net/wireless/quantenna/qtnfmac/commands.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index b1b73478d89b..68ae9c7ea95a 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -1325,9 +1325,10 @@ static int qtnf_cmd_band_fill_iftype(const u8 *data,
 	struct ieee80211_sband_iftype_data *iftype_data;
 	const struct qlink_tlv_iftype_data *tlv =
 		(const struct qlink_tlv_iftype_data *)data;
-	size_t payload_len = tlv->n_iftype_data * sizeof(*tlv->iftype_data) +
-		sizeof(*tlv) -
-		sizeof(struct qlink_tlv_hdr);
+	size_t payload_len;
+
+	payload_len = struct_size(tlv, iftype_data, tlv->n_iftype_data);
+	payload_len = size_sub(payload_len, sizeof(struct qlink_tlv_hdr));
 
 	if (tlv->hdr.len != cpu_to_le16(payload_len)) {
 		pr_err("bad IFTYPE_DATA TLV len %u\n", tlv->hdr.len);
-- 
2.39.1.405.gd4c25cc71f83


^ permalink raw reply related	[relevance 72%]

* [PATCH 1/3] wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[]
@ 2023-02-28 16:28 73% Jacob Keller
  2023-02-28 16:28 72% ` [PATCH 2/3] wifi: cfg80211: use struct_size and size_sub for payload length Jacob Keller
    0 siblings, 2 replies; 24+ results
From: Jacob Keller @ 2023-02-28 16:28 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Kalle Valo, linux-wireless, Jacob Keller, Stanislav Yakovlev

The ipw_fw_error structure contains a payload[] flexible array as well as
two pointers to this array area, ->elem, and ->log. The total size of the
allocated structure is computed without use of the <linux/overflow.h>
macros.

There's no reason to keep both a payload[] and an extra pointer to both the
elem and log members. Convert the elem pointer member into the flexible
array member, removing payload.

Fix the allocation of the ipw_fw_error structure to use size_add(),
struct_size(), and array_size() to compute the allocation. This ensures
that any overflow saturates at SIZE_MAX rather than overflowing and
potentially allowing an undersized allocation.

Before the structure change, the layout of ipw_fw_error was:

struct ipw_fw_error {
        long unsigned int          jiffies;              /*     0     8 */
        u32                        status;               /*     8     4 */
        u32                        config;               /*    12     4 */
        u32                        elem_len;             /*    16     4 */
        u32                        log_len;              /*    20     4 */
        struct ipw_error_elem *    elem;                 /*    24     8 */
        struct ipw_event *         log;                  /*    32     8 */
        u8                         payload[];            /*    40     0 */

        /* size: 40, cachelines: 1, members: 8 */
        /* last cacheline: 40 bytes */
};

After this change, the layout is now:

struct ipw_fw_error {
        long unsigned int          jiffies;              /*     0     8 */
        u32                        status;               /*     8     4 */
        u32                        config;               /*    12     4 */
        u32                        elem_len;             /*    16     4 */
        u32                        log_len;              /*    20     4 */
        struct ipw_event *         log;                  /*    24     8 */
        struct ipw_error_elem      elem[];               /*    32     0 */

        /* size: 32, cachelines: 1, members: 7 */
        /* last cacheline: 32 bytes */
};

This saves a total of 8 bytes for every ipw_fw_error allocation, and
removes the risk of a potential overflow on the allocation.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Cc: Stanislav Yakovlev <stas.yakovlev@gmail.com>
---
 drivers/net/wireless/intel/ipw2x00/ipw2200.c | 7 +++----
 drivers/net/wireless/intel/ipw2x00/ipw2200.h | 3 +--
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
index d382f2017325..b91b1a2d0be7 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
@@ -1234,9 +1234,9 @@ static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
 	u32 base = ipw_read32(priv, IPW_ERROR_LOG);
 	u32 elem_len = ipw_read_reg32(priv, base);
 
-	error = kmalloc(sizeof(*error) +
-			sizeof(*error->elem) * elem_len +
-			sizeof(*error->log) * log_len, GFP_ATOMIC);
+	error = kmalloc(size_add(struct_size(error, elem, elem_len),
+				 array_size(sizeof(*error->log), log_len)),
+			GFP_ATOMIC);
 	if (!error) {
 		IPW_ERROR("Memory allocation for firmware error log "
 			  "failed.\n");
@@ -1247,7 +1247,6 @@ static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
 	error->config = priv->config;
 	error->elem_len = elem_len;
 	error->log_len = log_len;
-	error->elem = (struct ipw_error_elem *)error->payload;
 	error->log = (struct ipw_event *)(error->elem + elem_len);
 
 	ipw_capture_event_log(priv, log_len, error->log);
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.h b/drivers/net/wireless/intel/ipw2x00/ipw2200.h
index 09ddd21608d4..8ebf09121e17 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.h
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.h
@@ -1106,9 +1106,8 @@ struct ipw_fw_error {	 /* XXX */
 	u32 config;
 	u32 elem_len;
 	u32 log_len;
-	struct ipw_error_elem *elem;
 	struct ipw_event *log;
-	u8 payload[];
+	struct ipw_error_elem elem[];
 } __packed;
 
 #ifdef CONFIG_IPW2200_PROMISCUOUS
-- 
2.39.1.405.gd4c25cc71f83


^ permalink raw reply related	[relevance 73%]

* [PATCH 0/3] net: wireless: use struct_size where appropriate
@ 2023-02-28 16:22 72% Jacob Keller
  2023-02-28 16:29 72% ` Jacob Keller
  0 siblings, 1 reply; 24+ results
From: Jacob Keller @ 2023-02-28 16:22 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Kalle Valo, Jacob Keller, linux-wireless

This series fixes a few wireless drivers to use struct_size rather than open
coding some equivalent checks. This ensures that these size calculations
will not overflow but instead be bounded at SIZE_MAX.

In the first case, the code is first converted to a flexible array, which
saves a few bytes of memory in addition to the fix with struct_size.

These were caught with a coccinelle patch I recently posted at [1].

[1]: https://lore.kernel.org/all/20230227202428.3657443-1-jacob.e.keller@intel.com/

Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: linux-wireless@vger.kernel.org

Jacob Keller (3):
  wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[]
  wifi: cfg80211: use struct_size and size_sub for payload length
  wifi: nl80211: convert cfg80211_scan_request allocation to *_size
    macros

 drivers/net/wireless/intel/ipw2x00/ipw2200.c  |  7 +++--
 drivers/net/wireless/intel/ipw2x00/ipw2200.h  |  3 +--
 .../net/wireless/quantenna/qtnfmac/commands.c |  7 ++---
 net/wireless/nl80211.c                        | 26 ++++++++++---------
 4 files changed, 22 insertions(+), 21 deletions(-)

-- 
2.39.1.405.gd4c25cc71f83


^ permalink raw reply	[relevance 72%]

* RE: [PATCH 0/3] net: wireless: use struct_size where appropriate
  @ 2023-02-28 16:21 76%   ` Keller, Jacob E
  0 siblings, 0 replies; 24+ results
From: Keller, Jacob E @ 2023-02-28 16:21 UTC (permalink / raw)
  To: Kalle Valo; +Cc: Johannes Berg, linux-wireless



> -----Original Message-----
> From: Kalle Valo <kvalo@kernel.org>
> Sent: Monday, February 27, 2023 10:24 PM
> To: Keller, Jacob E <jacob.e.keller@intel.com>
> Cc: Johannes Berg <johannes@sipsolutions.net>; linux-wireless@vger.kernel.org
> Subject: Re: [PATCH 0/3] net: wireless: use struct_size where appropriate
> 
> Jacob Keller <jacob.e.keller@intel.com> writes:
> 
> > This series fixes a few wireless drivers to use struct_size rather than open
> > coding some equivalent checks. This ensures that these size calculations
> > will not overflow but instead be bounded at SIZE_MAX.
> >
> > In the first case, the code is first converted to a flexible array, which
> > saves a few bytes of memory in addition to the fix with struct_size.
> >
> > These were caught with a coccinelle patch I recently posted at [1].
> >
> > [1]: https://lore.kernel.org/all/20230227202428.3657443-1-
> jacob.e.keller@intel.com/
> >
> > Cc: Johannes Berg <johannes@sipsolutions.net>
> > Cc: linux-wireless@vger.kernel.org
> >
> > Jacob Keller (3):
> >   wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[]
> >   wifi: cfg80211: use struct_size and size_sub for payload length
> >   wifi: nl80211: convert cfg80211_scan_request allocation to *_size
> >     macros
> >
> >  drivers/net/wireless/intel/ipw2x00/ipw2200.c  |  7 +++--
> >  drivers/net/wireless/intel/ipw2x00/ipw2200.h  |  3 +--
> >  .../net/wireless/quantenna/qtnfmac/commands.c |  7 ++---
> >  net/wireless/nl80211.c                        | 26 ++++++++++---------
> >  4 files changed, 22 insertions(+), 21 deletions(-)
> 
> I don't see the actual patches, only the cover letter. Also nothing on
> patchwork:
> 
> https://patchwork.kernel.org/project/linux-wireless/list/?state=*
> 

Hmm.. Let me resend.

Thanks,
Jake

> --
> https://patchwork.kernel.org/project/linux-wireless/list/
> 
> https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatch
> es

^ permalink raw reply	[relevance 76%]

* [PATCH] vhost: use struct_size and size_add to compute flex array sizes
@ 2023-02-27 21:41 70% ` Jacob Keller
  0 siblings, 0 replies; 24+ results
From: Jacob Keller @ 2023-02-27 21:41 UTC (permalink / raw)
  To: kvm; +Cc: Jacob Keller, virtualization, Michael S. Tsirkin

The vhost_get_avail_size and vhost_get_used_size functions compute the size
of structures with flexible array members with an additional 2 bytes if the
VIRTIO_RING_F_EVENT_IDX feature flag is set. Convert these functions to use
struct_size() and size_add() instead of coding the calculation by hand.

This ensures that the calculations will saturate at SIZE_MAX rather than
overflowing.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: virtualization@lists.linux-foundation.org
Cc: kvm@vger.kernel.org
---

I found this using a coccinelle patch I developed and submitted at [1].

[1]: https://lore.kernel.org/all/20230227202428.3657443-1-jacob.e.keller@intel.com/

 drivers/vhost/vhost.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index f11bdbe4c2c5..43fa626d4e44 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -436,8 +436,7 @@ static size_t vhost_get_avail_size(struct vhost_virtqueue *vq,
 	size_t event __maybe_unused =
 	       vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0;
 
-	return sizeof(*vq->avail) +
-	       sizeof(*vq->avail->ring) * num + event;
+	return size_add(struct_size(vq->avail, ring, num), event);
 }
 
 static size_t vhost_get_used_size(struct vhost_virtqueue *vq,
@@ -446,8 +445,7 @@ static size_t vhost_get_used_size(struct vhost_virtqueue *vq,
 	size_t event __maybe_unused =
 	       vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0;
 
-	return sizeof(*vq->used) +
-	       sizeof(*vq->used->ring) * num + event;
+	return size_add(struct_size(vq->used, ring, num), event);
 }
 
 static size_t vhost_get_desc_size(struct vhost_virtqueue *vq,
-- 
2.39.1.405.gd4c25cc71f83

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[relevance 70%]

* [PATCH] vhost: use struct_size and size_add to compute flex array sizes
@ 2023-02-27 21:41 70% ` Jacob Keller
  0 siblings, 0 replies; 24+ results
From: Jacob Keller @ 2023-02-27 21:41 UTC (permalink / raw)
  To: kvm; +Cc: Jacob Keller, Michael S. Tsirkin, Jason Wang, virtualization

The vhost_get_avail_size and vhost_get_used_size functions compute the size
of structures with flexible array members with an additional 2 bytes if the
VIRTIO_RING_F_EVENT_IDX feature flag is set. Convert these functions to use
struct_size() and size_add() instead of coding the calculation by hand.

This ensures that the calculations will saturate at SIZE_MAX rather than
overflowing.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: virtualization@lists.linux-foundation.org
Cc: kvm@vger.kernel.org
---

I found this using a coccinelle patch I developed and submitted at [1].

[1]: https://lore.kernel.org/all/20230227202428.3657443-1-jacob.e.keller@intel.com/

 drivers/vhost/vhost.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index f11bdbe4c2c5..43fa626d4e44 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -436,8 +436,7 @@ static size_t vhost_get_avail_size(struct vhost_virtqueue *vq,
 	size_t event __maybe_unused =
 	       vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0;
 
-	return sizeof(*vq->avail) +
-	       sizeof(*vq->avail->ring) * num + event;
+	return size_add(struct_size(vq->avail, ring, num), event);
 }
 
 static size_t vhost_get_used_size(struct vhost_virtqueue *vq,
@@ -446,8 +445,7 @@ static size_t vhost_get_used_size(struct vhost_virtqueue *vq,
 	size_t event __maybe_unused =
 	       vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0;
 
-	return sizeof(*vq->used) +
-	       sizeof(*vq->used->ring) * num + event;
+	return size_add(struct_size(vq->used, ring, num), event);
 }
 
 static size_t vhost_get_desc_size(struct vhost_virtqueue *vq,
-- 
2.39.1.405.gd4c25cc71f83


^ permalink raw reply related	[relevance 70%]

* [PATCH 0/3] net: wireless: use struct_size where appropriate
@ 2023-02-27 20:39 72% Jacob Keller
    0 siblings, 1 reply; 24+ results
From: Jacob Keller @ 2023-02-27 20:39 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Jacob Keller, linux-wireless

This series fixes a few wireless drivers to use struct_size rather than open
coding some equivalent checks. This ensures that these size calculations
will not overflow but instead be bounded at SIZE_MAX.

In the first case, the code is first converted to a flexible array, which
saves a few bytes of memory in addition to the fix with struct_size.

These were caught with a coccinelle patch I recently posted at [1].

[1]: https://lore.kernel.org/all/20230227202428.3657443-1-jacob.e.keller@intel.com/

Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: linux-wireless@vger.kernel.org

Jacob Keller (3):
  wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[]
  wifi: cfg80211: use struct_size and size_sub for payload length
  wifi: nl80211: convert cfg80211_scan_request allocation to *_size
    macros

 drivers/net/wireless/intel/ipw2x00/ipw2200.c  |  7 +++--
 drivers/net/wireless/intel/ipw2x00/ipw2200.h  |  3 +--
 .../net/wireless/quantenna/qtnfmac/commands.c |  7 ++---
 net/wireless/nl80211.c                        | 26 ++++++++++---------
 4 files changed, 22 insertions(+), 21 deletions(-)

-- 
2.39.1.405.gd4c25cc71f83


^ permalink raw reply	[relevance 72%]

* [PATCH] coccinelle: semantic patch to check for potential struct_size calls
@ 2023-02-27 20:24 65% Jacob Keller
      0 siblings, 2 replies; 24+ results
From: Jacob Keller @ 2023-02-27 20:24 UTC (permalink / raw)
  To: Julia Lawall
  Cc: Jacob Keller, Kees Cook, Gustavo A . R . Silva, cocci, linux-kernel

include/linux/overflow.h includes helper macros intended for calculating
sizes of allocations. These macros prevent accidental overflow by
saturating at SIZE_MAX.

In general when calculating such sizes use of the macros is preferred. Add
a semantic patch which can detect code patterns which can be replaced by
struct_size.

Note that I set the confidence to medium because this patch doesn't make an
attempt to ensure that the relevant array is actually a flexible array. The
struct_size macro does specifically require a flexible array. In many cases
the detected code could be refactored to a flexible array, but this is not
always possible (such as if there are multiple over-allocations).

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Cc: Julia Lawall <Julia.Lawall@lip6.fr>
Cc: Kees Cook <keescook@chromium.org>
Cc: Gustavo A. R. Silva <gustavoars@kernel.org>
Cc: cocci@systeme.lip6.fr
Cc: linux-kernel@vger.kernel.org

 scripts/coccinelle/misc/struct_size.cocci | 74 +++++++++++++++++++++++
 1 file changed, 74 insertions(+)
 create mode 100644 scripts/coccinelle/misc/struct_size.cocci

diff --git a/scripts/coccinelle/misc/struct_size.cocci b/scripts/coccinelle/misc/struct_size.cocci
new file mode 100644
index 000000000000..4ede9586e3c6
--- /dev/null
+++ b/scripts/coccinelle/misc/struct_size.cocci
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-only
+///
+/// Check for code that could use struct_size().
+///
+// Confidence: Medium
+// Author: Jacob Keller <jacob.e.keller@intel.com>
+// Copyright: (C) 2023 Intel Corporation
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+// the overflow Kunit tests have some code which intentionally does not use
+// the macros, so we want to ignore this code when reporting potential
+// issues.
+@overflow_tests@
+identifier f = overflow_size_helpers_test;
+@@
+
+f
+
+//----------------------------------------------------------
+//  For context mode
+//----------------------------------------------------------
+
+@depends on !overflow_tests && context@
+expression E1, E2;
+identifier m;
+@@
+(
+* (sizeof(*E1) + (E2 * sizeof(*E1->m)))
+)
+
+//----------------------------------------------------------
+//  For patch mode
+//----------------------------------------------------------
+
+@depends on !overflow_tests && patch@
+expression E1, E2;
+identifier m;
+@@
+(
+- (sizeof(*E1) + (E2 * sizeof(*E1->m)))
++ struct_size(E1, m, E2)
+)
+
+//----------------------------------------------------------
+//  For org and report mode
+//----------------------------------------------------------
+
+@r depends on !overflow_tests && (org || report)@
+expression E1, E2;
+identifier m;
+position p;
+@@
+(
+ (sizeof(*E1)@p + (E2 * sizeof(*E1->m)))
+)
+
+@script:python depends on org@
+p << r.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING should use struct_size")
+
+@script:python depends on report@
+p << r.p;
+@@
+
+msg="WARNING: Use struct_size"
+coccilib.report.print_report(p[0], msg)
+

base-commit: 982818426a0ffaf93b0621826ed39a84be3d7d62
-- 
2.39.1.405.gd4c25cc71f83


^ permalink raw reply related	[relevance 65%]

* [PATCH -next] mux: convert mux_chip->mux to flexible array
@ 2023-02-23  1:42 68% Jacob Keller
    0 siblings, 1 reply; 24+ results
From: Jacob Keller @ 2023-02-23  1:42 UTC (permalink / raw)
  To: Peter Rosin; +Cc: linux-kernel, Jacob Keller

The mux_chip structure size is over allocated to additionally include both
the array of mux controllers as well as a device specific private area.
The controllers array is then pointed to by assigning mux_chip->mux to the
first block of extra memory, while the private area is extracted via
mux_chip_priv() and points to the area just after the controllers.

The size of the mux_chip allocation uses direct multiplication and addition
rather than the <linux/overflow.h> helpers. In addition, the mux_chip->mux
struct member wastes space by having to store the pointer as part of the
structures.

Convert struct mux_chip to use a flexible array member for the mux
controller array. Use struct_size() and size_add() to compute the size of
the structure while protecting against overflow.

After converting the mux pointer, notice that two 4-byte holes remain in
the structure layout due to the alignment requirements for the dev
sub-structure and the ops pointer.

These can be easily fixed through re-ordering the id field to the 4-byte
hole just after the controllers member.

This changes the layout from:

struct mux_chip {
        unsigned int               controllers;          /*     0     4 */

        /* XXX 4 bytes hole, try to pack */

        struct mux_control *       mux;                  /*     8     8 */
        struct device              dev __attribute__((__aligned__(8))); /*    16  1400 */

        /* XXX last struct has 3 bytes of padding */

        /* --- cacheline 22 boundary (1408 bytes) was 8 bytes ago --- */
        int                        id;                   /*  1416     4 */

        /* XXX 4 bytes hole, try to pack */

        const struct mux_control_ops  * ops;             /*  1424     8 */

        /* size: 1432, cachelines: 23, members: 5 */
        /* sum members: 1424, holes: 2, sum holes: 8 */
        /* paddings: 1, sum paddings: 3 */
        /* forced alignments: 1 */
        /* last cacheline: 24 bytes */
} __attribute__((__aligned__(8)));

To the following:

struct mux_chip {
        unsigned int               controllers;          /*     0     4 */
        int                        id;                   /*     4     4 */
        struct device              dev __attribute__((__aligned__(8))); /*     8  1400 */

        /* XXX last struct has 3 bytes of padding */

        /* --- cacheline 22 boundary (1408 bytes) --- */
        const struct mux_control_ops  * ops;             /*  1408     8 */
        struct mux_control         mux[];                /*  1416     0 */

        /* size: 1416, cachelines: 23, members: 5 */
        /* paddings: 1, sum paddings: 3 */
        /* forced alignments: 1 */
        /* last cacheline: 8 bytes */
} __attribute__((__aligned__(8)));

This both removes risk of overflowing and performing an under-allocation,
as well as saves 16 bytes of otherwise wasted space for every mux_chip.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
 drivers/mux/core.c         |  7 +++----
 include/linux/mux/driver.h | 10 +++++-----
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/mux/core.c b/drivers/mux/core.c
index 49bedbe6316c..3e26b9911cc2 100644
--- a/drivers/mux/core.c
+++ b/drivers/mux/core.c
@@ -100,13 +100,12 @@ struct mux_chip *mux_chip_alloc(struct device *dev,
 	if (WARN_ON(!dev || !controllers))
 		return ERR_PTR(-EINVAL);
 
-	mux_chip = kzalloc(sizeof(*mux_chip) +
-			   controllers * sizeof(*mux_chip->mux) +
-			   sizeof_priv, GFP_KERNEL);
+	mux_chip = kzalloc(size_add(struct_size(mux_chip, mux, controllers),
+				    sizeof_priv),
+			   GFP_KERNEL);
 	if (!mux_chip)
 		return ERR_PTR(-ENOMEM);
 
-	mux_chip->mux = (struct mux_control *)(mux_chip + 1);
 	mux_chip->dev.class = &mux_class;
 	mux_chip->dev.type = &mux_type;
 	mux_chip->dev.parent = dev;
diff --git a/include/linux/mux/driver.h b/include/linux/mux/driver.h
index 18824064f8c0..84dc0d3e79d6 100644
--- a/include/linux/mux/driver.h
+++ b/include/linux/mux/driver.h
@@ -56,18 +56,18 @@ struct mux_control {
 /**
  * struct mux_chip -	Represents a chip holding mux controllers.
  * @controllers:	Number of mux controllers handled by the chip.
- * @mux:		Array of mux controllers that are handled.
- * @dev:		Device structure.
  * @id:			Used to identify the device internally.
+ * @dev:		Device structure.
  * @ops:		Mux controller operations.
+ * @mux:		Flexible array of mux controllers that are handled.
  */
 struct mux_chip {
 	unsigned int controllers;
-	struct mux_control *mux;
-	struct device dev;
 	int id;
-
+	struct device dev;
 	const struct mux_control_ops *ops;
+
+	struct mux_control mux[];
 };
 
 #define to_mux_chip(x) container_of((x), struct mux_chip, dev)

base-commit: 307e14c039063f0c9bd7a18a7add8f940580dcc9
-- 
I found this while developing a coccinelle patch that helps detect potential
code that could be converted to struct_size() and noticed this weird case
that could be a flexible array and save memory.

2.39.1.405.gd4c25cc71f83


^ permalink raw reply related	[relevance 68%]

* [PATCH] drm/rockchip: use struct_size() in vop2_bind
@ 2023-02-23  1:35 72% Jacob Keller
  0 siblings, 0 replies; 24+ results
From: Jacob Keller @ 2023-02-23  1:35 UTC (permalink / raw)
  To: dri-devel; +Cc: Jacob Keller, Sandy Huang

Use the overflow-protected struct_size() helper macro to compute the
allocation size of the vop2 data structure.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Cc: Sandy Huang <hjc@rock-chips.com>
Cc: Heiko Stübner <heiko@sntech.de>
Cc: David Airlie <airlied@gmail.com>
---
I found this while developing a coccinelle script to detect potential places
where struct_size() would be appropriate.

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0e0012368976..3e5861653b69 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2655,7 +2655,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 		return -ENODEV;
 
 	/* Allocate vop2 struct and its vop2_win array */
-	alloc_size = sizeof(*vop2) + sizeof(*vop2->win) * vop2_data->win_size;
+	alloc_size = struct_size(vop2, win, vop2_data->win_size);
 	vop2 = devm_kzalloc(dev, alloc_size, GFP_KERNEL);
 	if (!vop2)
 		return -ENOMEM;

base-commit: 4d5a2cce47a8e1e7119a881a4714f0eee557c1cd
-- 
2.39.1.405.gd4c25cc71f83


^ permalink raw reply related	[relevance 72%]

Results 1-24 of 24 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2023-02-23  1:35 72% [PATCH] drm/rockchip: use struct_size() in vop2_bind Jacob Keller
2023-02-23  1:42 68% [PATCH -next] mux: convert mux_chip->mux to flexible array Jacob Keller
2023-02-27 20:28     ` Jesse Brandeburg
2024-02-19  5:04       ` Kees Cook
2024-02-20 21:27 83%     ` Jacob Keller
2023-02-27 20:24 65% [PATCH] coccinelle: semantic patch to check for potential struct_size calls Jacob Keller
2023-08-27  1:19     ` Kees Cook
2023-08-29 19:25 72%   ` Jacob Keller
2024-01-16  7:03     ` Dan Carpenter
2024-01-17 21:54 76%   ` Keller, Jacob E
2023-02-27 20:39 72% [PATCH 0/3] net: wireless: use struct_size where appropriate Jacob Keller
2023-02-28  6:24     ` Kalle Valo
2023-02-28 16:21 76%   ` Keller, Jacob E
2023-02-27 21:41 70% [PATCH] vhost: use struct_size and size_add to compute flex array sizes Jacob Keller
2023-02-27 21:41 70% ` Jacob Keller
2023-02-28 16:22 72% [PATCH 0/3] net: wireless: use struct_size where appropriate Jacob Keller
2023-02-28 16:29 72% ` Jacob Keller
2023-02-28 16:28 73% [PATCH 1/3] wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[] Jacob Keller
2023-02-28 16:28 72% ` [PATCH 2/3] wifi: cfg80211: use struct_size and size_sub for payload length Jacob Keller
2023-02-28 17:16     ` [PATCH 1/3] wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[] Johannes Berg
2023-02-28 17:44 81%   ` Jacob Keller
2023-02-28 17:46         ` Johannes Berg
2023-02-28 17:48 83%       ` Jacob Keller
2023-03-01 20:49 83%       ` Jacob Keller
2023-03-01 20:53             ` Johannes Berg
2023-03-01 21:01 83%           ` Jacob Keller
2023-03-01 20:46 72% [PATCH] ASoC: Intel: avs: Use struct_size for struct avs_modcfg_ext size Jacob Keller
2023-03-03  9:27     ` Cezary Rojewski
2023-03-03 17:58 72%   ` Jacob Keller
2023-03-03 18:04 72% [PATCH v2] " Jacob Keller
2023-03-07 23:01 71% [PATCH v2] wifi: ipw2x00: convert ipw_fw_error->elem to flexible array[] Jacob Keller
2023-03-07 23:02 70% [PATCH v2] wifi: qtnfmac: use struct_size and size_sub for payload length Jacob Keller
2024-02-26 21:29 68% [PATCH v2] mux: convert mux_chip->mux to flexible array Jacob Keller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.