fixeria has uploaded this change for review.
client: honor IPv4 header length in GPRS filter
The GPRS-NS/BSSGP filter assumed a fixed 20-byte IPv4 header (IP_LEN)
when locating the UDP header and payload. When the captured packet
carries IPv4 options (ip_hl > 5), udp_data/payload_data pointed into
the middle of the headers and check_gprs() parsed garbage, classifying
packets incorrectly.
Use the actual header length from ip_hl, reject malformed headers
(ip_hl < 5), and re-validate that the larger headers fit within the
captured length before computing the payload.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Change-Id: Iac1fa9cc2a3c06cbe19c3e7799a0b335f2e3dda9
---
M src/osmo_client_core.c
1 file changed, 13 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-pcap refs/changes/45/42845/1
diff --git a/src/osmo_client_core.c b/src/osmo_client_core.c
index dbc2588..61e7cc0 100644
--- a/src/osmo_client_core.c
+++ b/src/osmo_client_core.c
@@ -108,6 +108,7 @@
{
int ll_type;
int offset;
+ size_t ip_hdr_len;
struct ip *ip_hdr;
const u_char *ip_data;
const u_char *udp_data;
@@ -145,9 +146,19 @@
if (ip_hdr->ip_p != 17)
return 1;
- udp_data = ip_data + IP_LEN;
+ /* Honour the actual IPv4 header length (ip_hl), which may be larger
+ * than IP_LEN when IP options are present. */
+ ip_hdr_len = ip_hdr->ip_hl * 4;
+ if (ip_hdr_len < IP_LEN)
+ return 1; /* malformed IPv4 header */
+
+ /* Re-check that the (possibly larger) headers fit within the capture */
+ if (offset + ip_hdr_len + UDP_LEN + NS_LEN > hdr->caplen)
+ return 1;
+
+ udp_data = ip_data + ip_hdr_len;
payload_data = udp_data + UDP_LEN;
- payload_len = hdr->caplen - offset - IP_LEN - UDP_LEN;
+ payload_len = hdr->caplen - offset - ip_hdr_len - UDP_LEN;
return check_gprs(payload_data, payload_len);
}
To view, visit change 42845. To unsubscribe, or for help writing mail filters, visit settings.