In the latest v4 version I submitted on December 18th, when I opened the -Wanalyzer-out-of-bounds and compiled it on the gcc14.2 environment, '''''' C compiler for the host machine: cc (gcc 14.2.1 "cc (GCC) 14.2.1 20241104 (Red Hat 14.2.1-6)") Compiler for C supports arguments -Wanalyzer-out-of-bounds: YES '''''' this issue did not occur; And [PATCH v4] net/zxdh: Provided zxdh basic init, this patch was submitted three months ago on September 9th; So, I am confused; Is this issue also present in the latest v4 submission version and do we need to solved it >Overall this looks good, one test checklist item for me was to build >with Gcc 14 and analyzer option. This finds bugs but can generate false >positives. The output is quite verbose. >It complains about this which may or may not be a real problem. >If memcpy() is used instead of rte_memcpy() then the problem goes away. >The issue is that inlined version rte_memcpy() will reference past the arguments >as an internal optimization for small values. >[1564/3222] Compiling C object drivers/libtmp_rte_net_zxdh.a.p/net_zxdh_zxdh_common.c.o >In file included from ../lib/mempool/rte_mempool.h:50, > from ../lib/mbuf/rte_mbuf.h:38, > from ../lib/net/rte_ether.h:20, > from ../lib/ethdev/rte_eth_ctrl.h:10, > from ../lib/ethdev/rte_ethdev.h:1472, > from ../lib/ethdev/ethdev_driver.h:21, > from ../drivers/net/zxdh/zxdh_common.c:8: >In function ‘rte_mov15_or_less’, > inlined from ‘rte_memcpy_generic’ at ../lib/eal/x86/include/rte_memcpy.h:395:10, > inlined from ‘rte_memcpy’ at ../lib/eal/x86/include/rte_memcpy.h:757:10, > inlined from ‘zxdh_get_res_info’ at ../drivers/net/zxdh/zxdh_common.c:231:2: >.../lib/eal/x86/include/rte_memcpy.h:82:55: warning: stack-based buffer overflow [CWE-121] [-Wanalyzer-out-of-bounds] > 82 | ((struct rte_uint64_alias *)dst)->val = > | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ > 83 | ((const struct rte_uint64_alias *)src)->val; > | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ‘zxdh_panelid_get’: events 1-3 > | > |../drivers/net/zxdh/zxdh_common.c:250:1: > | 239 | uint8_t reps = 0; > | | ~~~~ > | | | > | | (2) capacity: 1 byte > |...... > | 250 | zxdh_panelid_get(struct rte_eth_dev *dev, uint8_t *panelid) > | | ^~~~~~~~~~~~~~~~ > | | | > | | (1) entry to ‘zxdh_panelid_get’ > |...... > | 255 | int32_t ret = zxdh_get_res_panel_id(¶m, panelid); > | | ~ > | | | > | | (3) inlined call to ‘zxdh_get_res_panel_id’ from ‘zxdh_panelid_get’ > | > | > | 242 | if (zxdh_get_res_info(in, ZXDH_TBL_FIELD_PNLID, &reps, &reps_len) != ZXDH_BAR_MSG_OK) > | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > | | | > | | (4) calling ‘zxdh_get_res_info’ from ‘zxdh_panelid_get’ > | > ‘zxdh_get_res_info’: events 5-12 > | > | 186 | zxdh_get_res_info(struct zxdh_res_para *dev, uint8_t field, uint8_t *res, uint16_t *len) > | | ^~~~~~~~~~~~~~~~~ > | | | > | | (5) entry to ‘zxdh_get_res_info’ > |...... > | 192 | if (!res || !dev) > | | ~ > | | | > | | (6) following ‘false’ branch.... > |...... > | 195 | struct zxdh_tbl_msg_header tbl_msg = { > | | ~~~~~~~ > | | | > | | (7) ...to here > |...... > | 217 | if (ret != ZXDH_BAR_MSG_OK) { > | | ~ > | | | > | | (8) following ‘false’ branch (when ‘ret == 0’)... > |...... > | 225 | if (tbl_reps->check != ZXDH_TBL_MSG_PRO_SUCCESS) { > | | ~~~~~~~~~~~~~~~~ > | | | | > | | | (9) ...to here > | | (10) following ‘false’ branch... > |...... > | 230 | *len = tbl_reps->len; > | | ~~~~~~~~~~~~~ > | | | > | | (11) ...to here > | 231 | rte_memcpy(res, (recv_buf + ZXDH_REPS_HEADER_OFFSET + > | | ~ > | | | > | | (12) inlined call to ‘rte_memcpy’ from ‘zxdh_get_res_info’ > | > +--> ‘rte_memcpy’: events 13-14 > | > |../lib/eal/x86/include/rte_memcpy.h:754:12: > | 754 | if (!(((uintptr_t)dst | (uintptr_t)src) & ALIGNMENT_MASK)) > | | ^ > | | | > | | (13) following ‘false’ branch... > |...... > | 757 | return rte_memcpy_generic(dst, src, n); > | | ~ > | | | > | | (14) inlined call to ‘rte_memcpy_generic’ from ‘rte_memcpy’ > | > +--> ‘rte_memcpy_generic’: events 15-17 > | > | 394 | if (n < 16) { > | | ^ > | | | > | | (15) ...to here > | | (16) following ‘true’ branch... > | 395 | return rte_mov15_or_less(dst, src, n); > | | ~ > | | | > | | (17) inlined call to ‘rte_mov15_or_less’ from ‘rte_memcpy_generic’ > | > +--> ‘rte_mov15_or_less’: events 18-21 > | > | 81 | if (n & 8) { > | | ^ > | | | > | | (18) ...to here > | | (19) following ‘true’ branch... > | 82 | ((struct rte_uint64_alias *)dst)->val = > | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > | | | > | | (21) out-of-bounds write from byte 1 till byte 7 but ‘reps’ ends at byte 1 > | 83 | ((const struct rte_uint64_alias *)src)->val; > | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > | | | > | | (20) ...to here > | >.../lib/eal/x86/include/rte_memcpy.h:82:55: note: write of 7 bytes to beyond the end of ‘reps’ > 82 | ((struct rte_uint64_alias *)dst)->val = > | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ > 83 | ((const struct rte_uint64_alias *)src)->val; > | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > ┌──────────────────────────────────────────────────────────────────────┐ > │ write of ‘uint64_t’ (8 bytes) │ > └──────────────────────────────────────────────────────────────────────┘ > │ │ > │ │ > v v > ┌────────────────────────┐┌────────────────────────────────────────────┐ > │‘reps’ (type: ‘uint8_t’)││ after valid range │ > └────────────────────────┘└────────────────────────────────────────────┘ > ├───────────┬────────────┤├─────────────────────┬──────────────────────┤ > │ │ > ╭────────┴───────╮ ╭───────────┴──────────╮ > │capacity: 1 byte│ │⚠️ overflow of 7 bytes│ > ╰────────────────╯ ╰──────────────────────╯