reject too-short PROXY v2 address length in mod_remoteip#683
reject too-short PROXY v2 address length in mod_remoteip#683arshsmith1 wants to merge 2 commits into
Conversation
| switch (hdr->v2.fam) { | ||
| case 0x11: /* TCPv4 */ | ||
| if (ntohs(hdr->v2.len) < sizeof(hdr->v2.addr.ip4)) { | ||
| ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(10595) |
There was a problem hiding this comment.
Please use APLOGNO() and let a maintainer fill in the next number as appropriate to avoid conflicts.
There was a problem hiding this comment.
Done, both are bare APLOGNO() now and I dropped the next-number bump so the file isn't touched at all.
Your concern was well founded, by the way: trunk has moved to 10597 since I opened this, and 10596 is now taken by mod_cern_meta.c, so my hardcoded number would have collided exactly as you describe.
| case 0x21: /* TCPv6 */ | ||
| #if APR_HAVE_IPV6 | ||
| if (ntohs(hdr->v2.len) < sizeof(hdr->v2.addr.ip6)) { | ||
| ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(10596) |
There was a problem hiding this comment.
Same here, this one's bare APLOGNO() too.
d1b4b70 to
aa6c438
Compare
|
Thanks, sorry a couple more bits of feedback -
|
|
Both done in bfcf178. Swapped the two checks over to remoteip_get_v2_len and moved that helper above remoteip_process_v2_header so it's in scope; the log format is now APR_SIZE_T_FMT to match the return type (same idiom as the need=/rcvd= message further down). On >= vs ==: the records are fixed length, but the v2 len field covers the address block plus any TLVs that follow it, so a longer value is legitimate. Spec section 2.2 says a receiver must use the length to skip the extra bytes it doesn't understand rather than reject them, and the block right after this already handles that (the too-long gate only rejects past sizeof(proxy_v2), and the parser just skips the remainder). So == would break any sender that appends TLVs, e.g. haproxy's PP2_TYPE_SSL or authority. The only unsafe case is len being smaller than the address struct we're about to read out of the buffer, which is what < catches. |
|
Makes sense, thanks a lot. |
remoteip_process_v2_header only bounds the advertised v2 header length from above, so a peer sending a TCPv4 or TCPv6 family with a length shorter than its address block makes the code read past what was actually received from the uninitialized ctx->header buffer and adopt those bytes as the client IP used for logging and Require ip decisions. Reject the header when ntohs(hdr->v2.len) is smaller than the family address struct, matching the existing too-long check right beside it.