summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-08-11 21:29:36 +0300
committerDenys Fedoryshchenko <denys.f@collabora.com>2026-08-11 21:29:36 +0300
commitc32518d76569d833b0470633426ebd1f1cf029f4 (patch)
tree15e4336303138174bc430eb0dc649122bbeeaa0d
parentbb62ae7b29a20f7c2d4e26b9f5ad330f1bcc3d73 (diff)
downloadaccel-ppp-c32518d76569d833b0470633426ebd1f1cf029f4.tar.gz
accel-ppp-c32518d76569d833b0470633426ebd1f1cf029f4.zip
pppoe: account for the tag header in the add_tag2 bound
add_tag2() checked that the tag payload fits into the packet buffer, but the memcpy() copied the 4 byte tag header as well, so the check was short by sizeof(struct pppoe_tag) - 1 bytes. All callers build the packet in a ETHER_MAX_LEN stack buffer and pass tags taken from the received discovery packet. A PADI carrying a Host-Uniq tag of 1454..1456 bytes therefore made pppoe_send_PADO() write up to 3 bytes of peer supplied data past the end of the buffer. The PADS, PADT and error paths are affected in the same way. Include the tag header in the bound, and drop the tag_len < 0 test which can never be true since ntohs() returns an unsigned value.
-rw-r--r--accel-pppd/ctrl/pppoe/pppoe.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c
index 0cc23180..d5896a59 100644
--- a/accel-pppd/ctrl/pppoe/pppoe.c
+++ b/accel-pppd/ctrl/pppoe/pppoe.c
@@ -792,7 +792,7 @@ static int add_tag2(uint8_t *pack, size_t pack_size, const struct pppoe_tag *t)
{
struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN);
struct pppoe_tag *tag = (struct pppoe_tag *)(pack + ETH_HLEN + sizeof(*hdr) + ntohs(hdr->length));
- if (pack_size <= ETH_HLEN + sizeof(*hdr) + ntohs(hdr->length) + ntohs(t->tag_len) || ntohs(t->tag_len) < 0)
+ if (pack_size <= ETH_HLEN + sizeof(*hdr) + ntohs(hdr->length) + sizeof(*t) + ntohs(t->tag_len))
return -1;
memcpy(tag, t, sizeof(*t) + ntohs(t->tag_len));