Re: [PATCH] scsi: Replace zero-length array with flexible-array member

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 2/24/20 10:30, Lee Duncan wrote:
> On 2/24/20 8:14 AM, Gustavo A. R. Silva wrote:
>> 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@xxxxxxxxxxxxxx>
>> ---
>>  ...
>> diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
>> index 92b11c7e0b4f..b0e240b10bf9 100644
>> --- a/include/scsi/iscsi_if.h
>> +++ b/include/scsi/iscsi_if.h
>> @@ -311,7 +311,7 @@ enum iscsi_param_type {
>>  struct iscsi_param_info {
>>  	uint32_t len;		/* Actual length of the param value */
>>  	uint16_t param;		/* iscsi param */
>> -	uint8_t value[0];	/* length sized value follows */
>> +	uint8_t value[];	/* length sized value follows */
>>  } __packed;
>>  
>>  struct iscsi_iface_param_info {
>> @@ -320,7 +320,7 @@ struct iscsi_iface_param_info {
>>  	uint16_t param;		/* iscsi param value */
>>  	uint8_t iface_type;	/* IPv4 or IPv6 */
>>  	uint8_t param_type;	/* iscsi_param_type */
>> -	uint8_t value[0];	/* length sized value follows */
>> +	uint8_t value[];	/* length sized value follows */
>>  } __packed;
>>  
>>  /*
>> @@ -697,7 +697,7 @@ enum iscsi_flashnode_param {
>>  struct iscsi_flashnode_param_info {
>>  	uint32_t len;		/* Actual length of the param */
>>  	uint16_t param;		/* iscsi param value */
>> -	uint8_t value[0];	/* length sized value follows */
>> +	uint8_t value[];	/* length sized value follows */
>>  } __packed;
>>  
>>  enum iscsi_discovery_parent_type {
>> @@ -815,7 +815,7 @@ struct iscsi_stats {
>>  	 * up to ISCSI_STATS_CUSTOM_MAX
>>  	 */
>>  	uint32_t custom_length;
>> -	struct iscsi_stats_custom custom[0]
>> +	struct iscsi_stats_custom custom[]
>>  		__attribute__ ((aligned (sizeof(uint64_t))));
>>  };
>>  
>> @@ -946,7 +946,7 @@ struct iscsi_offload_host_stats {
>>  	 * up to ISCSI_HOST_STATS_CUSTOM_MAX
>>  	 */
>>  	uint32_t custom_length;
>> -	struct iscsi_host_stats_custom custom[0]
>> +	struct iscsi_host_stats_custom custom[]
>>  		__aligned(sizeof(uint64_t));
>>  };
>>  
>> diff --git a/include/scsi/scsi_bsg_iscsi.h b/include/scsi/scsi_bsg_iscsi.h
>> index fa0c820a1663..6b8128005af8 100644
>> --- a/include/scsi/scsi_bsg_iscsi.h
>> +++ b/include/scsi/scsi_bsg_iscsi.h
>> @@ -52,7 +52,7 @@ struct iscsi_bsg_host_vendor {
>>  	uint64_t vendor_id;
>>  
>>  	/* start of vendor command area */
>> -	uint32_t vendor_cmd[0];
>> +	uint32_t vendor_cmd[];
>>  };
>>  
>>  /* Response:
>> diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
>> index f8312a3e5b42..4dc158cf09b8 100644
>> --- a/include/scsi/scsi_device.h
>> +++ b/include/scsi/scsi_device.h
>> @@ -231,7 +231,7 @@ struct scsi_device {
>>  	struct mutex		state_mutex;
>>  	enum scsi_device_state sdev_state;
>>  	struct task_struct	*quiesced_by;
>> -	unsigned long		sdev_data[0];
>> +	unsigned long		sdev_data[];
>>  } __attribute__((aligned(sizeof(unsigned long))));
>>  
>>  #define	to_scsi_device(d)	\
>> @@ -315,7 +315,7 @@ struct scsi_target {
>>  	char			scsi_level;
>>  	enum scsi_target_state	state;
>>  	void 			*hostdata; /* available to low-level driver */
>> -	unsigned long		starget_data[0]; /* for the transport */
>> +	unsigned long		starget_data[]; /* for the transport */
>>  	/* starget_data must be the last element!!!! */
>>  } __attribute__((aligned(sizeof(unsigned long))));
>>  
>> diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
>> index 7a97fb8104cf..e6811ea8f984 100644
>> --- a/include/scsi/scsi_host.h
>> +++ b/include/scsi/scsi_host.h
>> @@ -682,7 +682,7 @@ struct Scsi_Host {
>>  	 * and also because some compilers (m68k) don't automatically force
>>  	 * alignment to a long boundary.
>>  	 */
>> -	unsigned long hostdata[0]  /* Used for storage of host specific stuff */
>> +	unsigned long hostdata[]  /* Used for storage of host specific stuff */
>>  		__attribute__ ((aligned (sizeof(unsigned long))));
>>  };
>>  
>> diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h
>> index 4fe69d863b5d..b465799f4d2d 100644
>> --- a/include/scsi/scsi_ioctl.h
>> +++ b/include/scsi/scsi_ioctl.h
>> @@ -27,7 +27,7 @@ struct scsi_device;
>>  typedef struct scsi_ioctl_command {
>>  	unsigned int inlen;
>>  	unsigned int outlen;
>> -	unsigned char data[0];
>> +	unsigned char data[];
>>  } Scsi_Ioctl_Command;
>>  
>>  typedef struct scsi_idlun {
>> diff --git a/include/scsi/srp.h b/include/scsi/srp.h
>> index 9220758d5087..177d8026e96f 100644
>> --- a/include/scsi/srp.h
>> +++ b/include/scsi/srp.h
>> @@ -109,7 +109,7 @@ struct srp_direct_buf {
>>  struct srp_indirect_buf {
>>  	struct srp_direct_buf	table_desc;
>>  	__be32			len;
>> -	struct srp_direct_buf	desc_list[0];
>> +	struct srp_direct_buf	desc_list[];
>>  } __attribute__((packed));
>>  
>>  /* Immediate data buffer descriptor as defined in SRP2. */
>> @@ -244,7 +244,7 @@ struct srp_cmd {
>>  	u8	reserved4;
>>  	u8	add_cdb_len;
>>  	u8	cdb[16];
>> -	u8	add_data[0];
>> +	u8	add_data[];
>>  };
>>  
>>  enum {
>> @@ -274,7 +274,7 @@ struct srp_rsp {
>>  	__be32	data_in_res_cnt;
>>  	__be32	sense_data_len;
>>  	__be32	resp_data_len;
>> -	u8	data[0];
>> +	u8	data[];
>>  } __attribute__((packed));
>>  
>>  struct srp_cred_req {
>> @@ -306,7 +306,7 @@ struct srp_aer_req {
>>  	struct scsi_lun	lun;
>>  	__be32	sense_data_len;
>>  	u32	reserved3;
>> -	u8	sense_data[0];
>> +	u8	sense_data[];
>>  } __attribute__((packed));
>>  
>>  struct srp_aer_rsp {
>> diff --git a/include/uapi/scsi/scsi_bsg_fc.h b/include/uapi/scsi/scsi_bsg_fc.h
>> index 3ae65e93235c..7f5930801f72 100644
>> --- a/include/uapi/scsi/scsi_bsg_fc.h
>> +++ b/include/uapi/scsi/scsi_bsg_fc.h
>> @@ -209,7 +209,7 @@ struct fc_bsg_host_vendor {
>>  	__u64 vendor_id;
>>  
>>  	/* start of vendor command area */
>> -	__u32 vendor_cmd[0];
>> +	__u32 vendor_cmd[];
>>  };
>>  
>>  /* Response:
>>
> 
> Reviewed-by: Lee Duncan <lduncan@xxxxxxxx>
> 

Thanks, Lee.

--
Gustavo



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux