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

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

Link: https://lkml.kernel.org/r/20200221150612.GA9717@embeddedor
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>

authored by

Gustavo A. R. Silva and committed by
Vasily Gorbik
fa226f1d d5d006fa

+9 -9
+1 -1
arch/s390/appldata/appldata_os.c
··· 75 75 (waiting for I/O) */ 76 76 77 77 /* per cpu data */ 78 - struct appldata_os_per_cpu os_cpu[0]; 78 + struct appldata_os_per_cpu os_cpu[]; 79 79 } __attribute__((packed)); 80 80 81 81 static struct appldata_os_data *appldata_os_data;
+1 -1
drivers/s390/block/dasd_diag.c
··· 58 58 59 59 struct dasd_diag_req { 60 60 unsigned int block_count; 61 - struct dasd_diag_bio bio[0]; 61 + struct dasd_diag_bio bio[]; 62 62 }; 63 63 64 64 static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
+1 -1
drivers/s390/block/dasd_eckd.h
··· 220 220 __u8 imbedded_count; 221 221 __u8 extended_operation; 222 222 __u16 extended_parameter_length; 223 - __u8 extended_parameter[0]; 223 + __u8 extended_parameter[]; 224 224 } __attribute__ ((packed)); 225 225 226 226 /* Prefix data for format 0x00 and 0x01 */
+1 -1
drivers/s390/char/raw3270.h
··· 211 211 struct list_head update; 212 212 unsigned long size; 213 213 unsigned long len; 214 - char string[0]; 214 + char string[]; 215 215 } __attribute__ ((aligned(8))); 216 216 217 217 static inline struct string *
+1 -1
drivers/s390/char/sclp_pci.c
··· 39 39 u8 atype; 40 40 u32 fh; 41 41 u32 fid; 42 - u8 data[0]; 42 + u8 data[]; 43 43 } __packed; 44 44 45 45 struct err_notify_sccb {
+1 -1
drivers/s390/cio/idset.c
··· 13 13 struct idset { 14 14 int num_ssid; 15 15 int num_id; 16 - unsigned long bitmap[0]; 16 + unsigned long bitmap[]; 17 17 }; 18 18 19 19 static inline unsigned long bitmap_size(int num_ssid, int num_id)
+1 -1
drivers/s390/crypto/pkey_api.c
··· 80 80 u8 res1[3]; 81 81 u32 keytype; /* key type, one of the PKEY_KEYTYPE values */ 82 82 u32 len; /* bytes actually stored in clearkey[] */ 83 - u8 clearkey[0]; /* clear key value */ 83 + u8 clearkey[]; /* clear key value */ 84 84 } __packed; 85 85 86 86 /*
+1 -1
drivers/s390/crypto/zcrypt_ccamisc.h
··· 90 90 u16 kmf1; /* key management field 1 */ 91 91 u16 kmf2; /* key management field 2 */ 92 92 u16 kmf3; /* key management field 3 */ 93 - u8 vdata[0]; /* variable part data follows */ 93 + u8 vdata[]; /* variable part data follows */ 94 94 } __packed; 95 95 96 96 /* Some defines for the CCA AES cipherkeytoken kmf1 field */
+1 -1
drivers/s390/crypto/zcrypt_msgtype6.c
··· 590 590 struct CPRBX cprbx; 591 591 unsigned char pad[4]; /* 4 byte function code/rules block ? */ 592 592 unsigned short length; 593 - char text[0]; 593 + char text[]; 594 594 } __packed; 595 595 596 596 struct type86_ep11_reply {