overflow: Change DEFINE_FLEX to take __counted_by member
The norm should be flexible array structures with __counted_by annotations, so DEFINE_FLEX() is updated to expect that. Rename the non-annotated version to DEFINE_RAW_FLEX(), and update the few existing users. Additionally add selftests for the macros. Reviewed-by: Gustavo A. R. Silva <gustavoars@kernel.org> Link: https://lore.kernel.org/r/20240306235128.it.933-kees@kernel.org Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
parent
acd80cdcee
commit
d8e45f2929
|
@ -956,7 +956,7 @@ ice_vsi_cfg_txq(struct ice_vsi *vsi, struct ice_tx_ring *ring,
|
|||
int ice_vsi_cfg_single_txq(struct ice_vsi *vsi, struct ice_tx_ring **tx_rings,
|
||||
u16 q_idx)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1);
|
||||
|
||||
if (q_idx >= vsi->alloc_txq || !tx_rings || !tx_rings[q_idx])
|
||||
return -EINVAL;
|
||||
|
@ -978,7 +978,7 @@ int ice_vsi_cfg_single_txq(struct ice_vsi *vsi, struct ice_tx_ring **tx_rings,
|
|||
static int
|
||||
ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_tx_ring **rings, u16 count)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1);
|
||||
int err = 0;
|
||||
u16 q_idx;
|
||||
|
||||
|
|
|
@ -4695,7 +4695,7 @@ ice_dis_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_queues,
|
|||
enum ice_disq_rst_src rst_src, u16 vmvf_num,
|
||||
struct ice_sq_cd *cd)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_dis_txq_item, qg_list, q_id, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_dis_txq_item, qg_list, q_id, 1);
|
||||
u16 i, buf_size = __struct_size(qg_list);
|
||||
struct ice_q_ctx *q_ctx;
|
||||
int status = -ENOENT;
|
||||
|
@ -4917,7 +4917,7 @@ int
|
|||
ice_dis_vsi_rdma_qset(struct ice_port_info *pi, u16 count, u32 *qset_teid,
|
||||
u16 *q_id)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_dis_txq_item, qg_list, q_id, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_dis_txq_item, qg_list, q_id, 1);
|
||||
u16 qg_size = __struct_size(qg_list);
|
||||
struct ice_hw *hw;
|
||||
int status = 0;
|
||||
|
|
|
@ -1938,8 +1938,8 @@ static enum ice_ddp_state ice_init_pkg_info(struct ice_hw *hw,
|
|||
*/
|
||||
static enum ice_ddp_state ice_get_pkg_info(struct ice_hw *hw)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_get_pkg_info_resp, pkg_info, pkg_info,
|
||||
ICE_PKG_CNT);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_get_pkg_info_resp, pkg_info, pkg_info,
|
||||
ICE_PKG_CNT);
|
||||
u16 size = __struct_size(pkg_info);
|
||||
u32 i;
|
||||
|
||||
|
@ -1990,8 +1990,8 @@ static enum ice_ddp_state ice_chk_pkg_compat(struct ice_hw *hw,
|
|||
struct ice_pkg_hdr *ospkg,
|
||||
struct ice_seg **seg)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_get_pkg_info_resp, pkg, pkg_info,
|
||||
ICE_PKG_CNT);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_get_pkg_info_resp, pkg, pkg_info,
|
||||
ICE_PKG_CNT);
|
||||
u16 size = __struct_size(pkg);
|
||||
enum ice_ddp_state state;
|
||||
u32 i;
|
||||
|
|
|
@ -491,7 +491,7 @@ static void
|
|||
ice_lag_move_vf_node_tc(struct ice_lag *lag, u8 oldport, u8 newport,
|
||||
u16 vsi_num, u8 tc)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
|
||||
struct device *dev = ice_pf_to_dev(lag->pf);
|
||||
u16 numq, valq, num_moved, qbuf_size;
|
||||
u16 buf_size = __struct_size(buf);
|
||||
|
@ -849,7 +849,7 @@ static void
|
|||
ice_lag_reclaim_vf_tc(struct ice_lag *lag, struct ice_hw *src_hw, u16 vsi_num,
|
||||
u8 tc)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
|
||||
struct device *dev = ice_pf_to_dev(lag->pf);
|
||||
u16 numq, valq, num_moved, qbuf_size;
|
||||
u16 buf_size = __struct_size(buf);
|
||||
|
@ -1873,7 +1873,7 @@ static void
|
|||
ice_lag_move_vf_nodes_tc_sync(struct ice_lag *lag, struct ice_hw *dest_hw,
|
||||
u16 vsi_num, u8 tc)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
|
||||
struct device *dev = ice_pf_to_dev(lag->pf);
|
||||
u16 numq, valq, num_moved, qbuf_size;
|
||||
u16 buf_size = __struct_size(buf);
|
||||
|
|
|
@ -237,7 +237,7 @@ static int
|
|||
ice_sched_remove_elems(struct ice_hw *hw, struct ice_sched_node *parent,
|
||||
u32 node_teid)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_delete_elem, buf, teid, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_delete_elem, buf, teid, 1);
|
||||
u16 buf_size = __struct_size(buf);
|
||||
u16 num_groups_removed = 0;
|
||||
int status;
|
||||
|
@ -2219,7 +2219,7 @@ int
|
|||
ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent,
|
||||
u16 num_items, u32 *list)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
|
||||
u16 buf_len = __struct_size(buf);
|
||||
struct ice_sched_node *node;
|
||||
u16 i, grps_movd = 0;
|
||||
|
|
|
@ -1812,7 +1812,7 @@ ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
|
|||
enum ice_sw_lkup_type lkup_type,
|
||||
enum ice_adminq_opc opc)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
|
||||
u16 buf_len = __struct_size(sw_buf);
|
||||
struct ice_aqc_res_elem *vsi_ele;
|
||||
int status;
|
||||
|
@ -2081,7 +2081,7 @@ ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
|
|||
*/
|
||||
int ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
|
||||
u16 buf_len = __struct_size(sw_buf);
|
||||
int status;
|
||||
|
||||
|
@ -4418,7 +4418,7 @@ int
|
|||
ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
|
||||
u16 *counter_id)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
|
||||
u16 buf_len = __struct_size(buf);
|
||||
int status;
|
||||
|
||||
|
@ -4446,7 +4446,7 @@ int
|
|||
ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
|
||||
u16 counter_id)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
|
||||
u16 buf_len = __struct_size(buf);
|
||||
int status;
|
||||
|
||||
|
@ -4476,7 +4476,7 @@ ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
|
|||
*/
|
||||
int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id)
|
||||
{
|
||||
DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
|
||||
DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
|
||||
u16 buf_len = __struct_size(buf);
|
||||
u16 res_type;
|
||||
int status;
|
||||
|
|
|
@ -398,7 +398,7 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
|
|||
* @count: Number of elements in the array; must be compile-time const.
|
||||
* @initializer: initializer expression (could be empty for no init).
|
||||
*/
|
||||
#define _DEFINE_FLEX(type, name, member, count, initializer) \
|
||||
#define _DEFINE_FLEX(type, name, member, count, initializer...) \
|
||||
_Static_assert(__builtin_constant_p(count), \
|
||||
"onstack flex array members require compile-time const count"); \
|
||||
union { \
|
||||
|
@ -408,8 +408,8 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
|
|||
type *name = (type *)&name##_u
|
||||
|
||||
/**
|
||||
* DEFINE_FLEX() - Define an on-stack instance of structure with a trailing
|
||||
* flexible array member.
|
||||
* DEFINE_RAW_FLEX() - Define an on-stack instance of structure with a trailing
|
||||
* flexible array member, when it does not have a __counted_by annotation.
|
||||
*
|
||||
* @type: structure type name, including "struct" keyword.
|
||||
* @name: Name for a variable to define.
|
||||
|
@ -420,7 +420,24 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
|
|||
* flexible array member.
|
||||
* Use __struct_size(@name) to get compile-time size of it afterwards.
|
||||
*/
|
||||
#define DEFINE_FLEX(type, name, member, count) \
|
||||
#define DEFINE_RAW_FLEX(type, name, member, count) \
|
||||
_DEFINE_FLEX(type, name, member, count, = {})
|
||||
|
||||
/**
|
||||
* DEFINE_FLEX() - Define an on-stack instance of structure with a trailing
|
||||
* flexible array member.
|
||||
*
|
||||
* @TYPE: structure type name, including "struct" keyword.
|
||||
* @NAME: Name for a variable to define.
|
||||
* @MEMBER: Name of the array member.
|
||||
* @COUNTER: Name of the __counted_by member.
|
||||
* @COUNT: Number of elements in the array; must be compile-time const.
|
||||
*
|
||||
* Define a zeroed, on-stack, instance of @TYPE structure with a trailing
|
||||
* flexible array member.
|
||||
* Use __struct_size(@NAME) to get compile-time size of it afterwards.
|
||||
*/
|
||||
#define DEFINE_FLEX(TYPE, NAME, MEMBER, COUNTER, COUNT) \
|
||||
_DEFINE_FLEX(TYPE, NAME, MEMBER, COUNT, = { .obj.COUNTER = COUNT, })
|
||||
|
||||
#endif /* __LINUX_OVERFLOW_H */
|
||||
|
|
|
@ -1172,6 +1172,24 @@ static void castable_to_type_test(struct kunit *test)
|
|||
#undef TEST_CASTABLE_TO_TYPE
|
||||
}
|
||||
|
||||
struct foo {
|
||||
int a;
|
||||
u32 counter;
|
||||
s16 array[] __counted_by(counter);
|
||||
};
|
||||
|
||||
static void DEFINE_FLEX_test(struct kunit *test)
|
||||
{
|
||||
DEFINE_RAW_FLEX(struct foo, two, array, 2);
|
||||
DEFINE_FLEX(struct foo, eight, array, counter, 8);
|
||||
DEFINE_FLEX(struct foo, empty, array, counter, 0);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, __struct_size(two),
|
||||
sizeof(struct foo) + sizeof(s16) + sizeof(s16));
|
||||
KUNIT_EXPECT_EQ(test, __struct_size(eight), 24);
|
||||
KUNIT_EXPECT_EQ(test, __struct_size(empty), sizeof(struct foo));
|
||||
}
|
||||
|
||||
static struct kunit_case overflow_test_cases[] = {
|
||||
KUNIT_CASE(u8_u8__u8_overflow_test),
|
||||
KUNIT_CASE(s8_s8__s8_overflow_test),
|
||||
|
@ -1194,6 +1212,7 @@ static struct kunit_case overflow_test_cases[] = {
|
|||
KUNIT_CASE(overflows_type_test),
|
||||
KUNIT_CASE(same_type_test),
|
||||
KUNIT_CASE(castable_to_type_test),
|
||||
KUNIT_CASE(DEFINE_FLEX_test),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue