Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFC: Replace zero-length array with flexible-array member

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]

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")

Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Gustavo A. R. Silva and committed by
David S. Miller
da60fbe7 6dd7f1a1

+11 -11
+1 -1
drivers/nfc/fdp/fdp.c
··· 76 76 struct nci_core_get_config_rsp { 77 77 u8 status; 78 78 u8 count; 79 - u8 data[0]; 79 + u8 data[]; 80 80 }; 81 81 82 82 static int fdp_nci_create_conn(struct nci_dev *ndev)
+2 -2
drivers/nfc/st21nfca/dep.c
··· 66 66 u8 bsi; 67 67 u8 bri; 68 68 u8 ppi; 69 - u8 gbi[0]; 69 + u8 gbi[]; 70 70 } __packed; 71 71 72 72 struct st21nfca_atr_res { ··· 79 79 u8 bri; 80 80 u8 to; 81 81 u8 ppi; 82 - u8 gbi[0]; 82 + u8 gbi[]; 83 83 } __packed; 84 84 85 85 struct st21nfca_psl_req {
+7 -7
include/net/nfc/nci.h
··· 244 244 struct core_conn_create_dest_spec_params { 245 245 __u8 type; 246 246 __u8 length; 247 - __u8 value[0]; 247 + __u8 value[]; 248 248 } __packed; 249 249 250 250 struct nci_core_conn_create_cmd { 251 251 __u8 destination_type; 252 252 __u8 number_destination_params; 253 - struct core_conn_create_dest_spec_params params[0]; 253 + struct core_conn_create_dest_spec_params params[]; 254 254 } __packed; 255 255 256 256 #define NCI_OP_CORE_CONN_CLOSE_CMD nci_opcode_pack(NCI_GID_CORE, 0x05) ··· 321 321 __u8 status; 322 322 __le32 nfcc_features; 323 323 __u8 num_supported_rf_interfaces; 324 - __u8 supported_rf_interfaces[0]; /* variable size array */ 324 + __u8 supported_rf_interfaces[]; /* variable size array */ 325 325 /* continuted in nci_core_init_rsp_2 */ 326 326 } __packed; 327 327 ··· 338 338 struct nci_core_set_config_rsp { 339 339 __u8 status; 340 340 __u8 num_params; 341 - __u8 params_id[0]; /* variable size array */ 341 + __u8 params_id[]; /* variable size array */ 342 342 } __packed; 343 343 344 344 #define NCI_OP_CORE_CONN_CREATE_RSP nci_opcode_pack(NCI_GID_CORE, 0x04) ··· 501 501 __u8 nfcee_id; 502 502 __u8 trigger; 503 503 __u8 supported_data_length; 504 - __u8 supported_data[0]; 504 + __u8 supported_data[]; 505 505 } __packed; 506 506 507 507 #define NCI_OP_NFCEE_DISCOVER_NTF nci_opcode_pack(NCI_GID_NFCEE_MGMT, 0x00) 508 508 struct nci_nfcee_supported_protocol { 509 509 __u8 num_protocol; 510 - __u8 supported_protocol[0]; 510 + __u8 supported_protocol[]; 511 511 } __packed; 512 512 513 513 struct nci_nfcee_information_tlv { 514 514 __u8 num_tlv; 515 - __u8 information_tlv[0]; 515 + __u8 information_tlv[]; 516 516 } __packed; 517 517 518 518 struct nci_nfcee_discover_ntf {
+1 -1
include/net/nfc/nfc.h
··· 146 146 u32 aid_len; 147 147 u8 aid[NFC_MAX_AID_LENGTH]; 148 148 u8 params_len; 149 - u8 params[0]; 149 + u8 params[]; 150 150 } __packed; 151 151 152 152 struct nfc_genl_data {