Probable bug in parse_proxy_proto_header_v2() when using listen-proxy-proto + PROXY v2 + IPv6
We likely found a functional correctness issue in upstream ocserv 1.4.2, in worker-proxyproto.c (line 459), function parse_proxy_proto_header_v2() (TCP6 branch).
In the IPv6 path, sin6_family for our_addr is assigned before sa is redirected to &ws->our_addr. As a result, ws->our_addr may remain AF_UNSPEC while our_addr_len is set to sizeof(struct sockaddr_in6).
This appears only in deployments that use:
- listen-proxy-proto
- PROXY protocol v2
- IPv6 client/frontend addressing
Observed/expected impact:
- This affects destination/local-side metadata (our_addr, usually frontend VIP/proxy destination), not the client remote IP.
- occtl show user *username may still show client ip correctly, but local-side address fields (local_dev_ip / Local Device IP) can become empty or incorrect.
- Script environment field IP_REAL_LOCAL may also be missing/incorrect.
Current code (upstream 1.4.2):
memset(&ws->our_addr, 0, sizeof(ws->our_addr));
sa->sin6_family = AF_INET6;
sa = (void *)&ws->our_addr;
memcpy(&sa->sin6_addr, p + 16, 16);
memcpy(&sa->sin6_port, p + 34, 2);
ws->our_addr_len = sizeof(struct sockaddr_in6);Suggested fix:
memset(&ws->our_addr, 0, sizeof(ws->our_addr));
sa = (void *)&ws->our_addr;
sa->sin6_family = AF_INET6;
memcpy(&sa->sin6_addr, p + 16, 16);
memcpy(&sa->sin6_port, p + 34, 2);
ws->our_addr_len = sizeof(struct sockaddr_in6);Note: We have not practically validated this on a live proxy-fronted setup yet, because we currently do not have a test stand with a TLS proxy in front of ocserv.
Edited by Dimitri Papadopoulos Orfanos