Bug ID | 1521 |
---|---|
Summary | Potential null dereference in mlx5 |
Product | DPDK |
Version | unspecified |
Hardware | All |
OS | All |
Status | UNCONFIRMED |
Severity | normal |
Priority | Normal |
Component | ethdev |
Assignee | dev@dpdk.org |
Reporter | stephen@networkplumber.org |
Target Milestone | --- |
Building DPDK 24.11-rc0 with gcc 14 and analyzer (-fanalyzer) shows this (wordy) error. ../drivers/net/mlx5/mlx5_flow_hw.c: In function ‘mlx5_tbl_ensure_shared_modify_header’: ../drivers/net/mlx5/mlx5_flow_hw.c:2351:72: warning: dereference of NULL ‘0’ [CWE-476] [-Wanalyzer-null-dereference] 2351 | .sz = sizeof(struct mlx5_modification_cmd) * acts->mhdr->mhdr_cmds_num | ~~~~~~~~~~^~~~~~~~~~~~~~~ ‘mlx5_flow_hw_ctrl_flows’: events 1-4 | |15933 | mlx5_flow_hw_ctrl_flows(struct rte_eth_dev *dev, uint32_t flags) | | ^~~~~~~~~~~~~~~~~~~~~~~ | | | | | (1) entry to ‘mlx5_flow_hw_ctrl_flows’ |...... |15943 | if (!priv->dr_ctx) { | | ~ | | | | | (2) following ‘false’ branch... |...... |15949 | if (!priv->hw_ctrl_rx) { | | ~ ~~~~~~~~~~~~~~~~ | | | | | | | (3) ...to here | | (4) following ‘false’ branch... | ‘mlx5_flow_hw_ctrl_flows’: event 5 | |cc1: | (5): ...to here | ‘mlx5_flow_hw_ctrl_flows’: events 6-8 | |15956 | for (i = 0; i < MLX5_FLOW_HW_CTRL_RX_ETH_PATTERN_MAX; ++i) { | | ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (6) following ‘true’ branch (when ‘i != 10’)... |...... |15959 | if (!eth_pattern_type_is_requested(eth_pattern_type, flags)) | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (7) ...to here | | (8) calling ‘eth_pattern_type_is_requested’ from ‘mlx5_flow_hw_ctrl_flows’ | +--> ‘eth_pattern_type_is_requested’: event 9 | |15668 | eth_pattern_type_is_requested(const enum mlx5_flow_ctrl_rx_eth_pattern_type eth_pattern_type, | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (9) entry to ‘eth_pattern_type_is_requested’ | ‘eth_pattern_type_is_requested’: event 10 | |cc1: | (10): following ‘true’ branch (when ‘eth_pattern_type <= 9’)... | ‘eth_pattern_type_is_requested’: event 11 | |15672 | uint32_t vlan_flags = __calc_vlan_flags(eth_pattern_type); | | ^ | | | | | (11) inlined call to ‘__calc_vlan_flags’ from ‘eth_pattern_type_is_requested’ | +--> ‘__calc_vlan_flags’: events 12-13 | |15656 | switch (eth_pattern_type) { | | ^~~~~~ | | | | | (12) ...to here | | (13) following ‘default:’ branch... | <------+ | ‘eth_pattern_type_is_requested’: event 14 | |cc1: | (14): ...to here | ‘eth_pattern_type_is_requested’: events 15-16 | |15674 | bool consider_vlan = vlan_flags || (MLX5_CTRL_VLAN_FILTER & flags); | | ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | | | (16) ...to here | | (15) following ‘false’ branch... | <------+ | ‘mlx5_flow_hw_ctrl_flows’: events 17-18 | |15959 | if (!eth_pattern_type_is_requested(eth_pattern_type, flags)) | | ~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | | | (17) returning to ‘mlx5_flow_hw_ctrl_flows’ from ‘eth_pattern_type_is_requested’ | | (18) following ‘true’ branch... | ‘mlx5_flow_hw_ctrl_flows’: event 19 | |cc1: | (19): ...to here | ‘mlx5_flow_hw_ctrl_flows’: events 20-26 | |15961 | for (j = 0; j < MLX5_FLOW_HW_CTRL_RX_EXPANDED_RSS_MAX; ++j) { | | ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (20) following ‘true’ branch (when ‘j != 7’)... |...... |15965 | const struct mlx5_flow_template_table_cfg cfg = { | | ~~~ | | | | | (21) ...to here |...... |15978 | if (!rss_type_is_requested(priv, rss_type)) | | ~ | | | | | (22) following ‘true’ branch... |15979 | continue; |15980 | if (!tmpls->tbl) { | | ~ ~~~~~~~~~~ | | | | | | | (23) ...to here | | (24) following ‘true’ branch... |15981 | tmpls->tbl = flow_hw_table_create(dev, &cfg, | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (25) ...to here | | (26) calling ‘flow_hw_table_create’ from ‘mlx5_flow_hw_ctrl_flows’ |15982 | &tmpls->pt, 1, &at, 1, NULL); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +--> ‘flow_hw_table_create’: events 27-28 | | 4978 | flow_hw_table_create(struct rte_eth_dev *dev, | | ^~~~~~~~~~~~~~~~~~~~ | | | | | (27) entry to ‘flow_hw_table_create’ |...... | 5021 | if (!flow_hw_validate_table_domain(&attr->flow_attr)) { | | ~ | | | | | (28) following ‘false’ branch... | ‘flow_hw_table_create’: event 29 | |cc1: | (29): ...to here | ‘flow_hw_table_create’: events 30-49 | | 5026 | for (i = 0; i < nb_item_templates; i++) { | | ~~^~~~~~~~~~~~~~~~~~~ ~~~ | | | | | | | (33) ...to here | | (30) following ‘true’ branch... | 5027 | const struct rte_flow_pattern_template_attr *pt_attr = | 5028 | &item_templates[i]->attr; | | ~ | | | | | (31) ...to here |...... | 5033 | if (!match) { | | ~ | | | | | (32) following ‘true’ branch... |...... | 5040 | for (i = 0; i < nb_action_templates; i++) { | | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~ | | | | | | | (37) ...to here | | (34) following ‘true’ branch... | 5041 | const struct rte_flow_actions_template *at = action_templates[i]; | | ~ | | | | | (35) ...to here |...... | 5046 | if (!match) { | | ~ | | | | | (36) following ‘true’ branch... |...... | 5068 | if (nb_item_templates > max_tpl || | | ~ | | | | | (38) following ‘false’ branch... |...... | 5080 | tbl_mem_size += nb_action_templates * priv->nb_queue * sizeof(tbl->rule_acts[0]); | | ~~~~~~~~~~~~~~ | | | | | (39) ...to here |...... | 5083 | if (!tbl) | | ~ | | | | | (40) following ‘false’ branch (when ‘tbl’ is non-NULL)... | 5084 | goto error; | 5085 | tbl->cfg = *table_cfg; | | ~~~~~~~~~~~~~~~~~~~~~ | | | | | (41) ...to here |...... | 5088 | if (!tbl->flow) | | ~ | | | | | (42) following ‘false’ branch... |...... | 5092 | RTE_CACHE_LINE_SIZE, rte_dev_numa_node(dev->device)); | | ~~~~~~~~~~~ | | | | | (43) ...to here | 5093 | if (!tbl->flow_aux) | | ~ | | | | | (44) following ‘false’ branch... |...... | 5096 | ge = mlx5_hlist_register(priv->sh->groups, attr->flow_attr.group, &ctx); | | ~~~~~~~~~~~~~~~~~~~~~ | | | | | (45) ...to here | 5097 | if (!ge) | | ~ | | | | | (46) following ‘false’ branch (when ‘ge’ is non-NULL)... |...... | 5100 | tbl->grp = grp; | | ~~~~~~~~~~~~~~ | | | | | (47) ...to here |...... | 5109 | if (attr->hash_func == RTE_FLOW_TABLE_HASH_FUNC_CRC16) { | | ~ | | | | | (48) following ‘false’ branch... |...... | 5114 | matcher_attr.distribute_mode = flow_hw_matcher_distribute_mode_get(attr->hash_func); | | ~ | | | | | (49) inlined call to ‘flow_hw_matcher_distribute_mode_get’ from ‘flow_hw_table_create’ | +--> ‘flow_hw_matcher_distribute_mode_get’: event 50 | | 481 | if (hash_func == RTE_FLOW_TABLE_HASH_FUNC_LINEAR) | | ^ | | | | | (50) ...to here | <------+ | ‘flow_hw_table_create’: events 51-57 | | 5137 | for (i = 0; i < nb_item_templates; i++) { | | ~~^~~~~~~~~~~~~~~~~~~ | | | | | (51) following ‘true’ branch... | | (55) following ‘false’ branch... |...... | 5140 | if ((flow_attr.ingress && !item_templates[i]->attr.ingress) || | | ~~~~~~~~~~~~~~~~~ | | | | | (52) ...to here |...... | 5151 | if (ret <= 1) { | | ~ | | | | | (53) following ‘false’ branch... |...... | 5155 | mt[i] = item_templates[i]->mt; | | ~~~~~~~~~~~~~~~~~ | | | | | (54) ...to here |...... | 5158 | tbl->nb_item_templates = nb_item_templates; | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (56) ...to here | 5159 | /* Build the action template. */ | 5160 | err = mlx5_hw_build_template_table(dev, nb_action_templates, | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (57) calling ‘mlx5_hw_build_template_table’ from ‘flow_hw_table_create’ | 5161 | action_templates, at, tbl, &sub_error); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +--> ‘mlx5_hw_build_template_table’: events 58-59 | | 4876 | mlx5_hw_build_template_table(struct rte_eth_dev *dev, | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (58) entry to ‘mlx5_hw_build_template_table’ |...... | 4886 | for (i = 0; i < nb_action_templates; i++) { | | ~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (59) following ‘true’ branch (when ‘i < nb_action_templates’)... | ‘mlx5_hw_build_template_table’: event 60 | | 4887 | uint32_t refcnt = rte_atomic_fetch_add_explicit(&action_templates[i]->refcnt, 1, | | ^ | | | | | (60) ...to here ../lib/eal/include/rte_stdatomic.h:159:28: note: in definition of macro ‘rte_atomic_fetch_add_explicit’ | 159 | __atomic_fetch_add(ptr, val, memorder) | | ^~~ | ‘mlx5_hw_build_template_table’: events 61-65 | |../drivers/net/mlx5/mlx5_flow_hw.c:4890:20: | 4890 | if (refcnt <= 1) { | | ^ | | | | | (61) following ‘false’ branch... |...... | 4896 | at[i] = action_templates[i]->tmpl; | | ~~~~~~~~~~~~~~~~~~~ | | | | | (62) ...to here |...... | 4900 | if (!dev->data->dev_started) | | ~ | | | | | (63) following ‘false’ branch... | 4901 | continue; | 4902 | ret = flow_hw_translate_actions_template(dev, &tbl->cfg, | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (64) ...to here | | (65) inlined call to ‘flow_hw_translate_actions_template’ from ‘mlx5_hw_build_template_table’ | 4903 | &tbl->ats[i].acts, | | ~~~~~~~~~~~~~~~~~~ | 4904 | action_templates[i], | | ~~~~~~~~~~~~~~~~~~~~ | 4905 | &tbl->mpctx, error); | | ~~~~~~~~~~~~~~~~~~~ | +--> ‘flow_hw_translate_actions_template’: event 66 | | 2977 | return __flow_hw_translate_actions_template(dev, cfg, acts, at, mp_ctx, false, error); | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (66) calling ‘__flow_hw_translate_actions_template’ from ‘mlx5_hw_build_template_table’ | ‘__flow_hw_translate_actions_template’: events 67-74 | | 2468 | __flow_hw_translate_actions_template(struct rte_eth_dev *dev, | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (67) entry to ‘__flow_hw_translate_actions_template’ |...... | 2510 | for (; !actions_end; actions++, masks++) { | | ~~~~~~~~~~~~ | | | | | (68) following ‘false’ branch (when ‘actions_end == 0’)... | | (70) following ‘true’ branch (when ‘actions_end != 0’)... | 2511 | uint64_t pos = actions - at->actions; | | ~~~~~~~~~~~ | | | | | (69) ...to here |...... | 2899 | if (mhdr.pos != UINT16_MAX) { | | ~~~~~~~~~ | | | | | | | (71) ...to here | | (72) following ‘true’ branch... | 2900 | ret = mlx5_tbl_translate_modify_header(dev, cfg, acts, mp_ctx, &mhdr, error); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (73) ...to here | | (74) calling ‘mlx5_tbl_translate_modify_header’ from ‘__flow_hw_translate_actions_template’ | +--> ‘mlx5_tbl_translate_modify_header’: events 75-76 | | 2305 | mlx5_tbl_translate_modify_header(struct rte_eth_dev *dev, | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (75) entry to ‘mlx5_tbl_translate_modify_header’ |...... | 2317 | if (flow_hw_validate_compiled_modify_field(dev, cfg, mhdr, error)) { | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (76) calling ‘flow_hw_validate_compiled_modify_field’ from ‘mlx5_tbl_translate_modify_header’ | +--> ‘flow_hw_validate_compiled_modify_field’: events 77-81 | | 1662 | flow_hw_validate_compiled_modify_field(struct rte_eth_dev *dev, | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (77) entry to ‘flow_hw_validate_compiled_modify_field’ |...... | 1675 | if (cfg->attr.flow_attr.group != 0 && | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | | | (80) following ‘true’ branch... | | (78) following ‘true’ branch... | 1676 | mhdr->mhdr_cmds_num > hca_attr->max_header_modify_pattern_length) { | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (79) ...to here | 1677 | uint32_t nops = flow_hw_count_nop_modify_field(mhdr); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (81) ...to here | <------+ | ‘mlx5_tbl_translate_modify_header’: events 82-85 | | 2317 | if (flow_hw_validate_compiled_modify_field(dev, cfg, mhdr, error)) { | | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | || | | |(82) returning to ‘mlx5_tbl_translate_modify_header’ from ‘flow_hw_validate_compiled_modify_field’ | | (83) following ‘true’ branch... | 2318 | __flow_hw_action_template_destroy(dev, acts); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (84) ...to here | | (85) calling ‘__flow_hw_action_template_destroy’ from ‘mlx5_tbl_translate_modify_header’ | +--> ‘__flow_hw_action_template_destroy’: events 86-87 | | 943 | __flow_hw_action_template_destroy(struct rte_eth_dev *dev, struct mlx5_hw_actions *acts) | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (86) entry to ‘__flow_hw_action_template_destroy’ |...... | 954 | __flow_hw_actions_release(dev, acts); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (87) calling ‘__flow_hw_actions_release’ from ‘__flow_hw_action_template_destroy’ | +--> ‘__flow_hw_actions_release’: events 88-90 | | 884 | __flow_hw_actions_release(struct rte_eth_dev *dev, struct mlx5_hw_actions *acts) | | ^~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (88) entry to ‘__flow_hw_actions_release’ |...... | 916 | if (acts->mhdr) { | | ~ | | | | | (89) following ‘true’ branch... | 917 | flow_hw_template_destroy_mhdr_action(acts->mhdr); | | ~ | | | | | (90) inlined call to ‘flow_hw_template_destroy_mhdr_action’ from ‘__flow_hw_actions_release’ | +--> ‘flow_hw_template_destroy_mhdr_action’: event 91 | | 868 | if (mhdr->action && !mhdr->multi_pattern) | | ~~~~^~~~~~~~ | | | | | (91) ...to here | <------+ | ‘__flow_hw_actions_release’: events 92-96 | | 919 | acts->mhdr = NULL; | | ^ | | | | | (92) ‘0’ is NULL | 920 | } | 921 | if (mlx5_hws_cnt_id_valid(acts->cnt_id)) { | | ~ | | | | | (93) following ‘false’ branch... |...... | 925 | if (acts->mtr_id) { | | ~~~~~~~~~~~~~ | | | | | | | (94) ...to here | | (95) following ‘false’ branch... |...... | 929 | } | | ~ | | | | | (96) ...to here | <------+ | ‘__flow_hw_action_template_destroy’: event 97 | | 954 | __flow_hw_actions_release(dev, acts); | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (97) returning to ‘__flow_hw_action_template_destroy’ from ‘__flow_hw_actions_release’ | <------+ | ‘mlx5_tbl_translate_modify_header’: event 98 | | 2318 | __flow_hw_action_template_destroy(dev, acts); | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (98) returning to ‘mlx5_tbl_translate_modify_header’ from ‘__flow_hw_action_template_destroy’ | <------+ | ‘__flow_hw_translate_actions_template’: events 99-106 | | 2900 | ret = mlx5_tbl_translate_modify_header(dev, cfg, acts, mp_ctx, &mhdr, error); | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (99) returning to ‘__flow_hw_translate_actions_template’ from ‘mlx5_tbl_translate_modify_header’ | 2901 | if (ret) | | ~ | | | | | (100) following ‘false’ branch (when ‘ret == 0’)... | 2902 | goto err; | 2903 | if (!nt_mode && mhdr.shared) { | | ~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | | | (103) ...to here | | | (104) following ‘true’ branch... | | (101) ...to here | | (102) following ‘false’ branch (when ‘nt_mode == 0’)... | 2904 | ret = mlx5_tbl_ensure_shared_modify_header(dev, cfg, acts, error); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (105) ...to here | | (106) calling ‘mlx5_tbl_ensure_shared_modify_header’ from ‘__flow_hw_translate_actions_template’ | +--> ‘mlx5_tbl_ensure_shared_modify_header’: events 107-109 | | 2341 | mlx5_tbl_ensure_shared_modify_header(struct rte_eth_dev *dev, | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (107) entry to ‘mlx5_tbl_ensure_shared_modify_header’ |...... | 2351 | .sz = sizeof(struct mlx5_modification_cmd) * acts->mhdr->mhdr_cmds_num | | ~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | | | (109) dereference of NULL ‘*acts.mhdr’ | | (108) ‘0’ is NULL |