From b062d38b0e565776a6062171b3cb8ea8a09aa1be Mon Sep 17 00:00:00 2001 From: kircher Date: Mon, 29 May 2023 12:21:54 +0800 Subject: [PATCH] drop netbuf in recv_udp to fix mem overflow (cherry picked from commit 7500eab109ed443f73b37a1a7b219b8df7787653) --- ...tbuf-in-recv_udp-to-fix-mem-overflow.patch | 249 ++++++++++++++++++ lwip.spec | 7 +- 2 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 0074-drop-netbuf-in-recv_udp-to-fix-mem-overflow.patch diff --git a/0074-drop-netbuf-in-recv_udp-to-fix-mem-overflow.patch b/0074-drop-netbuf-in-recv_udp-to-fix-mem-overflow.patch new file mode 100644 index 0000000..7022817 --- /dev/null +++ b/0074-drop-netbuf-in-recv_udp-to-fix-mem-overflow.patch @@ -0,0 +1,249 @@ +From 2e51934e230013c9df58971df53a08dad108becf Mon Sep 17 00:00:00 2001 +From: kircher +Date: Mon, 29 May 2023 19:58:52 +0800 +Subject: [PATCH] drop-netbuf-in-recv_udp-to-fix-mem-overflow + +--- + src/api/api_lib.c | 14 ++++++++++++++ + src/api/api_msg.c | 15 ++++++++++++--- + src/api/sockets.c | 6 +++--- + src/core/udp.c | 8 ++++++++ + src/include/lwip/api.h | 3 +++ + src/include/lwip/pbuf.h | 4 ++++ + src/include/lwip/sockets.h | 8 ++++---- + src/include/lwipopts.h | 4 ++++ + 8 files changed, 52 insertions(+), 10 deletions(-) + +diff --git a/src/api/api_lib.c b/src/api/api_lib.c +index ffa14d6..afdfc11 100644 +--- a/src/api/api_lib.c ++++ b/src/api/api_lib.c +@@ -655,7 +655,11 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags) + #if (LWIP_UDP || LWIP_RAW) + { + LWIP_ASSERT("buf != NULL", buf != NULL); ++#if GAZELLE_UDP_ENABLE ++ len = ((struct pbuf *)buf)->tot_len; ++#else /* GAZELLE_UDP_ENABLE */ + len = netbuf_len((struct netbuf *)buf); ++#endif /* GAZELLE_UDP_ENABLE */ + } + #endif /* (LWIP_UDP || LWIP_RAW) */ + +@@ -827,6 +831,16 @@ netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf) + return netconn_recv_data(conn, (void **)new_buf, 0); + } + ++#if GAZELLE_UDP_ENABLE ++err_t ++netconn_recv_udp_raw_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags) ++{ ++ LWIP_ERROR("netconn_recv_udp_raw_pbuf: invalid conn", (conn != NULL) && ++ NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;); ++ return netconn_recv_data(conn, (void **)new_buf, apiflags); ++} ++#endif /* GAZELLE_UDP_ENABLE */ ++ + /** + * Receive data (in form of a netbuf) from a UDP or RAW netconn + * +diff --git a/src/api/api_msg.c b/src/api/api_msg.c +index 30929be..b82ebf2 100644 +--- a/src/api/api_msg.c ++++ b/src/api/api_msg.c +@@ -253,6 +253,14 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, + return; + } + ++#if GAZELLE_UDP_ENABLE ++ LWIP_UNUSED_ARG(buf); ++ ip_addr_set(&p->addr, addr); ++ p->port = port; ++ len = p->tot_len; ++ if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) { ++ return; ++#else /* GAZELLE_UDP_ENABLE */ + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + pbuf_free(p); +@@ -277,17 +285,18 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, + if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); + return; ++#endif /* GAZELLE_UDP_ENABLE */ + } else { + #if LWIP_SO_RCVBUF + SYS_ARCH_INC(conn->recv_avail, len); + #endif /* LWIP_SO_RCVBUF */ +-#if GAZELLE_ENABLE ++#if GAZELLE_UDP_ENABLE + add_recv_list(conn->socket); + LWIP_UNUSED_ARG(len); +-#else ++#else /* GAZELLE_UDP_ENABLE */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); +-#endif ++#endif /* GAZELLE_UDP_ENABLE */ + } + } + #endif /* LWIP_UDP */ +diff --git a/src/api/sockets.c b/src/api/sockets.c +index dee9230..17691f7 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -1179,7 +1179,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 + apiflags = 0; + } + +-#if !GAZELLE_ENABLE ++#if !GAZELLE_UDP_ENABLE + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw[UDP/RAW]: top sock->lastdata=%p\n", (void *)sock->lastdata.netbuf)); + /* Check if there is data left from the last recv operation. */ + buf = sock->lastdata.netbuf; +@@ -1267,7 +1267,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 + sock->lastdata.netbuf = NULL; + netbuf_delete(buf); + } +-#else /* GAZELLE_ENABLE */ ++#else /* GAZELLE_UDP_ENABLE */ + LWIP_UNUSED_ARG(copylen); + LWIP_UNUSED_ARG(buf); + LWIP_UNUSED_ARG(err); +@@ -1278,7 +1278,7 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16 + return ERR_BUF; + } + +-#endif /* GAZELLE_ENABLE */ ++#endif /* GAZELLE_UDP_ENABLE */ + if (datagram_len) { + *datagram_len = buflen; + } +diff --git a/src/core/udp.c b/src/core/udp.c +index 170c911..1eb459d 100644 +--- a/src/core/udp.c ++++ b/src/core/udp.c +@@ -599,6 +599,7 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, + UDP_STATS_INC(udp.rterr); + return ERR_RTE; + } ++#if GAZELLE_UDP_ENABLE + uint8_t apiflags = 0; + + struct pbuf *udp_pbuf = write_lwip_data((struct lwip_sock *)(p->payload), p->tot_len, &apiflags); +@@ -611,14 +612,21 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, + } + + if (p->port) { ++#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP ++ return udp_sendto_if_chksum(pcb, p, &(p->addr), p->port, netif, have_chksum, chksum); ++#else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ + return udp_sendto_if(pcb, p, &(p->addr), p->port, netif); ++#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ + } else { ++#endif /* GAZELLE_UDP_ENABLE */ + #if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP + return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum); + #else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ + return udp_sendto_if(pcb, p, dst_ip, dst_port, netif); + #endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ ++#if GAZELLE_UDP_ENABLE + } ++#endif /* GAZELLE_UDP_ENABLE */ + } + + /** +diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h +index d3c4f02..6090cab 100644 +--- a/src/include/lwip/api.h ++++ b/src/include/lwip/api.h +@@ -338,6 +338,9 @@ err_t netconn_accept(struct netconn *conn, struct netconn **new_conn); + err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf); + err_t netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf); + err_t netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags); ++#if GAZELLE_UDP_ENABLE ++err_t netconn_recv_udp_raw_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags); ++#endif /* GAZELLE_UDP_ENABLE */ + err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf); + err_t netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags); + err_t netconn_tcp_recvd(struct netconn *conn, size_t len); +diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h +index 728c5e4..4747f39 100644 +--- a/src/include/lwip/pbuf.h ++++ b/src/include/lwip/pbuf.h +@@ -40,8 +40,10 @@ + + #include "lwip/opt.h" + #include "lwip/err.h" ++#if GAZELLE_UDP_ENABLE + #include "lwip/ip_addr.h" + #include "lwip/ip6_addr.h" ++#endif /* GAZELLE_UDP_ENABLE */ + + #ifdef __cplusplus + extern "C" { +@@ -238,8 +240,10 @@ struct pbuf { + struct pbuf *last; + pthread_spinlock_t pbuf_lock; + struct tcp_pcb *pcb; ++#if GAZELLE_UDP_ENABLE + ip_addr_t addr; + u16_t port; ++#endif /* GAZELLE_UDP_ENABLE */ + #endif /* GAZELLE_ENABLE CHECKSUM_OFFLOAD_SWITCH */ + + /** In case the user needs to store data custom data on a pbuf */ +diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h +index 643093a..2b6e6be 100644 +--- a/src/include/lwip/sockets.h ++++ b/src/include/lwip/sockets.h +@@ -330,7 +330,7 @@ struct linger { + + + #if LWIP_MULTICAST_TX_OPTIONS +-#if GAZELLE_ENABLE ++#if GAZELLE_UDP_ENABLE + #define IP_MULTICAST_IF 32 + #define IP_MULTICAST_TTL 33 + #define IP_MULTICAST_LOOP 34 +@@ -341,11 +341,11 @@ struct linger { + #define IP_MULTICAST_TTL 5 + #define IP_MULTICAST_IF 6 + #define IP_MULTICAST_LOOP 7 +-#endif /* GAZELLE_ENABLE */ ++#endif /* GAZELLE_UDP_ENABLE */ + #endif /* LWIP_MULTICAST_TX_OPTIONS */ + + #if LWIP_IGMP +-#if GAZELLE_ENABLE ++#if GAZELLE_UDP_ENABLE + #define IP_ADD_MEMBERSHIP 35 + #define IP_DROP_MEMBERSHIP 36 + #else +@@ -354,7 +354,7 @@ struct linger { + */ + #define IP_ADD_MEMBERSHIP 3 + #define IP_DROP_MEMBERSHIP 4 +-#endif /* GAZELLE_ENABLE */ ++#endif /* GAZELLE_UDP_ENABLE */ + + typedef struct ip_mreq { + struct in_addr imr_multiaddr; /* IP multicast address of group */ +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index 6b5a2d1..9804aed 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h +@@ -63,6 +63,10 @@ + + #define GAZELLE_TCP_MIN_TSO_SEG_LEN 256 + ++ ++#define GAZELLE_UDP_ENABLE 1 ++ ++ + /* + ---------------------------------- + ---------- NIC offloads ---------- +-- +2.33.0 + diff --git a/lwip.spec b/lwip.spec index e27e87e..881194f 100644 --- a/lwip.spec +++ b/lwip.spec @@ -4,7 +4,7 @@ Summary: lwip is a small independent implementation of the TCP/IP protocol suite Name: lwip Version: 2.1.3 -Release: 64 +Release: 65 License: BSD URL: http://savannah.nongnu.org/projects/lwip/ Source0: http://download.savannah.nongnu.org/releases/lwip/%{name}-%{version}.zip @@ -85,6 +85,7 @@ Patch9069: 0070-cleancode-refactor-GAZELLE_TCP_PCB_HASH.patch Patch9070: 0071-cleancode-refactor-sys_now-and-lwip_ioctl.patch Patch9071: 0072-cleancode-refactor-OFFLOAD_CHECKSUM-GAZELLE_TCP_DATA.patch Patch9072: 0073-cleancode-refactor-memp.patch +Patch9073: 0074-drop-netbuf-in-recv_udp-to-fix-mem-overflow.patch BuildRequires: gcc-c++ dos2unix dpdk-devel @@ -174,6 +175,7 @@ find %{_builddir}/%{name}-%{version} -type f -exec dos2unix -q {} \; %patch9070 -p1 %patch9071 -p1 %patch9072 -p1 +%patch9073 -p1 %build cd %{_builddir}/%{name}-%{version}/src @@ -189,6 +191,9 @@ cd %{_builddir}/%{name}-%{version}/src %{_libdir}/liblwip.a %changelog +* Mon May 29 2023 kircher - 2.1.3-65 +- drop netbuf in recv_udp to fix mem overflow + * Mon May 29 2023 Lemmy Huang - 2.1.3-64 - cleancode: refactor memp