virtchnl: fix fake 1-elem arrays for structures allocated as nents

Finally, fix 3 structures which are allocated technically correctly,
i.e. the calculated size equals to the one that struct_size() would
return, except for sizeof(). For &virtchnl_vlan_filter_list_v2, use
the same approach when there are no enough space as taken previously
for &virtchnl_vlan_filter_list, i.e. let the maximum size be calculated
automatically instead of trying to guestimate it using maths.

Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
Alexander Lobakin
2023-07-28 17:52:07 +02:00
committed by Tony Nguyen
parent 5e7f59fa07
commit b0654e64db
5 changed files with 40 additions and 37 deletions
+24 -15
View File
@@ -716,10 +716,11 @@ struct virtchnl_vlan_filter_list_v2 {
u16 vport_id;
u16 num_elements;
u8 pad[4];
struct virtchnl_vlan_filter filters[1];
struct virtchnl_vlan_filter filters[];
};
VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_vlan_filter_list_v2);
VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_vlan_filter_list_v2);
#define virtchnl_vlan_filter_list_v2_LEGACY_SIZEOF 40
/* VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2
* VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2
@@ -918,10 +919,11 @@ VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_channel_info);
struct virtchnl_tc_info {
u32 num_tc;
u32 pad;
struct virtchnl_channel_info list[1];
struct virtchnl_channel_info list[];
};
VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_tc_info);
VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_tc_info);
#define virtchnl_tc_info_LEGACY_SIZEOF 24
/* VIRTCHNL_ADD_CLOUD_FILTER
* VIRTCHNL_DEL_CLOUD_FILTER
@@ -1059,10 +1061,11 @@ VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_rdma_qv_info);
struct virtchnl_rdma_qvlist_info {
u32 num_vectors;
struct virtchnl_rdma_qv_info qv_info[1];
struct virtchnl_rdma_qv_info qv_info[];
};
VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_rdma_qvlist_info);
VIRTCHNL_CHECK_STRUCT_LEN(4, virtchnl_rdma_qvlist_info);
#define virtchnl_rdma_qvlist_info_LEGACY_SIZEOF 16
/* VF reset states - these are written into the RSTAT register:
* VFGEN_RSTAT on the VF
@@ -1377,6 +1380,9 @@ VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_fdir_del);
#define __vss_byone(p, member, count, old) \
(struct_size(p, member, count) + (old - 1 - struct_size(p, member, 0)))
#define __vss_byelem(p, member, count, old) \
(struct_size(p, member, count - 1) + (old - struct_size(p, member, 0)))
#define __vss_full(p, member, count, old) \
(struct_size(p, member, count) + (old - struct_size(p, member, 0)))
@@ -1390,6 +1396,9 @@ VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_fdir_del);
__vss(virtchnl_irq_map_info, __vss_full, p, m, c), \
__vss(virtchnl_ether_addr_list, __vss_full, p, m, c), \
__vss(virtchnl_vlan_filter_list, __vss_full, p, m, c), \
__vss(virtchnl_vlan_filter_list_v2, __vss_byelem, p, m, c), \
__vss(virtchnl_tc_info, __vss_byelem, p, m, c), \
__vss(virtchnl_rdma_qvlist_info, __vss_byelem, p, m, c), \
__vss(virtchnl_rss_key, __vss_byone, p, m, c), \
__vss(virtchnl_rss_lut, __vss_byone, p, m, c))
@@ -1495,13 +1504,13 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
case VIRTCHNL_OP_RELEASE_RDMA_IRQ_MAP:
break;
case VIRTCHNL_OP_CONFIG_RDMA_IRQ_MAP:
valid_len = sizeof(struct virtchnl_rdma_qvlist_info);
valid_len = virtchnl_rdma_qvlist_info_LEGACY_SIZEOF;
if (msglen >= valid_len) {
struct virtchnl_rdma_qvlist_info *qv =
(struct virtchnl_rdma_qvlist_info *)msg;
valid_len += ((qv->num_vectors - 1) *
sizeof(struct virtchnl_rdma_qv_info));
valid_len = virtchnl_struct_size(qv, qv_info,
qv->num_vectors);
}
break;
case VIRTCHNL_OP_CONFIG_RSS_KEY:
@@ -1534,12 +1543,12 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
valid_len = sizeof(struct virtchnl_vf_res_request);
break;
case VIRTCHNL_OP_ENABLE_CHANNELS:
valid_len = sizeof(struct virtchnl_tc_info);
valid_len = virtchnl_tc_info_LEGACY_SIZEOF;
if (msglen >= valid_len) {
struct virtchnl_tc_info *vti =
(struct virtchnl_tc_info *)msg;
valid_len += (vti->num_tc - 1) *
sizeof(struct virtchnl_channel_info);
valid_len = virtchnl_struct_size(vti, list,
vti->num_tc);
if (vti->num_tc == 0)
err_msg_format = true;
}
@@ -1566,13 +1575,13 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
break;
case VIRTCHNL_OP_ADD_VLAN_V2:
case VIRTCHNL_OP_DEL_VLAN_V2:
valid_len = sizeof(struct virtchnl_vlan_filter_list_v2);
valid_len = virtchnl_vlan_filter_list_v2_LEGACY_SIZEOF;
if (msglen >= valid_len) {
struct virtchnl_vlan_filter_list_v2 *vfl =
(struct virtchnl_vlan_filter_list_v2 *)msg;
valid_len += (vfl->num_elements - 1) *
sizeof(struct virtchnl_vlan_filter);
valid_len = virtchnl_struct_size(vfl, filters,
vfl->num_elements);
if (vfl->num_elements == 0) {
err_msg_format = true;