From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 506DE456BE for ; Fri, 26 Jul 2024 21:43:13 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 19D6F4279A; Fri, 26 Jul 2024 21:43:13 +0200 (CEST) Received: from forward101d.mail.yandex.net (forward101d.mail.yandex.net [178.154.239.212]) by mails.dpdk.org (Postfix) with ESMTP id 39EB741133; Fri, 26 Jul 2024 21:43:11 +0200 (CEST) Received: from mail-nwsmtp-smtp-production-main-42.klg.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-42.klg.yp-c.yandex.net [IPv6:2a02:6b8:c42:8141:0:640:b0b3:0]) by forward101d.mail.yandex.net (Yandex) with ESMTPS id 5ADE26098A; Fri, 26 Jul 2024 22:43:10 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-42.klg.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id 4hXW24AoG8c0-cq48AbmM; Fri, 26 Jul 2024 22:43:09 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1722022989; bh=cw0fqz6TbVFnPU+9yXZOFvi0eeY99OP0heFNTg2KyiY=; h=Message-Id:Date:Cc:Subject:To:From; b=uHEfjoK4Jr1xAexdKhARFuEQjjJyM+c6ZKv5Ir8h2Nm6GcyJkfK+KCx7nidFPhacW 6dlW4qawFjAulgppQ90pyZH1ijKfXl7BL2DzbqSgHV3QrcEMz69zrpUiH7RzxS21SE IRZOvsOIjL0uUEQ1WLygXWdyXGf3XqWIWgsl/Nis= Authentication-Results: mail-nwsmtp-smtp-production-main-42.klg.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Konstantin Ananyev To: dev@dpdk.org Cc: Konstantin Ananyev , stable@dpdk.org Subject: [PATCH] examples/l3fwd: fix read beyond array bondaries Date: Fri, 26 Jul 2024 20:43:02 +0100 Message-Id: <20240726194302.920-1-konstantin.v.ananyev@yandex.ru> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org From: Konstantin Ananyev ASAN report: ERROR: AddressSanitizer: unknown-crash on address 0x7ffffef92e32 at pc 0x00000053d1e9 bp 0x7ffffef92c00 sp 0x7ffffef92bf8 READ of size 16 at 0x7ffffef92e32 thread T0 #0 0x53d1e8 in _mm_loadu_si128 /usr/lib64/gcc/x86_64-suse-linux/11/include/emmintrin.h:703 #1 0x53d1e8 in send_packets_multi ../examples/l3fwd/l3fwd_sse.h:125 #2 0x53d1e8 in acl_send_packets ../examples/l3fwd/l3fwd_acl.c:1048 #3 0x53ec18 in acl_main_loop ../examples/l3fwd/l3fwd_acl.c:1127 #4 0x12151eb in rte_eal_mp_remote_launch ../lib/eal/common/eal_common_launch.c:83 #5 0x5bf2df in main ../examples/l3fwd/main.c:1647 #6 0x7f6d42a0d2bc in __libc_start_main (/lib64/libc.so.6+0x352bc) #7 0x527499 in _start (/home/kananyev/dpdk-l3fwd-acl/x86_64-native-linuxapp-gcc-dbg-b1/examples/dpdk-l3fwd+0x527499) Reason for that is that send_packets_multi() uses 16B loads to access input dst_port[]and might read beyond array boundaries. Right now, it doesn't cause any real issue - junk values are ignored, also inside l3fwd we always allocate dst_port[] array on the stack, so memory beyond it is always available. Anyway, it probably need to be fixed. The patch below simply allocates extra space for dst_port[], so send_packets_multi() will never read beyond its boundaries. Probably a better fix would be to change send_packets_multi() itself to avoid access beyond 'nb_rx' entries. Bugzilla ID: 1502 Fixes: 94c54b4158d5 ("examples/l3fwd: rework exact-match") Cc: stable@dpdk.org Signed-off-by: Konstantin Ananyev --- examples/l3fwd/l3fwd_acl.c | 2 +- examples/l3fwd/l3fwd_altivec.h | 6 +++++- examples/l3fwd/l3fwd_common.h | 7 +++++++ examples/l3fwd/l3fwd_em_hlm.h | 2 +- examples/l3fwd/l3fwd_em_sequential.h | 2 +- examples/l3fwd/l3fwd_fib.c | 2 +- examples/l3fwd/l3fwd_lpm_altivec.h | 2 +- examples/l3fwd/l3fwd_lpm_neon.h | 2 +- examples/l3fwd/l3fwd_lpm_sse.h | 2 +- examples/l3fwd/l3fwd_neon.h | 6 +++++- examples/l3fwd/l3fwd_sse.h | 6 +++++- 11 files changed, 29 insertions(+), 10 deletions(-) diff --git a/examples/l3fwd/l3fwd_acl.c b/examples/l3fwd/l3fwd_acl.c index b635011ef7..baa01e6dde 100644 --- a/examples/l3fwd/l3fwd_acl.c +++ b/examples/l3fwd/l3fwd_acl.c @@ -1056,7 +1056,7 @@ int acl_main_loop(__rte_unused void *dummy) { struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; - uint16_t hops[MAX_PKT_BURST]; + uint16_t hops[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)]; unsigned int lcore_id; uint64_t prev_tsc, diff_tsc, cur_tsc; int i, nb_rx; diff --git a/examples/l3fwd/l3fwd_altivec.h b/examples/l3fwd/l3fwd_altivec.h index e45e138e59..b91a6b5587 100644 --- a/examples/l3fwd/l3fwd_altivec.h +++ b/examples/l3fwd/l3fwd_altivec.h @@ -11,6 +11,9 @@ #include "altivec/port_group.h" #include "l3fwd_common.h" +#undef SENDM_PORT_OVERHEAD +#define SENDM_PORT_OVERHEAD(x) ((x) + 2 * FWDSTEP) + /* * Update source and destination MAC addresses in the ethernet header. * Perform RFC1812 checks and updates for IPV4 packets. @@ -117,7 +120,8 @@ process_packet(struct rte_mbuf *pkt, uint16_t *dst_port) */ static __rte_always_inline void send_packets_multi(struct lcore_conf *qconf, struct rte_mbuf **pkts_burst, - uint16_t dst_port[MAX_PKT_BURST], int nb_rx) + uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)], + int nb_rx) { int32_t k; int j = 0; diff --git a/examples/l3fwd/l3fwd_common.h b/examples/l3fwd/l3fwd_common.h index 224b1c08e8..d94e5f1357 100644 --- a/examples/l3fwd/l3fwd_common.h +++ b/examples/l3fwd/l3fwd_common.h @@ -18,6 +18,13 @@ /* Minimum value of IPV4 total length (20B) in network byte order. */ #define IPV4_MIN_LEN_BE (sizeof(struct rte_ipv4_hdr) << 8) +/* + * send_packet_multi() specific number of dest ports + * due to implementation we need to allocate array bigger then + * actual max number of elements in the array. + */ +#define SENDM_PORT_OVERHEAD(x) (x) + /* * From http://www.rfc-editor.org/rfc/rfc1812.txt section 5.2.2: * - The IP version number must be 4. diff --git a/examples/l3fwd/l3fwd_em_hlm.h b/examples/l3fwd/l3fwd_em_hlm.h index 31cda9ddc1..c1d819997a 100644 --- a/examples/l3fwd/l3fwd_em_hlm.h +++ b/examples/l3fwd/l3fwd_em_hlm.h @@ -249,7 +249,7 @@ static inline void l3fwd_em_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, uint16_t portid, struct lcore_conf *qconf) { - uint16_t dst_port[MAX_PKT_BURST]; + uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)]; l3fwd_em_process_packets(nb_rx, pkts_burst, dst_port, portid, qconf, 0); send_packets_multi(qconf, pkts_burst, dst_port, nb_rx); diff --git a/examples/l3fwd/l3fwd_em_sequential.h b/examples/l3fwd/l3fwd_em_sequential.h index 067f23889a..3a40b2e434 100644 --- a/examples/l3fwd/l3fwd_em_sequential.h +++ b/examples/l3fwd/l3fwd_em_sequential.h @@ -79,7 +79,7 @@ l3fwd_em_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, uint16_t portid, struct lcore_conf *qconf) { int32_t i, j; - uint16_t dst_port[MAX_PKT_BURST]; + uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)]; if (nb_rx > 0) { rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[0], diff --git a/examples/l3fwd/l3fwd_fib.c b/examples/l3fwd/l3fwd_fib.c index f38b19af3f..a36330119a 100644 --- a/examples/l3fwd/l3fwd_fib.c +++ b/examples/l3fwd/l3fwd_fib.c @@ -121,7 +121,7 @@ fib_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, { uint32_t ipv4_arr[nb_rx]; uint8_t ipv6_arr[nb_rx][RTE_FIB6_IPV6_ADDR_SIZE]; - uint16_t hops[nb_rx]; + uint16_t hops[SENDM_PORT_OVERHEAD(nb_rx)]; uint64_t hopsv4[nb_rx], hopsv6[nb_rx]; uint8_t type_arr[nb_rx]; uint32_t ipv4_cnt = 0, ipv6_cnt = 0; diff --git a/examples/l3fwd/l3fwd_lpm_altivec.h b/examples/l3fwd/l3fwd_lpm_altivec.h index adb82f1478..91aad5c313 100644 --- a/examples/l3fwd/l3fwd_lpm_altivec.h +++ b/examples/l3fwd/l3fwd_lpm_altivec.h @@ -145,7 +145,7 @@ static inline void l3fwd_lpm_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, uint8_t portid, struct lcore_conf *qconf) { - uint16_t dst_port[MAX_PKT_BURST]; + uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)]; l3fwd_lpm_process_packets(nb_rx, pkts_burst, portid, dst_port, qconf, 0); diff --git a/examples/l3fwd/l3fwd_lpm_neon.h b/examples/l3fwd/l3fwd_lpm_neon.h index 2a68c4c15e..3c1f827424 100644 --- a/examples/l3fwd/l3fwd_lpm_neon.h +++ b/examples/l3fwd/l3fwd_lpm_neon.h @@ -171,7 +171,7 @@ static inline void l3fwd_lpm_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, uint16_t portid, struct lcore_conf *qconf) { - uint16_t dst_port[MAX_PKT_BURST]; + uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)]; l3fwd_lpm_process_packets(nb_rx, pkts_burst, portid, dst_port, qconf, 0); diff --git a/examples/l3fwd/l3fwd_lpm_sse.h b/examples/l3fwd/l3fwd_lpm_sse.h index db15030320..50f1abbd8a 100644 --- a/examples/l3fwd/l3fwd_lpm_sse.h +++ b/examples/l3fwd/l3fwd_lpm_sse.h @@ -129,7 +129,7 @@ static inline void l3fwd_lpm_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, uint16_t portid, struct lcore_conf *qconf) { - uint16_t dst_port[MAX_PKT_BURST]; + uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)]; l3fwd_lpm_process_packets(nb_rx, pkts_burst, portid, dst_port, qconf, 0); diff --git a/examples/l3fwd/l3fwd_neon.h b/examples/l3fwd/l3fwd_neon.h index 40807d5965..bc2bab8265 100644 --- a/examples/l3fwd/l3fwd_neon.h +++ b/examples/l3fwd/l3fwd_neon.h @@ -10,6 +10,9 @@ #include "neon/port_group.h" #include "l3fwd_common.h" +#undef SENDM_PORT_OVERHEAD +#define SENDM_PORT_OVERHEAD(x) ((x) + 2 * FWDSTEP) + /* * Update source and destination MAC addresses in the ethernet header. * Perform RFC1812 checks and updates for IPV4 packets. @@ -92,7 +95,8 @@ process_packet(struct rte_mbuf *pkt, uint16_t *dst_port) */ static __rte_always_inline void send_packets_multi(struct lcore_conf *qconf, struct rte_mbuf **pkts_burst, - uint16_t dst_port[MAX_PKT_BURST], int nb_rx) + uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)], + int nb_rx) { int32_t k; int j = 0; diff --git a/examples/l3fwd/l3fwd_sse.h b/examples/l3fwd/l3fwd_sse.h index 083729cdef..6236b7873c 100644 --- a/examples/l3fwd/l3fwd_sse.h +++ b/examples/l3fwd/l3fwd_sse.h @@ -10,6 +10,9 @@ #include "sse/port_group.h" #include "l3fwd_common.h" +#undef SENDM_PORT_OVERHEAD +#define SENDM_PORT_OVERHEAD(x) ((x) + 2 * FWDSTEP) + /* * Update source and destination MAC addresses in the ethernet header. * Perform RFC1812 checks and updates for IPV4 packets. @@ -91,7 +94,8 @@ process_packet(struct rte_mbuf *pkt, uint16_t *dst_port) */ static __rte_always_inline void send_packets_multi(struct lcore_conf *qconf, struct rte_mbuf **pkts_burst, - uint16_t dst_port[MAX_PKT_BURST], int nb_rx) + uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)], + int nb_rx) { int32_t k; int j = 0; -- 2.35.3