Commit fbce58e7 authored by Lukas Johannes Möller's avatar Lukas Johannes Möller Committed by Florian Westphal
Browse files

netfilter: nf_conntrack_sip: fix Content-Length u32 truncation in sip_help_tcp()



sip_help_tcp() parses the SIP Content-Length header with
simple_strtoul(), which returns unsigned long, but stores the result in
unsigned int clen.  On 64-bit systems, values exceeding UINT_MAX are
silently truncated before computing the SIP message boundary.

For example, Content-Length 4294967328 (2^32 + 32) is truncated to 32,
causing the parser to miscalculate where the current message ends.  The
loop then treats trailing data in the TCP segment as a second SIP
message and processes it through the SDP parser.

Fix this by changing clen to unsigned long to match the return type of
simple_strtoul(), and reject Content-Length values that exceed the
remaining TCP payload length.

Fixes: f5b321bd ("netfilter: nf_conntrack_sip: add TCP support")
Signed-off-by: default avatarLukas Johannes Möller <research@johannes-moeller.dev>
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
parent f900e1d7
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -1534,11 +1534,12 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
{
	struct tcphdr *th, _tcph;
	unsigned int dataoff, datalen;
	unsigned int matchoff, matchlen, clen;
	unsigned int matchoff, matchlen;
	unsigned int msglen, origlen;
	const char *dptr, *end;
	s16 diff, tdiff = 0;
	int ret = NF_ACCEPT;
	unsigned long clen;
	bool term;

	if (ctinfo != IP_CT_ESTABLISHED &&
@@ -1573,6 +1574,9 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
		if (dptr + matchoff == end)
			break;

		if (clen > datalen)
			break;

		term = false;
		for (; end + strlen("\r\n\r\n") <= dptr + datalen; end++) {
			if (end[0] == '\r' && end[1] == '\n' &&