From 817a3b938db89efa8ef63d610b43cb10321da446 Mon Sep 17 00:00:00 2001
From: hantwofish <hankangkang5@huawei.com>
Date: Tue, 7 May 2024 17:49:32 +0800
Subject: [PATCH] mod udp loop mem leak

---
 src/core/netif.c | 21 +++++++++++++++------
 src/core/pbuf.c  | 20 +++++++++++++++++---
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/src/core/netif.c b/src/core/netif.c
index 2fc8945..e6cdebe 100644
--- a/src/core/netif.c
+++ b/src/core/netif.c
@@ -1182,13 +1182,22 @@ udp_netif_loop_output(struct netif *netif, struct pbuf *p)
   LWIP_ASSERT("netif_loop_output: invalid pbuf", p != NULL);
 
   /* Allocate a new pbuf */
-  r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
-  if (r == NULL) {
-    LINK_STATS_INC(link.memerr);
-    LINK_STATS_INC(link.drop);
-    MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards);
-    return ERR_MEM;
+  u16_t p_clen = pbuf_clen(p);
+  struct pbuf *temp[p_clen];
+  for (int i = 0; i < p_clen; i++) {
+      temp[i] = pbuf_alloc(PBUF_LINK, p->len, PBUF_RAM);
+      if (temp[i] == NULL) {
+          LINK_STATS_INC(link.memerr);
+          LINK_STATS_INC(link.drop);
+          MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards);
+          pbuf_free(temp[0]);
+          return ERR_MEM;
+      }
+      if (i > 0) {
+          pbuf_cat(temp[0], temp[i]);
+      }
   }
+  r = temp[0];
 #if LWIP_LOOPBACK_MAX_PBUFS
   clen = pbuf_clen(r);
   /* check for overflow or too many pbuf on queue */
diff --git a/src/core/pbuf.c b/src/core/pbuf.c
index b0a63b4..914d1f4 100644
--- a/src/core/pbuf.c
+++ b/src/core/pbuf.c
@@ -1373,11 +1373,25 @@ pbuf_clone(pbuf_layer layer, pbuf_type type, struct pbuf *p)
 {
   struct pbuf *q;
   err_t err;
-  q = pbuf_alloc(layer, p->tot_len, type);
-  if (q == NULL) {
-    return NULL;
+  u16_t p_clen = pbuf_clen(p);
+  struct pbuf *temp[p_clen];
+  for (int i = 0; i < p_clen; i++) {
+      temp[i] = pbuf_alloc(PBUF_LINK, p->len, PBUF_RAM);
+      if (temp[i] == NULL) {
+          pbuf_free(temp[0]);
+          return NULL;
+      }
+      if (i > 0) {
+          pbuf_cat(temp[0], temp[i]);
+      }
   }
+  q = temp[0];
+
   err = pbuf_copy(q, p);
+  if (err != ERR_OK) {
+      pbuf_free(q);
+      return NULL;
+  }
   LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */
   LWIP_ASSERT("pbuf_copy failed", err == ERR_OK);
   return q;
-- 
2.33.0

