wil6210: Replace zero-length array with flexible-array
Subsystems (3)
PATCH 1/1 wil6210: Replace zero-length array with flexible-array
The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99:
struct foo {
int stuff;
struct boo array[];
};By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on.
Also, notice that, dynamic memory allocations won't be affected by this change:
"Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1]
sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues.
This issue was found with the help of Coccinelle.
[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour")
--- drivers/net/wireless/ath/wil6210/fw.h | 16 ++++---- drivers/net/wireless/ath/wil6210/wmi.c | 2 +- drivers/net/wireless/ath/wil6210/wmi.h | 56 +++++++++++++------------- 3 files changed, 37 insertions(+), 37 deletions(-)
drivers/net/wireless/ath/wil6210/fw.h +8 -8
@@ -33,7 +33,7 @@ struct wil_fw_record_head {*/ struct wil_fw_record_data {/* type == wil_fw_type_data */ __le32 addr; -__le32 data[0 ];/* [data_size], see above */ +__le32 data[];/* [data_size], see above */ } __packed;/* fill with constant @value, @size bytes starting from @addr */
@@ -61,7 +61,7 @@ struct wil_fw_record_capabilities { /* type == wil_fw_type_comment *//* identifies capabilities record */ struct wil_fw_record_comment_hdr hdr;/* capabilities (variable size), see enum wmi_fw_capability */ -u8 capabilities[0 ]; +u8 capabilities[]; } __packed;/* FW VIF concurrency encoded inside a comment record
@@ -80,7 +80,7 @@ struct wil_fw_concurrency_combo {u8 n_diff_channels;/* total number of different channels allowed */ u8 same_bi;/* for APs, 1 if all APs must have same BI */ /* keep last - concurrency limits, variable size by n_limits */ -struct wil_fw_concurrency_limit limits[0 ]; +struct wil_fw_concurrency_limit limits[]; } __packed;struct wil_fw_record_concurrency {/* type == wil_fw_type_comment */
@@ -93,7 +93,7 @@ struct wil_fw_record_concurrency { /* type == wil_fw_type_comment *//* number of concurrency combinations that follow */ __le16 n_combos;/* keep last - combinations, variable size by n_combos */ -struct wil_fw_concurrency_combo combos[0 ]; +struct wil_fw_concurrency_combo combos[]; } __packed;/* brd file info encoded inside a comment record */
@@ -108,7 +108,7 @@ struct wil_fw_record_brd_file { /* type == wil_fw_type_comment *//* identifies brd file record */ struct wil_fw_record_comment_hdr hdr;__le32 version; -struct brd_info brd_info[0 ]; +struct brd_info brd_info[]; } __packed;/* perform action
@@ -116,7 +116,7 @@ struct wil_fw_record_brd_file { /* type == wil_fw_type_comment */*/ struct wil_fw_record_action {/* type == wil_fw_type_action */ __le32 action;/* action to perform: reset, wait for fw ready etc. */ -__le32 data[0 ];/* action specific, [data_size], see above */ +__le32 data[];/* action specific, [data_size], see above */ } __packed;/* data block for struct wil_fw_record_direct_write */
@@ -179,7 +179,7 @@ struct wil_fw_record_gateway_data { /* type == wil_fw_type_gateway_data */#define WIL_FW_GW_CTL_BUSY BIT(29)/* gateway busy performing operation */ #define WIL_FW_GW_CTL_RUN BIT(30)/* start gateway operation */ __le32 command; -struct wil_fw_data_gw data[0 ];/* total size [data_size], see above */ +struct wil_fw_data_gw data[];/* total size [data_size], see above */ } __packed;/* 4-dword gateway */
@@ -201,7 +201,7 @@ struct wil_fw_record_gateway_data4 { /* type == wil_fw_type_gateway_data4 */__le32 gateway_cmd_addr;__le32 gateway_ctrl_address;/* same logic as for 1-dword gw */ __le32 command; - struct wil_fw_data_gw4 data[0]; /* total size [data_size], see above */ + struct wil_fw_data_gw4 data[]; /* total size [data_size], see above */ } __packed;#endif /* __WIL_FW_H__ */
drivers/net/wireless/ath/wil6210/wmi.c +1 -1
@@ -222,7 +222,7 @@ struct auth_no_hdr {__le16 auth_transaction;__le16 status_code;/* possibly followed by Challenge text */ -u8 variable[0 ]; +u8 variable[]; } __packed;u8 led_polarity =LED_POLARITY_LOW_ACTIVE ;
drivers/net/wireless/ath/wil6210/wmi.h +28 -28
224 lines not on this page · raw message
Signature · 1 line
2.26.2
Quoted 29 lines · Gustavo A. R. Silva
The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99:
struct foo { int stuff; struct boo array[]; };By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on.
Also, notice that, dynamic memory allocations won't be affected by this change:
"Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1]
sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues.
Quoted 8 lines
This issue was found with the help of Coccinelle.
[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit76497732932f("cxgb3/l2t: Fix undefined behaviour")Signed-off-by Gustavo A. R. Silva <[email protected]>Signed-off-by Kalle Valo <[email protected]>
Patch applied to ath-next branch of ath.git, thanks.
104f3d95d8d6 wil6210: Replace zero-length array with flexible-array
Signature · 3 lines
https://patchwork.kernel.org/patch/11534175/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches