This diff cleans up extract_prefix(). The main point is to abort before writing anything.
PREFIX_SIZE() includes the length byte so exclude that again. I think overall the function is more readable now. -- :wq Claudio Index: util.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/util.c,v retrieving revision 1.74 diff -u -p -r1.74 util.c --- util.c 4 Jan 2023 14:33:30 -0000 1.74 +++ util.c 30 Mar 2023 13:09:52 -0000 @@ -501,19 +501,18 @@ extract_prefix(u_char *p, uint16_t len, static u_char addrmask[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; u_char *a = va; - int i; - uint16_t plen = 0; + int plen; - for (i = 0; pfxlen && i < max; i++) { - if (len <= plen) - return (-1); + plen = PREFIX_SIZE(pfxlen) - 1; + if (len < plen || max < plen) + return -1; + + while (pfxlen > 0) { if (pfxlen < 8) { - a[i] = *p++ & addrmask[pfxlen]; - plen++; + *a++ = *p++ & addrmask[pfxlen]; break; } else { - a[i] = *p++; - plen++; + *a++ = *p++; pfxlen -= 8; } }