wifi: brcmfmac: fweh: Add __counted_by for struct brcmf_fweh_queue_item and use struct_size()
PATCH 1/1 wifi: brcmfmac: fweh: Add __counted_by for struct brcmf_fweh_queue_item and use struct_size()
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.
--- drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +3 -3
@@ -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);
Signature · 1 line
2.34.1
Quoted 11 lines · Gustavo A. R. Silva
Prepare for the coming implementation by GCC and Clang of the
__counted_byattribute. Flexible array members annotated with__counted_bycan have their accesses bounds-checked at run-time viaCONFIG_UBSAN_BOUNDS(for array indexing) andCONFIG_FORTIFY_SOURCE(for strcpy/memcpy-family functions).Also, relocate
event->datalen = datalen;to before callingmemcpy(event->data, data, datalen);, so that the__counted_byannotation has effect, and flex-array memberdatacan be properly bounds-checked at run-time.
Quoted 8 lines
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 <[email protected]>
Yeah, looks right. Thanks for moving the count assignment.
-Kees
Quoted 41 lines
--- drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +3
-3@@ -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);Signature · 1 line
2.34.1
Signature · 1 line
Kees Cook
Quoted 11 lines · Gustavo A. R. Silva
Prepare for the coming implementation by GCC and Clang of the
__counted_byattribute. Flexible array members annotated with__counted_bycan have their accesses bounds-checked at run-time viaCONFIG_UBSAN_BOUNDS(for array indexing) andCONFIG_FORTIFY_SOURCE(for strcpy/memcpy-family functions).Also, relocate
event->datalen = datalen;to before callingmemcpy(event->data, data, datalen);, so that the__counted_byannotation has effect, and flex-array memberdatacan be properly bounds-checked at run-time.
Quoted 6 lines
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.
From the description above I think this change looks sane so...
Quoted 4 lines
Signed-off-by Gustavo A. R. Silva <[email protected]>---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c| 6 +++---1 file changed, 3 insertions(+), 3 deletions(-)
Quoted 15 lines · Gustavo A. R. Silva
Prepare for the coming implementation by GCC and Clang of the
__counted_byattribute. Flexible array members annotated with__counted_bycan have their accesses bounds-checked at run-time viaCONFIG_UBSAN_BOUNDS(for array indexing) andCONFIG_FORTIFY_SOURCE(for strcpy/memcpy-family functions).Also, relocate
event->datalen = datalen;to before callingmemcpy(event->data, data, datalen);, so that the__counted_byannotation has effect, and flex-array memberdatacan 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.
Quoted 6 lines
This code was found with the help of Coccinelle, and audited and fixed manually.
Signed-off-by Gustavo A. R. Silva <[email protected]>Reviewed-by Kees Cook <[email protected]>Acked-by Arend van Spriel <[email protected]>
Patch applied to wireless-next.git, thanks.
62d19b358088 wifi: brcmfmac: fweh: Add __counted_by for struct brcmf_fweh_queue_item and use struct_size()
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/patch/ZSRzrIe0345eymk2@work/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches