patch 'pcapng: use malloc instead of fixed buffer size' has been queued to stable release 24.11.5

luca.boccassi at gmail.com luca.boccassi at gmail.com
Fri Feb 20 15:56:56 CET 2026


Hi,

FYI, your patch has been queued to stable release 24.11.5

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 02/22/26. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/bluca/dpdk-stable

This queued commit can be viewed at:
https://github.com/bluca/dpdk-stable/commit/34c9558bd7091b659240dda5f6d85c1ba7c74cb4

Thanks.

Luca Boccassi

---
>From 34c9558bd7091b659240dda5f6d85c1ba7c74cb4 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen at networkplumber.org>
Date: Mon, 16 Feb 2026 13:38:01 -0800
Subject: [PATCH] pcapng: use malloc instead of fixed buffer size

[ upstream commit edd9b971f7781390e050d4d2f54656ec8e98bbc1 ]

The administrative APIs accept comments and other metadata as
strings. Since these strings can be arbitrarily long (up to
UINT16_MAX bytes), they may overflow the fixed-size stack buffers
previously used for block construction.

Replace the fixed-size buffers with dynamically allocated memory
sized to the actual block length. Return appropriate error codes
on allocation failure.

Bugzilla ID: 1820
Fixes: 8d23ce8f5ee9 ("pcapng: add new library for writing pcapng files")

Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>
---
 lib/pcapng/rte_pcapng.c | 51 ++++++++++++++++++++++++++---------------
 lib/pcapng/rte_pcapng.h |  1 +
 2 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/lib/pcapng/rte_pcapng.c b/lib/pcapng/rte_pcapng.c
index e0d731e3f9..d5f4e86218 100644
--- a/lib/pcapng/rte_pcapng.c
+++ b/lib/pcapng/rte_pcapng.c
@@ -33,9 +33,6 @@
 /* conversion from DPDK speed to PCAPNG */
 #define PCAPNG_MBPS_SPEED 1000000ull
 
-/* upper bound for section, stats and interface blocks (in uint32_t) */
-#define PCAPNG_BLKSIZ	(2048 / sizeof(uint32_t))
-
 /* Format of the capture file handle */
 struct rte_pcapng {
 	int  outfd;		/* output file */
@@ -144,8 +141,9 @@ pcapng_section_block(rte_pcapng_t *self,
 {
 	struct pcapng_section_header *hdr;
 	struct pcapng_option *opt;
-	uint32_t buf[PCAPNG_BLKSIZ];
+	uint32_t *buf;
 	uint32_t len;
+	ssize_t ret;
 
 	len = sizeof(*hdr);
 	if (hw)
@@ -161,8 +159,9 @@ pcapng_section_block(rte_pcapng_t *self,
 	len += pcapng_optlen(0);
 	len += sizeof(uint32_t);
 
-	if (len > sizeof(buf))
-		return -1;
+	buf = malloc(len);
+	if (buf == NULL)
+		return -ENOMEM;
 
 	hdr = (struct pcapng_section_header *)buf;
 	*hdr = (struct pcapng_section_header) {
@@ -195,7 +194,9 @@ pcapng_section_block(rte_pcapng_t *self,
 	/* clone block_length after option */
 	memcpy(opt, &hdr->block_length, sizeof(uint32_t));
 
-	return write(self->outfd, buf, len);
+	ret = write(self->outfd, buf, len);
+	free(buf);
+	return ret < 0 ? -errno : 0;
 }
 
 /* Write an interface block for a DPDK port */
@@ -212,10 +213,11 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port,
 	struct pcapng_option *opt;
 	const uint8_t tsresol = 9;	/* nanosecond resolution */
 	uint32_t len;
-	uint32_t buf[PCAPNG_BLKSIZ];
+	uint32_t *buf;
 	char ifname_buf[IF_NAMESIZE];
 	char ifhw[256];
 	uint64_t speed = 0;
+	int ret;
 
 	if (rte_eth_dev_info_get(port, &dev_info) < 0)
 		return -1;
@@ -266,8 +268,9 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port,
 	len += pcapng_optlen(0);
 	len += sizeof(uint32_t);
 
-	if (len > sizeof(buf))
-		return -1;
+	buf = malloc(len);
+	if (buf == NULL)
+		return -1; /* ENOMEM */
 
 	hdr = (struct pcapng_interface_block *)buf;
 	*hdr = (struct pcapng_interface_block) {
@@ -310,10 +313,14 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port,
 	/* clone block_length after optionsa */
 	memcpy(opt, &hdr->block_length, sizeof(uint32_t));
 
-	/* remember the file index */
-	self->port_index[port] = self->ports++;
+	ret = write(self->outfd, buf, len);
+	free(buf);
 
-	return write(self->outfd, buf, len);
+	/* remember the file index only after successful write */
+	if (ret > 0)
+		self->port_index[port] = self->ports++;
+
+	return ret;
 }
 
 /*
@@ -329,7 +336,8 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
 	uint64_t start_time = self->offset_ns;
 	uint64_t sample_time;
 	uint32_t optlen, len;
-	uint32_t buf[PCAPNG_BLKSIZ];
+	uint32_t *buf;
+	ssize_t ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -349,8 +357,9 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
 		optlen += pcapng_optlen(0);
 
 	len = sizeof(*hdr) + optlen + sizeof(uint32_t);
-	if (len > sizeof(buf))
-		return -1;
+	buf = malloc(len);
+	if (buf == NULL)
+		return -ENOMEM;
 
 	hdr = (struct pcapng_statistics *)buf;
 	opt = (struct pcapng_option *)(hdr + 1);
@@ -381,7 +390,9 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
 	/* clone block_length after option */
 	memcpy(opt, &len, sizeof(uint32_t));
 
-	return write(self->outfd, buf, len);
+	ret = write(self->outfd, buf, len);
+	free(buf);
+	return ret;
 }
 
 uint32_t
@@ -684,6 +695,7 @@ rte_pcapng_fdopen(int fd,
 	rte_pcapng_t *self;
 	struct timespec ts;
 	uint64_t cycles;
+	int ret;
 
 	self = malloc(sizeof(*self));
 	if (!self) {
@@ -703,8 +715,11 @@ rte_pcapng_fdopen(int fd,
 	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
 		self->port_index[i] = UINT32_MAX;
 
-	if (pcapng_section_block(self, osname, hardware, appname, comment) < 0)
+	ret = pcapng_section_block(self, osname, hardware, appname, comment);
+	if (ret < 0) {
+		rte_errno = -ret;
 		goto fail;
+	}
 
 	return self;
 fail:
diff --git a/lib/pcapng/rte_pcapng.h b/lib/pcapng/rte_pcapng.h
index f51efcc6b1..9e11f3bcee 100644
--- a/lib/pcapng/rte_pcapng.h
+++ b/lib/pcapng/rte_pcapng.h
@@ -191,6 +191,7 @@ rte_pcapng_write_packets(rte_pcapng_t *self,
  *  On success number of bytes written to file,
  *   -1 on failure to write file (and errno is set)
  *   - (-EINVAL) if bad parameter.
+ *   - (-ENOMEM) if unable to allocate resources.
  */
 ssize_t
 rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port,
-- 
2.47.3

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2026-02-20 14:55:47.544567723 +0000
+++ 0114-pcapng-use-malloc-instead-of-fixed-buffer-size.patch	2026-02-20 14:55:43.376193990 +0000
@@ -1 +1 @@
-From edd9b971f7781390e050d4d2f54656ec8e98bbc1 Mon Sep 17 00:00:00 2001
+From 34c9558bd7091b659240dda5f6d85c1ba7c74cb4 Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit edd9b971f7781390e050d4d2f54656ec8e98bbc1 ]
+
@@ -17 +18,0 @@
-Cc: stable at dpdk.org
@@ -21 +22 @@
- lib/pcapng/rte_pcapng.c | 50 ++++++++++++++++++++++++++---------------
+ lib/pcapng/rte_pcapng.c | 51 ++++++++++++++++++++++++++---------------
@@ -23 +24 @@
- 2 files changed, 33 insertions(+), 18 deletions(-)
+ 2 files changed, 34 insertions(+), 18 deletions(-)
@@ -26 +27 @@
-index 4488eb0aca..c99dbca09d 100644
+index e0d731e3f9..d5f4e86218 100644
@@ -29,3 +30,3 @@
-@@ -37,9 +37,6 @@
- /* upper bound for strings in pcapng option data */
- #define PCAPNG_STR_MAX	UINT16_MAX
+@@ -33,9 +33,6 @@
+ /* conversion from DPDK speed to PCAPNG */
+ #define PCAPNG_MBPS_SPEED 1000000ull
@@ -39 +40 @@
-@@ -148,8 +145,9 @@ pcapng_section_block(rte_pcapng_t *self,
+@@ -144,8 +141,9 @@ pcapng_section_block(rte_pcapng_t *self,
@@ -50 +51 @@
-@@ -165,8 +163,9 @@ pcapng_section_block(rte_pcapng_t *self,
+@@ -161,8 +159,9 @@ pcapng_section_block(rte_pcapng_t *self,
@@ -62 +63 @@
-@@ -199,7 +198,9 @@ pcapng_section_block(rte_pcapng_t *self,
+@@ -195,7 +194,9 @@ pcapng_section_block(rte_pcapng_t *self,
@@ -73 +74 @@
-@@ -217,7 +218,7 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port, uint16_t link_type,
+@@ -212,10 +213,11 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port,
@@ -82 +83,5 @@
-@@ -279,8 +280,9 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port, uint16_t link_type,
++	int ret;
+ 
+ 	if (rte_eth_dev_info_get(port, &dev_info) < 0)
+ 		return -1;
+@@ -266,8 +268,9 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port,
@@ -87 +92 @@
--		return -1; /* EINVAL */
+-		return -1;
@@ -94,2 +99,2 @@
-@@ -323,10 +325,14 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port, uint16_t link_type,
- 	/* clone block_length after options */
+@@ -310,10 +313,14 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port,
+ 	/* clone block_length after optionsa */
@@ -112 +117 @@
-@@ -343,7 +349,8 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
+@@ -329,7 +336,8 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
@@ -122 +127 @@
-@@ -366,8 +373,9 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
+@@ -349,8 +357,9 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
@@ -134 +139 @@
-@@ -398,7 +406,9 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
+@@ -381,7 +390,9 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
@@ -144,2 +149,2 @@
- RTE_EXPORT_SYMBOL(rte_pcapng_mbuf_size)
-@@ -710,6 +720,7 @@ rte_pcapng_fdopen(int fd,
+ uint32_t
+@@ -684,6 +695,7 @@ rte_pcapng_fdopen(int fd,
@@ -151,3 +156,3 @@
- 	if ((osname && strlen(osname) > PCAPNG_STR_MAX) ||
- 	    (hardware && strlen(hardware) > PCAPNG_STR_MAX) ||
-@@ -737,8 +748,11 @@ rte_pcapng_fdopen(int fd,
+ 	self = malloc(sizeof(*self));
+ 	if (!self) {
+@@ -703,8 +715,11 @@ rte_pcapng_fdopen(int fd,
@@ -167 +172 @@
-index 68e13c67e4..d8d328f710 100644
+index f51efcc6b1..9e11f3bcee 100644
@@ -170 +175 @@
-@@ -199,6 +199,7 @@ rte_pcapng_write_packets(rte_pcapng_t *self,
+@@ -191,6 +191,7 @@ rte_pcapng_write_packets(rte_pcapng_t *self,


More information about the stable mailing list