pppoe_sess_send: check packet length before reading header

if the packet is too small then reading pack + ETH_HLEN is invalid, first
check that the packet is big enough then read the header at an offset we
know is valid

Reported-by: Coverity#375305
This commit is contained in:
Dominique Martinet 2022-11-05 21:35:53 +09:00
parent 54be500888
commit c770205890

15
pppoe.c
View file

@ -343,7 +343,7 @@ static void pppoe_disc_send(const uint8_t *pack)
void pppoe_sess_send(const uint8_t *pack, uint16_t l, tunnelidt t) void pppoe_sess_send(const uint8_t *pack, uint16_t l, tunnelidt t)
{ {
struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN); struct pppoe_hdr *hdr;
int n; int n;
uint16_t sizeppp; uint16_t sizeppp;
sessionidt s; sessionidt s;
@ -354,6 +354,13 @@ void pppoe_sess_send(const uint8_t *pack, uint16_t l, tunnelidt t)
return; return;
} }
if (l < (ETH_HLEN + sizeof(*hdr) + 3))
{
LOG(3, 0, t, "ERROR pppoe_sess_send: packet too small for pppoe sent (size=%d)\n", l);
return;
}
hdr = (struct pppoe_hdr *)(pack + ETH_HLEN);
s = ntohs(hdr->sid); s = ntohs(hdr->sid);
if (session[s].tunnel != t) if (session[s].tunnel != t)
{ {
@ -361,12 +368,6 @@ void pppoe_sess_send(const uint8_t *pack, uint16_t l, tunnelidt t)
return; return;
} }
if (l < (ETH_HLEN + sizeof(*hdr) + 3))
{
LOG(0, s, t, "ERROR pppoe_sess_send: packet too small for pppoe sent (size=%d)\n", l);
return;
}
// recalculate the ppp frame length // recalculate the ppp frame length
sizeppp = l - (ETH_HLEN + sizeof(*hdr)); sizeppp = l - (ETH_HLEN + sizeof(*hdr));
hdr->length = htons(sizeppp); hdr->length = htons(sizeppp);