Message ID | ZSRzrIe0345eymk2@work |
---|---|
State | New |
Headers | show |
Series | [next] wifi: brcmfmac: fweh: Add __counted_by for struct brcmf_fweh_queue_item and use struct_size() | expand |
On Mon, Oct 09, 2023 at 03:42:04PM -0600, Gustavo A. R. Silva wrote: > Prepare for the coming implementation by GCC and Clang of the __counted_by > attribute. Flexible array members annotated with __counted_by can have > their accesses bounds-checked at run-time via CONFIG_UBSAN_BOUNDS (for > array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family > functions). > > Also, relocate `event->datalen = datalen;` to before calling > `memcpy(event->data, data, datalen);`, so that the __counted_by > annotation has effect, and flex-array member `data` can be properly > bounds-checked at run-time. > > While there, use struct_size() helper, instead of the open-coded > version, to calculate the size for the allocation of the whole > flexible structure, including of course, the flexible-array member. > > This code was found with the help of Coccinelle, and audited and > fixed manually. > > Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org> Yeah, looks right. Thanks for moving the count assignment. Reviewed-by: Kees Cook <keescook@chromium.org> -Kees > --- > drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c > index dac7eb77799b..68960ae98987 100644 > --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c > +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c > @@ -33,7 +33,7 @@ struct brcmf_fweh_queue_item { > u8 ifaddr[ETH_ALEN]; > struct brcmf_event_msg_be emsg; > u32 datalen; > - u8 data[]; > + u8 data[] __counted_by(datalen); > }; > > /* > @@ -418,17 +418,17 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr, > datalen + sizeof(*event_packet) > packet_len) > return; > > - event = kzalloc(sizeof(*event) + datalen, gfp); > + event = kzalloc(struct_size(event, data, datalen), gfp); > if (!event) > return; > > + event->datalen = datalen; > event->code = code; > event->ifidx = event_packet->msg.ifidx; > > /* use memcpy to get aligned event message */ > memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); > memcpy(event->data, data, datalen); > - event->datalen = datalen; > memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN); > > brcmf_fweh_queue_event(fweh, event); > -- > 2.34.1 > >
"Gustavo A. R. Silva" <gustavoars@kernel.org> wrote: > Prepare for the coming implementation by GCC and Clang of the __counted_by > attribute. Flexible array members annotated with __counted_by can have > their accesses bounds-checked at run-time via CONFIG_UBSAN_BOUNDS (for > array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family > functions). > > Also, relocate `event->datalen = datalen;` to before calling > `memcpy(event->data, data, datalen);`, so that the __counted_by > annotation has effect, and flex-array member `data` can be properly > bounds-checked at run-time. > > While there, use struct_size() helper, instead of the open-coded > version, to calculate the size for the allocation of the whole > flexible structure, including of course, the flexible-array member. > > This code was found with the help of Coccinelle, and audited and > fixed manually. > > Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org> > Reviewed-by: Kees Cook <keescook@chromium.org> > Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> Patch applied to wireless-next.git, thanks. 62d19b358088 wifi: brcmfmac: fweh: Add __counted_by for struct brcmf_fweh_queue_item and use struct_size()
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c index dac7eb77799b..68960ae98987 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c @@ -33,7 +33,7 @@ struct brcmf_fweh_queue_item { u8 ifaddr[ETH_ALEN]; struct brcmf_event_msg_be emsg; u32 datalen; - u8 data[]; + u8 data[] __counted_by(datalen); }; /* @@ -418,17 +418,17 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr, datalen + sizeof(*event_packet) > packet_len) return; - event = kzalloc(sizeof(*event) + datalen, gfp); + event = kzalloc(struct_size(event, data, datalen), gfp); if (!event) return; + event->datalen = datalen; event->code = code; event->ifidx = event_packet->msg.ifidx; /* use memcpy to get aligned event message */ memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); memcpy(event->data, data, datalen); - event->datalen = datalen; memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN); brcmf_fweh_queue_event(fweh, event);
Prepare for the coming implementation by GCC and Clang of the __counted_by attribute. Flexible array members annotated with __counted_by can have their accesses bounds-checked at run-time via CONFIG_UBSAN_BOUNDS (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family functions). Also, relocate `event->datalen = datalen;` to before calling `memcpy(event->data, data, datalen);`, so that the __counted_by annotation has effect, and flex-array member `data` can be properly bounds-checked at run-time. While there, use struct_size() helper, instead of the open-coded version, to calculate the size for the allocation of the whole flexible structure, including of course, the flexible-array member. This code was found with the help of Coccinelle, and audited and fixed manually. Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org> --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)