net/ipv4: Use __DECLARE_FLEX_ARRAY() helper
authorGustavo A. R. Silva <gustavoars@kernel.org>
Wed, 31 Aug 2022 19:12:42 +0000 (14:12 -0500)
committerDavid S. Miller <davem@davemloft.net>
Sat, 3 Sep 2022 08:51:10 +0000 (09:51 +0100)
commit5854a09b49574da5a77a0f36ad7b021a2661321d
treeec3173bf11696cd1db2c3866a5690844f72ab9b6
parent2e5fb3223261366d1673c3827190c85a74b1aa56
net/ipv4: Use __DECLARE_FLEX_ARRAY() helper

We now have a cleaner way to keep compatibility with user-space
(a.k.a. not breaking it) when we need to keep in place a one-element
array (for its use in user-space) together with a flexible-array
member (for its use in kernel-space) without making it hard to read
at the source level. This is through the use of the new
__DECLARE_FLEX_ARRAY() helper macro.

The size and memory layout of the structure is preserved after the
changes. See below.

Before changes:

$ pahole -C ip_msfilter net/ipv4/igmp.o
struct ip_msfilter {
union {
struct {
__be32     imsf_multiaddr_aux;   /*     0     4 */
__be32     imsf_interface_aux;   /*     4     4 */
__u32      imsf_fmode_aux;       /*     8     4 */
__u32      imsf_numsrc_aux;      /*    12     4 */
__be32     imsf_slist[1];        /*    16     4 */
};                                       /*     0    20 */
struct {
__be32     imsf_multiaddr;       /*     0     4 */
__be32     imsf_interface;       /*     4     4 */
__u32      imsf_fmode;           /*     8     4 */
__u32      imsf_numsrc;          /*    12     4 */
__be32     imsf_slist_flex[0];   /*    16     0 */
};                                       /*     0    16 */
};                                               /*     0    20 */

/* size: 20, cachelines: 1, members: 1 */
/* last cacheline: 20 bytes */
};

After changes:

$ pahole -C ip_msfilter net/ipv4/igmp.o
struct ip_msfilter {
__be32                     imsf_multiaddr;       /*     0     4 */
__be32                     imsf_interface;       /*     4     4 */
__u32                      imsf_fmode;           /*     8     4 */
__u32                      imsf_numsrc;          /*    12     4 */
union {
__be32             imsf_slist[1];        /*    16     4 */
struct {
struct {
} __empty_imsf_slist_flex;       /*    16     0 */
__be32     imsf_slist_flex[0];   /*    16     0 */
};                                       /*    16     0 */
};                                               /*    16     4 */

/* size: 20, cachelines: 1, members: 5 */
/* last cacheline: 20 bytes */
};

In the past, we had to duplicate the whole original structure within
a union, and update the names of all the members. Now, we just need to
declare the flexible-array member to be used in kernel-space through
the __DECLARE_FLEX_ARRAY() helper together with the one-element array,
within a union. This makes the source code more clean and easier to read.

Link: https://github.com/KSPP/linux/issues/193
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/uapi/linux/in.h