All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: linux-kernel@vger.kernel.org, Kalle Valo <kvalo@codeaurora.org>,
	"David S. Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
	linux-hardening@vger.kernel.org
Subject: Re: [PATCH v2 2/2][next] wl3501_cs: Fix out-of-bounds warning in wl3501_mgmt_join
Date: Wed, 7 Apr 2021 12:02:00 -0700	[thread overview]
Message-ID: <202104071158.B4FA1956@keescook> (raw)
In-Reply-To: <83b0388403a61c01fad8d638db40b4245666ff53.1617226664.git.gustavoars@kernel.org>

On Wed, Mar 31, 2021 at 04:45:34PM -0500, Gustavo A. R. Silva wrote:
> Fix the following out-of-bounds warning by enclosing
> some structure members into new struct req:
> 
> arch/x86/include/asm/string_32.h:182:25: warning: '__builtin_memcpy' offset [39, 108] from the object at 'sig' is out of the bounds of referenced subobject 'beacon_period' with type 'short unsigned int' at offset 36 [-Warray-bounds]
> 
> Refactor the code, accordingly:
> 
> $ pahole -C wl3501_join_req drivers/net/wireless/wl3501_cs.o
> struct wl3501_join_req {
> 	u16                        next_blk;             /*     0     2 */
> 	u8                         sig_id;               /*     2     1 */
> 	u8                         reserved;             /*     3     1 */
> 	struct iw_mgmt_data_rset   operational_rset;     /*     4    10 */
> 	u16                        reserved2;            /*    14     2 */
> 	u16                        timeout;              /*    16     2 */
> 	u16                        probe_delay;          /*    18     2 */
> 	u8                         timestamp[8];         /*    20     8 */
> 	u8                         local_time[8];        /*    28     8 */
> 	struct {
> 		u16                beacon_period;        /*    36     2 */
> 		u16                dtim_period;          /*    38     2 */
> 		u16                cap_info;             /*    40     2 */
> 		u8                 bss_type;             /*    42     1 */
> 		u8                 bssid[6];             /*    43     6 */
> 		struct iw_mgmt_essid_pset ssid;          /*    49    34 */
> 		/* --- cacheline 1 boundary (64 bytes) was 19 bytes ago --- */
> 		struct iw_mgmt_ds_pset ds_pset;          /*    83     3 */
> 		struct iw_mgmt_cf_pset cf_pset;          /*    86     8 */
> 		struct iw_mgmt_ibss_pset ibss_pset;      /*    94     4 */
> 		struct iw_mgmt_data_rset bss_basic_rset; /*    98    10 */
> 	} req;                                           /*    36    72 */

This section is the same as a large portion of struct wl3501_scan_confirm:

struct wl3501_scan_confirm {
        u16                         next_blk;
        u8                          sig_id;
        u8                          reserved;
        u16                         status;
        char                        timestamp[8];
        char                        localtime[8];

from here
        u16                         beacon_period;
        u16                         dtim_period;
        u16                         cap_info;
        u8                          bss_type;
        u8                          bssid[ETH_ALEN];
        struct iw_mgmt_essid_pset   ssid;
        struct iw_mgmt_ds_pset      ds_pset;
        struct iw_mgmt_cf_pset      cf_pset;
        struct iw_mgmt_ibss_pset    ibss_pset;
        struct iw_mgmt_data_rset    bss_basic_rset;
through here

        u8                          rssi;
};

It seems like maybe extracting that and using it in both structures
would make more sense?

> 
> 	/* size: 108, cachelines: 2, members: 10 */
> 	/* last cacheline: 44 bytes */
> };
> 
> The problem is that the original code is trying to copy data into a
> bunch of struct members adjacent to each other in a single call to
> memcpy(). Now that a new struct _req_ enclosing all those adjacent
> members is introduced, memcpy() doesn't overrun the length of
> &sig.beacon_period, because the address of the new struct object
> _req_ is used as the destination, instead.
> 
> Also, this helps with the ongoing efforts to enable -Warray-bounds and
> avoid confusing the compiler.
> 
> Link: https://github.com/KSPP/linux/issues/109
> Reported-by: kernel test robot <lkp@intel.com>
> Build-tested-by: kernel test robot <lkp@intel.com>
> Link: https://lore.kernel.org/lkml/60641d9b.2eNLedOGSdcSoAV2%25lkp@intel.com/
> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> ---
> Changes in v2:
>  - None.
> 
>  drivers/net/wireless/wl3501.h    | 22 ++++++++++++----------
>  drivers/net/wireless/wl3501_cs.c |  4 ++--
>  2 files changed, 14 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
> index ef9d605d8c88..774d8cac046d 100644
> --- a/drivers/net/wireless/wl3501.h
> +++ b/drivers/net/wireless/wl3501.h
> @@ -389,16 +389,18 @@ struct wl3501_join_req {
>  	u16			    probe_delay;
>  	u8			    timestamp[8];
>  	u8			    local_time[8];
> -	u16			    beacon_period;
> -	u16			    dtim_period;
> -	u16			    cap_info;
> -	u8			    bss_type;
> -	u8			    bssid[ETH_ALEN];
> -	struct iw_mgmt_essid_pset   ssid;
> -	struct iw_mgmt_ds_pset	    ds_pset;
> -	struct iw_mgmt_cf_pset	    cf_pset;
> -	struct iw_mgmt_ibss_pset    ibss_pset;
> -	struct iw_mgmt_data_rset    bss_basic_rset;
> +	struct {
> +		u16			    beacon_period;
> +		u16			    dtim_period;
> +		u16			    cap_info;
> +		u8			    bss_type;
> +		u8			    bssid[ETH_ALEN];
> +		struct iw_mgmt_essid_pset   ssid;
> +		struct iw_mgmt_ds_pset	    ds_pset;
> +		struct iw_mgmt_cf_pset	    cf_pset;
> +		struct iw_mgmt_ibss_pset    ibss_pset;
> +		struct iw_mgmt_data_rset    bss_basic_rset;
> +	} req;
>  };
>  
>  struct wl3501_join_confirm {
> diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
> index e149ef81d6cc..399d3bd2ae76 100644
> --- a/drivers/net/wireless/wl3501_cs.c
> +++ b/drivers/net/wireless/wl3501_cs.c
> @@ -590,7 +590,7 @@ static int wl3501_mgmt_join(struct wl3501_card *this, u16 stas)
>  	struct wl3501_join_req sig = {
>  		.sig_id		  = WL3501_SIG_JOIN_REQ,
>  		.timeout	  = 10,
> -		.ds_pset = {
> +		.req.ds_pset = {
>  			.el = {
>  				.id  = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
>  				.len = 1,
> @@ -599,7 +599,7 @@ static int wl3501_mgmt_join(struct wl3501_card *this, u16 stas)
>  		},
>  	};
>  
> -	memcpy(&sig.beacon_period, &this->bss_set[stas].beacon_period, 72);
> +	memcpy(&sig.req, &this->bss_set[stas].beacon_period, sizeof(sig.req));

If not, then probably something like this should be added to make sure
nothing unexpected happens to change structure sizes:

BUILD_BUG_ON(sizeof(sig.req) != 72);

>  	return wl3501_esbq_exec(this, &sig, sizeof(sig));
>  }
>  
> -- 
> 2.27.0
> 

-- 
Kees Cook

  reply	other threads:[~2021-04-07 19:02 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-31 21:43 [PATCH v2 0/2][next] wl3501_cs: Fix out-of-bounds warnings Gustavo A. R. Silva
2021-03-31 21:44 ` [PATCH v2 1/2][next] wl3501_cs: Fix out-of-bounds warning in wl3501_send_pkt Gustavo A. R. Silva
2021-04-07 18:56   ` Kees Cook
2021-03-31 21:45 ` [PATCH v2 2/2][next] wl3501_cs: Fix out-of-bounds warning in wl3501_mgmt_join Gustavo A. R. Silva
2021-04-07 19:02   ` Kees Cook [this message]
2021-04-13 21:25     ` Gustavo A. R. Silva
2021-04-13 21:27 ` [PATCH v2 0/2][next] wl3501_cs: Fix out-of-bounds warnings Gustavo A. R. Silva
2021-04-14  6:51   ` Kalle Valo
2021-04-15  0:00     ` Gustavo A. R. Silva

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=202104071158.B4FA1956@keescook \
    --to=keescook@chromium.org \
    --cc=davem@davemloft.net \
    --cc=gustavoars@kernel.org \
    --cc=kuba@kernel.org \
    --cc=kvalo@codeaurora.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.