From a6222f2b0e63f377b225f9f4a6f73c368d298d3d Mon Sep 17 00:00:00 2001 From: Hashim1999164 Date: Fri, 4 Sep 2026 23:16:36 +0500 Subject: [PATCH] lldp: fix TLV query corruption and module UAF get_tlvs compacted matching TLVs with memcpy even when the source and destination overlapped, which corrupted filtered neighbor TLV output. Also stop delivering a TLV to later modules once one returns TLV_OK so a handler that frees the TLV cannot leave a use after free. Fixes: https://github.com/intel/openlldp/issues/127 Signed-off-by: Hashim1999164 --- lldp/rx.c | 8 ++++++-- lldp_mand_cmds.c | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lldp/rx.c b/lldp/rx.c index f44b439..8f6f220 100644 --- a/lldp/rx.c +++ b/lldp/rx.c @@ -407,9 +407,13 @@ void rxProcessFrame(struct port *port, struct lldp_agent *agent) err = np->ops->lldp_mod_rchange(port, agent, tlv); - if (!err) + if (!err) { + /* Module claimed the TLV; do not pass a possibly freed + * pointer to later modules in the list. + */ tlv_stored = true; - else if (err == TLV_ERR) { + break; + } else if (err == TLV_ERR) { frame_error++; free_unpkd_tlv(tlv); goto out; diff --git a/lldp_mand_cmds.c b/lldp_mand_cmds.c index bfbe98f..e90cdf8 100644 --- a/lldp_mand_cmds.c +++ b/lldp_mand_cmds.c @@ -695,7 +695,8 @@ int get_tlvs(struct cmd *cmd, char *rbuf, int rlen) } if (tlvid == cmd->tlvid) { - memcpy(tlvs+moff, tlvs+off, sizeof(u16)+len); + /* overlapping src/dst when matching TLVs are compacted forward */ + memmove(tlvs+moff, tlvs+off, sizeof(u16)+len); moff += sizeof(u16)+len; }