• Gustavo A. R. Silva's avatar
    net/ipv4: Use __DECLARE_FLEX_ARRAY() helper · 5854a09b
    Gustavo A. R. Silva authored
    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/193Signed-off-by: default avatarGustavo A. R. Silva <gustavoars@kernel.org>
    Reviewed-by: default avatarKees Cook <keescook@chromium.org>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    5854a09b
in.h 10.5 KB