Thread (8 messages) 8 messages, 3 authors, 2021-08-28

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

From: Vincent MAILHOL <hidden>
Date: 2021-08-28 07:31:35
Also in: bpf, linux-can, linux-hardening, linux-scsi, linux-wireless, lkml, netdev
Subsystem: can network drivers, the rest · Maintainers: Marc Kleine-Budde, Vincent Mailhol, Linus Torvalds

Le sam. 28 août 2021 à 01:17, Kees Cook [off-list ref] a écrit :
quoted hunk ↗ jump to hunk
On Thu, Aug 26, 2021 at 08:24:52AM +0200, Marc Kleine-Budde wrote:
quoted
[...]
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?
quoted hunk ↗ jump to hunk
 } __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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help