2021-08-26 06:26:54

by Marc Kleine-Budde

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] treewide: Replace open-coded flex arrays in unions

On 25.08.2021 22:04:55, Kees Cook wrote:
> In support of enabling -Warray-bounds and -Wzero-length-bounds and
> correctly handling run-time memcpy() bounds checking, replace all
> open-coded flexible arrays (i.e. 0-element arrays) in unions with the
> flex_array() helper macro.
>
> This fixes warnings such as:
>
> fs/hpfs/anode.c: In function 'hpfs_add_sector_to_btree':
> fs/hpfs/anode.c:209:27: warning: array subscript 0 is outside the bounds of an interior zero-length array 'struct bplus_internal_node[0]' [-Wzero-length-bounds]
> 209 | anode->btree.u.internal[0].down = cpu_to_le32(a);
> | ~~~~~~~~~~~~~~~~~~~~~~~^~~
> In file included from fs/hpfs/hpfs_fn.h:26,
> from fs/hpfs/anode.c:10:
> fs/hpfs/hpfs.h:412:32: note: while referencing 'internal'
> 412 | struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving
> | ^~~~~~~~
>
> drivers/net/can/usb/etas_es58x/es58x_fd.c: In function 'es58x_fd_tx_can_msg':
> drivers/net/can/usb/etas_es58x/es58x_fd.c:360:35: warning: array subscript 65535 is outside the bounds of an interior zero-length array 'u8[0]' {aka 'unsigned char[]'} [-Wzero-length-bounds]
> 360 | tx_can_msg = (typeof(tx_can_msg))&es58x_fd_urb_cmd->raw_msg[msg_len];
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> In file included from drivers/net/can/usb/etas_es58x/es58x_core.h:22,
> from drivers/net/can/usb/etas_es58x/es58x_fd.c:17:
> drivers/net/can/usb/etas_es58x/es58x_fd.h:231:6: note: while referencing 'raw_msg'
> 231 | u8 raw_msg[0];
> | ^~~~~~~
>
> Cc: "Gustavo A. R. Silva" <[email protected]>
> Cc: Arnd Bergmann <[email protected]>
> Cc: Ayush Sawal <[email protected]>
> Cc: Vinay Kumar Yadav <[email protected]>
> Cc: Rohit Maheshwari <[email protected]>
> Cc: Herbert Xu <[email protected]>
> Cc: "David S. Miller" <[email protected]>
> Cc: Kalle Valo <[email protected]>
> Cc: Jakub Kicinski <[email protected]>
> Cc: Stanislaw Gruszka <[email protected]>
> Cc: Luca Coelho <[email protected]>
> Cc: "James E.J. Bottomley" <[email protected]>
> Cc: "Martin K. Petersen" <[email protected]>
> Cc: Alexei Starovoitov <[email protected]>
> Cc: Daniel Borkmann <[email protected]>
> Cc: Andrii Nakryiko <[email protected]>
> Cc: Martin KaFai Lau <[email protected]>
> Cc: Song Liu <[email protected]>
> Cc: Yonghong Song <[email protected]>
> Cc: John Fastabend <[email protected]>
> Cc: KP Singh <[email protected]>
> Cc: Johannes Berg <[email protected]>
> Cc: Mordechay Goodstein <[email protected]>
> Cc: Lee Jones <[email protected]>
> Cc: Wolfgang Grandegger <[email protected]>
> Cc: Marc Kleine-Budde <[email protected]>
> Cc: Arunachalam Santhanam <[email protected]>
> Cc: Vincent Mailhol <[email protected]>
> Cc: Mikulas Patocka <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Signed-off-by: Kees Cook <[email protected]>
> ---
> drivers/net/can/usb/etas_es58x/es581_4.h | 2 +-
> drivers/net/can/usb/etas_es58x/es58x_fd.h | 2 +-

For the can drivers:

Acked-by: Marc Kleine-Budde <[email protected]>

BTW: Is there opportunity for conversion, too?

| drivers/net/can/peak_canfd/peak_pciefd_main.c:146:32: warning: array of flexible structures

regards,
Marc

--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung West/Dortmund | Phone: +49-231-2826-924 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |


Attachments:
(No filename) (3.86 kB)
signature.asc (499.00 B)
Download all attachments

2021-08-27 16:09:11

by Kees Cook

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] treewide: Replace open-coded flex arrays in unions

On Thu, Aug 26, 2021 at 08:24:52AM +0200, Marc Kleine-Budde wrote:
> On 25.08.2021 22:04:55, Kees Cook wrote:
> > In support of enabling -Warray-bounds and -Wzero-length-bounds and
> > correctly handling run-time memcpy() bounds checking, replace all
> > open-coded flexible arrays (i.e. 0-element arrays) in unions with the
> > flex_array() helper macro.
> >
> > This fixes warnings such as:
> >
> > fs/hpfs/anode.c: In function 'hpfs_add_sector_to_btree':
> > fs/hpfs/anode.c:209:27: warning: array subscript 0 is outside the bounds of an interior zero-length array 'struct bplus_internal_node[0]' [-Wzero-length-bounds]
> > 209 | anode->btree.u.internal[0].down = cpu_to_le32(a);
> > | ~~~~~~~~~~~~~~~~~~~~~~~^~~
> > In file included from fs/hpfs/hpfs_fn.h:26,
> > from fs/hpfs/anode.c:10:
> > fs/hpfs/hpfs.h:412:32: note: while referencing 'internal'
> > 412 | struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving
> > | ^~~~~~~~
> >
> > drivers/net/can/usb/etas_es58x/es58x_fd.c: In function 'es58x_fd_tx_can_msg':
> > drivers/net/can/usb/etas_es58x/es58x_fd.c:360:35: warning: array subscript 65535 is outside the bounds of an interior zero-length array 'u8[0]' {aka 'unsigned char[]'} [-Wzero-length-bounds]
> > 360 | tx_can_msg = (typeof(tx_can_msg))&es58x_fd_urb_cmd->raw_msg[msg_len];
> > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > In file included from drivers/net/can/usb/etas_es58x/es58x_core.h:22,
> > from drivers/net/can/usb/etas_es58x/es58x_fd.c:17:
> > drivers/net/can/usb/etas_es58x/es58x_fd.h:231:6: note: while referencing 'raw_msg'
> > 231 | u8 raw_msg[0];
> > | ^~~~~~~
> >
> > Cc: "Gustavo A. R. Silva" <[email protected]>
> > Cc: Arnd Bergmann <[email protected]>
> > Cc: Ayush Sawal <[email protected]>
> > Cc: Vinay Kumar Yadav <[email protected]>
> > Cc: Rohit Maheshwari <[email protected]>
> > Cc: Herbert Xu <[email protected]>
> > Cc: "David S. Miller" <[email protected]>
> > Cc: Kalle Valo <[email protected]>
> > Cc: Jakub Kicinski <[email protected]>
> > Cc: Stanislaw Gruszka <[email protected]>
> > Cc: Luca Coelho <[email protected]>
> > Cc: "James E.J. Bottomley" <[email protected]>
> > Cc: "Martin K. Petersen" <[email protected]>
> > Cc: Alexei Starovoitov <[email protected]>
> > Cc: Daniel Borkmann <[email protected]>
> > Cc: Andrii Nakryiko <[email protected]>
> > Cc: Martin KaFai Lau <[email protected]>
> > Cc: Song Liu <[email protected]>
> > Cc: Yonghong Song <[email protected]>
> > Cc: John Fastabend <[email protected]>
> > Cc: KP Singh <[email protected]>
> > Cc: Johannes Berg <[email protected]>
> > Cc: Mordechay Goodstein <[email protected]>
> > Cc: Lee Jones <[email protected]>
> > Cc: Wolfgang Grandegger <[email protected]>
> > Cc: Marc Kleine-Budde <[email protected]>
> > Cc: Arunachalam Santhanam <[email protected]>
> > Cc: Vincent Mailhol <[email protected]>
> > Cc: Mikulas Patocka <[email protected]>
> > Cc: [email protected]
> > Cc: [email protected]
> > Cc: [email protected]
> > Cc: [email protected]
> > Cc: [email protected]
> > Cc: [email protected]
> > Cc: [email protected]
> > Signed-off-by: Kees Cook <[email protected]>
> > ---
> > drivers/net/can/usb/etas_es58x/es581_4.h | 2 +-
> > drivers/net/can/usb/etas_es58x/es58x_fd.h | 2 +-
>
> For the can drivers:
>
> Acked-by: Marc Kleine-Budde <[email protected]>

Thanks!

> BTW: Is there opportunity for conversion, too?
>
> | drivers/net/can/peak_canfd/peak_pciefd_main.c:146:32: warning: array of flexible structures

Oh, hrmpf. This isn't a sane use of flex arrays:


struct __packed pucan_rx_msg {
...
__le32 can_id;
u8 d[];
};

struct pciefd_rx_dma {
__le32 irq_status;
__le32 sys_time_low;
__le32 sys_time_high;
struct pucan_rx_msg msg[];
} __packed __aligned(4);

I think that needs to be handled separately. How are you building to get
that warning, by the way? I haven't seen that in my builds...

--
Kees Cook

2021-08-27 16:18:33

by Kees Cook

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] treewide: Replace open-coded flex arrays in unions

On Thu, Aug 26, 2021 at 08:24:52AM +0200, Marc Kleine-Budde wrote:
> [...]
> BTW: Is there opportunity for conversion, too?
>
> | drivers/net/can/peak_canfd/peak_pciefd_main.c:146:32: warning: array of flexible structures

Untested potential solution:

diff --git a/drivers/net/can/peak_canfd/peak_pciefd_main.c b/drivers/net/can/peak_canfd/peak_pciefd_main.c
index 1df3c4b54f03..efa2b5a52bd7 100644
--- a/drivers/net/can/peak_canfd/peak_pciefd_main.c
+++ b/drivers/net/can/peak_canfd/peak_pciefd_main.c
@@ -143,7 +143,11 @@ struct pciefd_rx_dma {
__le32 irq_status;
__le32 sys_time_low;
__le32 sys_time_high;
- struct pucan_rx_msg msg[];
+ /*
+ * with "msg" being pciefd_irq_rx_cnt(priv->irq_status)-many
+ * variable-sized struct pucan_rx_msg following.
+ */
+ __le32 msg[];
} __packed __aligned(4);

/* Tx Link record */
@@ -327,7 +331,7 @@ static irqreturn_t pciefd_irq_handler(int irq, void *arg)

/* handle rx messages (if any) */
peak_canfd_handle_msgs_list(&priv->ucan,
- rx_dma->msg,
+ (struct pucan_rx_msg *)rx_dma->msg,
pciefd_irq_rx_cnt(priv->irq_status));

/* handle tx link interrupt (if any) */


It's not great, but it's also not strictly a flex array, in the sense
that since struct pucan_rx_msg is a variable size, the compiler cannot
reason about the size of struct pciefd_rx_dma based only on the
irq_status encoding...

--
Kees Cook

2021-08-27 17:10:25

by Marc Kleine-Budde

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] treewide: Replace open-coded flex arrays in unions

On 27.08.2021 09:08:19, Kees Cook wrote:
> > BTW: Is there opportunity for conversion, too?
> >
> > | drivers/net/can/peak_canfd/peak_pciefd_main.c:146:32: warning: array of flexible structures
>
> Oh, hrmpf. This isn't a sane use of flex arrays:
>
> struct __packed pucan_rx_msg {
> ...
> __le32 can_id;
> u8 d[];
> };
>
> struct pciefd_rx_dma {
> __le32 irq_status;
> __le32 sys_time_low;
> __le32 sys_time_high;
> struct pucan_rx_msg msg[];
> } __packed __aligned(4);
>
> I think that needs to be handled separately. How are you building to get
> that warning, by the way? I haven't seen that in my builds...

If compiling with C=1, sparse will complain about this.

regards,
Marc

--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung West/Dortmund | Phone: +49-231-2826-924 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |


Attachments:
(No filename) (1.00 kB)
signature.asc (499.00 B)
Download all attachments

2021-08-28 07:31:58

by Vincent MAILHOL

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] treewide: Replace open-coded flex arrays in unions

Le sam. 28 août 2021 à 01:17, Kees Cook <[email protected]> a écrit :
>
> On Thu, Aug 26, 2021 at 08:24:52AM +0200, Marc Kleine-Budde wrote:
> > [...]
> > BTW: Is there opportunity for conversion, too?
> >
> > | drivers/net/can/peak_canfd/peak_pciefd_main.c:146:32: warning: array of flexible structures
>
> Untested potential solution:
>
> diff --git a/drivers/net/can/peak_canfd/peak_pciefd_main.c b/drivers/net/can/peak_canfd/peak_pciefd_main.c
> index 1df3c4b54f03..efa2b5a52bd7 100644
> --- a/drivers/net/can/peak_canfd/peak_pciefd_main.c
> +++ b/drivers/net/can/peak_canfd/peak_pciefd_main.c
> @@ -143,7 +143,11 @@ struct pciefd_rx_dma {
> __le32 irq_status;
> __le32 sys_time_low;
> __le32 sys_time_high;
> - struct pucan_rx_msg msg[];
> + /*
> + * with "msg" being pciefd_irq_rx_cnt(priv->irq_status)-many
> + * variable-sized struct pucan_rx_msg following.
> + */
> + __le32 msg[];

Isn't u8 msg[] preferable here?

> } __packed __aligned(4);
>
> /* Tx Link record */
> @@ -327,7 +331,7 @@ static irqreturn_t pciefd_irq_handler(int irq, void *arg)
>
> /* handle rx messages (if any) */
> peak_canfd_handle_msgs_list(&priv->ucan,
> - rx_dma->msg,
> + (struct pucan_rx_msg *)rx_dma->msg,
> pciefd_irq_rx_cnt(priv->irq_status));
>
> /* handle tx link interrupt (if any) */
>
>
> It's not great, but it's also not strictly a flex array, in the sense
> that since struct pucan_rx_msg is a variable size, the compiler cannot
> reason about the size of struct pciefd_rx_dma based only on the
> irq_status encoding...

In the same spirit, it is a bit cleaner to change the prototype of
handle_msgs_list().

Like that:


diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canf
d/peak_canfd.c
index d08718e98e11..81a9faa6193f 100644
--- a/drivers/net/can/peak_canfd/peak_canfd.c
+++ b/drivers/net/can/peak_canfd/peak_canfd.c
@@ -484,9 +484,8 @@ int peak_canfd_handle_msg(struct peak_canfd_priv *priv,

/* handle a list of rx_count messages from rx_msg memory address */
int peak_canfd_handle_msgs_list(struct peak_canfd_priv *priv,
- struct pucan_rx_msg *msg_list, int msg_count)
+ void *msg_ptr, int msg_count)
{
- void *msg_ptr = msg_list;
int i, msg_size = 0;

for (i = 0; i < msg_count; i++) {
diff --git a/drivers/net/can/peak_canfd/peak_canfd_user.h b/drivers/net/can/peak
_canfd/peak_canfd_user.h
index a72719dc3b74..ef91f92e70c3 100644
--- a/drivers/net/can/peak_canfd/peak_canfd_user.h
+++ b/drivers/net/can/peak_canfd/peak_canfd_user.h
@@ -42,5 +42,5 @@ struct net_device *alloc_peak_canfd_dev(int
sizeof_priv, int index,
int peak_canfd_handle_msg(struct peak_canfd_priv *priv,
struct pucan_rx_msg *msg);
int peak_canfd_handle_msgs_list(struct peak_canfd_priv *priv,
- struct pucan_rx_msg *rx_msg, int rx_count);
+ void *msg_ptr, int rx_count);
#endif
diff --git a/drivers/net/can/peak_canfd/peak_pciefd_main.c
b/drivers/net/can/peak_canfd/peak_pciefd_main.c
index 1df3c4b54f03..c1de1e3dc4bc 100644
--- a/drivers/net/can/peak_canfd/peak_pciefd_main.c
+++ b/drivers/net/can/peak_canfd/peak_pciefd_main.c
@@ -143,7 +143,11 @@ struct pciefd_rx_dma {
__le32 irq_status;
__le32 sys_time_low;
__le32 sys_time_high;
- struct pucan_rx_msg msg[];
+ /*
+ * with "msg" being pciefd_irq_rx_cnt(priv->irq_status)-many
+ * variable-sized struct pucan_rx_msg following.
+ */
+ u8 msg[];
} __packed __aligned(4);

/* Tx Link record */


Another solution would be to declare a maximum length for struct
pucan_rx_msg::d. Because these are CAN FD messages, I suppose
that maximum length would be CANFD_MAX_DLEN. struct canfd_frame
from the UAPI uses the same pattern.

N.B. This solution is not exclusive from the above one (actually,
I think that using both would be the best solution).

diff --git a/include/linux/can/dev/peak_canfd.h
b/include/linux/can/dev/peak_canfd.h
index f38772fd0c07..a048359db430 100644
--- a/include/linux/can/dev/peak_canfd.h
+++ b/include/linux/can/dev/peak_canfd.h
@@ -189,7 +189,7 @@ struct __packed pucan_rx_msg {
u8 client;
__le16 flags;
__le32 can_id;
- u8 d[];
+ u8 d[CANFD_MAX_DLEN];
};

/* uCAN error types */



I only tested for compilation.

Yours sincerely,
Vincent