RDMA/uverbs: Remove flexible arrays from struct *_filter
When a struct containing a flexible array is included in another struct, and there is a member after the struct-with-flex-array, there is a possibility of memory overlap. These cases must be audited [1]. See: struct inner { ... int flex[]; }; struct outer { ... struct inner header; int overlap; ... }; This is the scenario for all the "struct *_filter" structures that are included in the following "struct ib_flow_spec_*" structures: struct ib_flow_spec_eth struct ib_flow_spec_ib struct ib_flow_spec_ipv4 struct ib_flow_spec_ipv6 struct ib_flow_spec_tcp_udp struct ib_flow_spec_tunnel struct ib_flow_spec_esp struct ib_flow_spec_gre struct ib_flow_spec_mpls The pattern is like the one shown below: struct *_filter { ... u8 real_sz[]; }; struct ib_flow_spec_* { ... struct *_filter val; struct *_filter mask; }; In this case, the trailing flexible array "real_sz" is never allocated and is only used to calculate the size of the structures. Here the use of the "offsetof" helper can be changed by the "sizeof" operator because the goal is to get the size of these structures. Therefore, the trailing flexible arrays can also be removed. However, due to the trailing padding that can be induced in structs it is possible that the: offsetof(struct *_filter, real_sz) != sizeof(struct *_filter) This situation happens with the "struct ib_flow_ipv6_filter" and to avoid it the "__packed" macro is used in this structure. But now, the "sizeof(struct ib_flow_ipv6_filter)" has changed. This is not a problem since this size is not used in the code. The situation now is that "sizeof(struct ib_flow_spec_ipv6)" has also changed (this struct contains the struct ib_flow_ipv6_filter). This is also not a problem since it is only used to set the size of the "union ib_flow_spec", which can store all the "ib_flow_spec_*" structures. Link: https://lore.kernel.org/r/20240217142913.4285-1-erick.archer@gmx.com Signed-off-by: Erick Archer <erick.archer@gmx.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
7a8bccd8b2
commit
14b526f55b
@ -2737,7 +2737,7 @@ int ib_uverbs_kern_spec_to_ib_spec_filter(enum ib_flow_spec_type type,
|
||||
|
||||
switch (ib_spec->type & ~IB_FLOW_SPEC_INNER) {
|
||||
case IB_FLOW_SPEC_ETH:
|
||||
ib_filter_sz = offsetof(struct ib_flow_eth_filter, real_sz);
|
||||
ib_filter_sz = sizeof(struct ib_flow_eth_filter);
|
||||
actual_filter_sz = spec_filter_size(kern_spec_mask,
|
||||
kern_filter_sz,
|
||||
ib_filter_sz);
|
||||
@ -2748,7 +2748,7 @@ int ib_uverbs_kern_spec_to_ib_spec_filter(enum ib_flow_spec_type type,
|
||||
memcpy(&ib_spec->eth.mask, kern_spec_mask, actual_filter_sz);
|
||||
break;
|
||||
case IB_FLOW_SPEC_IPV4:
|
||||
ib_filter_sz = offsetof(struct ib_flow_ipv4_filter, real_sz);
|
||||
ib_filter_sz = sizeof(struct ib_flow_ipv4_filter);
|
||||
actual_filter_sz = spec_filter_size(kern_spec_mask,
|
||||
kern_filter_sz,
|
||||
ib_filter_sz);
|
||||
@ -2759,7 +2759,7 @@ int ib_uverbs_kern_spec_to_ib_spec_filter(enum ib_flow_spec_type type,
|
||||
memcpy(&ib_spec->ipv4.mask, kern_spec_mask, actual_filter_sz);
|
||||
break;
|
||||
case IB_FLOW_SPEC_IPV6:
|
||||
ib_filter_sz = offsetof(struct ib_flow_ipv6_filter, real_sz);
|
||||
ib_filter_sz = sizeof(struct ib_flow_ipv6_filter);
|
||||
actual_filter_sz = spec_filter_size(kern_spec_mask,
|
||||
kern_filter_sz,
|
||||
ib_filter_sz);
|
||||
@ -2775,7 +2775,7 @@ int ib_uverbs_kern_spec_to_ib_spec_filter(enum ib_flow_spec_type type,
|
||||
break;
|
||||
case IB_FLOW_SPEC_TCP:
|
||||
case IB_FLOW_SPEC_UDP:
|
||||
ib_filter_sz = offsetof(struct ib_flow_tcp_udp_filter, real_sz);
|
||||
ib_filter_sz = sizeof(struct ib_flow_tcp_udp_filter);
|
||||
actual_filter_sz = spec_filter_size(kern_spec_mask,
|
||||
kern_filter_sz,
|
||||
ib_filter_sz);
|
||||
@ -2786,7 +2786,7 @@ int ib_uverbs_kern_spec_to_ib_spec_filter(enum ib_flow_spec_type type,
|
||||
memcpy(&ib_spec->tcp_udp.mask, kern_spec_mask, actual_filter_sz);
|
||||
break;
|
||||
case IB_FLOW_SPEC_VXLAN_TUNNEL:
|
||||
ib_filter_sz = offsetof(struct ib_flow_tunnel_filter, real_sz);
|
||||
ib_filter_sz = sizeof(struct ib_flow_tunnel_filter);
|
||||
actual_filter_sz = spec_filter_size(kern_spec_mask,
|
||||
kern_filter_sz,
|
||||
ib_filter_sz);
|
||||
@ -2801,7 +2801,7 @@ int ib_uverbs_kern_spec_to_ib_spec_filter(enum ib_flow_spec_type type,
|
||||
return -EINVAL;
|
||||
break;
|
||||
case IB_FLOW_SPEC_ESP:
|
||||
ib_filter_sz = offsetof(struct ib_flow_esp_filter, real_sz);
|
||||
ib_filter_sz = sizeof(struct ib_flow_esp_filter);
|
||||
actual_filter_sz = spec_filter_size(kern_spec_mask,
|
||||
kern_filter_sz,
|
||||
ib_filter_sz);
|
||||
@ -2812,7 +2812,7 @@ int ib_uverbs_kern_spec_to_ib_spec_filter(enum ib_flow_spec_type type,
|
||||
memcpy(&ib_spec->esp.mask, kern_spec_mask, actual_filter_sz);
|
||||
break;
|
||||
case IB_FLOW_SPEC_GRE:
|
||||
ib_filter_sz = offsetof(struct ib_flow_gre_filter, real_sz);
|
||||
ib_filter_sz = sizeof(struct ib_flow_gre_filter);
|
||||
actual_filter_sz = spec_filter_size(kern_spec_mask,
|
||||
kern_filter_sz,
|
||||
ib_filter_sz);
|
||||
@ -2823,7 +2823,7 @@ int ib_uverbs_kern_spec_to_ib_spec_filter(enum ib_flow_spec_type type,
|
||||
memcpy(&ib_spec->gre.mask, kern_spec_mask, actual_filter_sz);
|
||||
break;
|
||||
case IB_FLOW_SPEC_MPLS:
|
||||
ib_filter_sz = offsetof(struct ib_flow_mpls_filter, real_sz);
|
||||
ib_filter_sz = sizeof(struct ib_flow_mpls_filter);
|
||||
actual_filter_sz = spec_filter_size(kern_spec_mask,
|
||||
kern_filter_sz,
|
||||
ib_filter_sz);
|
||||
|
@ -1910,8 +1910,6 @@ struct ib_flow_eth_filter {
|
||||
u8 src_mac[6];
|
||||
__be16 ether_type;
|
||||
__be16 vlan_tag;
|
||||
/* Must be last */
|
||||
u8 real_sz[];
|
||||
};
|
||||
|
||||
struct ib_flow_spec_eth {
|
||||
@ -1924,8 +1922,6 @@ struct ib_flow_spec_eth {
|
||||
struct ib_flow_ib_filter {
|
||||
__be16 dlid;
|
||||
__u8 sl;
|
||||
/* Must be last */
|
||||
u8 real_sz[];
|
||||
};
|
||||
|
||||
struct ib_flow_spec_ib {
|
||||
@ -1949,8 +1945,6 @@ struct ib_flow_ipv4_filter {
|
||||
u8 tos;
|
||||
u8 ttl;
|
||||
u8 flags;
|
||||
/* Must be last */
|
||||
u8 real_sz[];
|
||||
};
|
||||
|
||||
struct ib_flow_spec_ipv4 {
|
||||
@ -1967,9 +1961,7 @@ struct ib_flow_ipv6_filter {
|
||||
u8 next_hdr;
|
||||
u8 traffic_class;
|
||||
u8 hop_limit;
|
||||
/* Must be last */
|
||||
u8 real_sz[];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct ib_flow_spec_ipv6 {
|
||||
u32 type;
|
||||
@ -1981,8 +1973,6 @@ struct ib_flow_spec_ipv6 {
|
||||
struct ib_flow_tcp_udp_filter {
|
||||
__be16 dst_port;
|
||||
__be16 src_port;
|
||||
/* Must be last */
|
||||
u8 real_sz[];
|
||||
};
|
||||
|
||||
struct ib_flow_spec_tcp_udp {
|
||||
@ -1994,7 +1984,6 @@ struct ib_flow_spec_tcp_udp {
|
||||
|
||||
struct ib_flow_tunnel_filter {
|
||||
__be32 tunnel_id;
|
||||
u8 real_sz[];
|
||||
};
|
||||
|
||||
/* ib_flow_spec_tunnel describes the Vxlan tunnel
|
||||
@ -2010,8 +1999,6 @@ struct ib_flow_spec_tunnel {
|
||||
struct ib_flow_esp_filter {
|
||||
__be32 spi;
|
||||
__be32 seq;
|
||||
/* Must be last */
|
||||
u8 real_sz[];
|
||||
};
|
||||
|
||||
struct ib_flow_spec_esp {
|
||||
@ -2025,8 +2012,6 @@ struct ib_flow_gre_filter {
|
||||
__be16 c_ks_res0_ver;
|
||||
__be16 protocol;
|
||||
__be32 key;
|
||||
/* Must be last */
|
||||
u8 real_sz[];
|
||||
};
|
||||
|
||||
struct ib_flow_spec_gre {
|
||||
@ -2038,8 +2023,6 @@ struct ib_flow_spec_gre {
|
||||
|
||||
struct ib_flow_mpls_filter {
|
||||
__be32 tag;
|
||||
/* Must be last */
|
||||
u8 real_sz[];
|
||||
};
|
||||
|
||||
struct ib_flow_spec_mpls {
|
||||
|
Loading…
Reference in New Issue
Block a user