[PATCH v5 1/5] pcapng: add length checks to string arguments

Stephen Hemminger
2026-01-19T18:20:29Z

The pcapng file format has a maximum possible string length
of 16 bits since information is recorded as type, value, length.

The API should check these lengths before possible memory
allocation or overwrite failures. Update Doxygen comments
to include return value.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/pcapng/rte_pcapng.c | 33 +++++++++++++++++++++++++++++----
lib/pcapng/rte_pcapng.h | 8 +++++++-
2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/lib/pcapng/rte_pcapng.c b/lib/pcapng/rte_pcapng.c
index 21bc94cea1..ac46e43b38 100644
--- a/lib/pcapng/rte_pcapng.c
+++ b/lib/pcapng/rte_pcapng.c
@@ -34,6 +34,9 @@
/* conversion from DPDK speed to PCAPNG */
#define PCAPNG_MBPS_SPEED 1000000ull

+/* upper bound for strings in pcapng option data */
+#define PCAPNG_STR_MAX UINT16_MAX
+
/* upper bound for section, stats and interface blocks (in uint32_t) */
#define PCAPNG_BLKSIZ (2048 / sizeof(uint32_t))

@@ -218,9 +221,11 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port, uint16_t link_type,
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;
+ ret = rte_eth_dev_info_get(port, &dev_info);
+ if (ret < 0)
+ return ret;

/* make something like an interface name */
if (ifname == NULL) {
@@ -230,8 +235,14 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port, uint16_t link_type,
snprintf(ifname_buf, IF_NAMESIZE, "dpdk:%u", port);
ifname = ifname_buf;
}
+ } else if (strlen(ifname) > PCAPNG_STR_MAX) {
+ return -EINVAL;
}

+ if ((ifdescr && strlen(ifdescr) > PCAPNG_STR_MAX) ||
+ (filter && strlen(filter) > PCAPNG_STR_MAX))
+ return -EINVAL;
+
/* make a useful device hardware string */
dev = dev_info.device;
if (dev)
@@ -269,7 +280,7 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port, uint16_t link_type,
len += sizeof(uint32_t);

if (len > sizeof(buf))
- return -1;
+ return -EINVAL;

hdr = (struct pcapng_interface_block *)buf;
*hdr = (struct pcapng_interface_block) {
@@ -337,6 +348,9 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,

RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);

+ if (comment && strlen(comment) > PCAPNG_STR_MAX)
+ return -1;
+
optlen = 0;

if (ifrecv != UINT64_MAX)
@@ -489,6 +503,9 @@ rte_pcapng_copy(uint16_t port_id, uint32_t queue,

#ifdef RTE_LIBRTE_ETHDEV_DEBUG
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
+
+ if (comment && strlen(comment) > PCAPNG_STR_MAX)
+ return NULL;
#endif
orig_len = rte_pktmbuf_pkt_len(md);

@@ -693,8 +710,16 @@ rte_pcapng_fdopen(int fd,
struct timespec ts;
uint64_t cycles;

+ if ((osname && strlen(osname) > PCAPNG_STR_MAX) ||
+ (hardware && strlen(hardware) > PCAPNG_STR_MAX) ||
+ (appname && strlen(appname) > PCAPNG_STR_MAX) ||
+ (comment && strlen(comment) > PCAPNG_STR_MAX)) {
+ rte_errno = ENAMETOOLONG;
+ return NULL;
+ }
+
self = malloc(sizeof(*self));
- if (!self) {
+ if (self == NULL) {
rte_errno = ENOMEM;
return NULL;
}
diff --git a/lib/pcapng/rte_pcapng.h b/lib/pcapng/rte_pcapng.h
index de1bf953e9..4f085f5c86 100644
--- a/lib/pcapng/rte_pcapng.h
+++ b/lib/pcapng/rte_pcapng.h
@@ -89,6 +89,12 @@ rte_pcapng_close(rte_pcapng_t *self);
* Interfaces must be added to the output file after opening
* and before any packet record. All ports used in packet capture
* must be added.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if bad parameter.
*/
int
rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port, uint16_t link_type,
@@ -192,7 +198,7 @@ rte_pcapng_write_packets(rte_pcapng_t *self,
* @param comment
* Optional comment to add to statistics.
* @return
- * number of bytes written to file, -1 on failure to write file
+ * number of bytes written to file, -1 on failure to write file or memory allocation failure.
*/
ssize_t
rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port,
--
2.51.0