Skip to content

Commit 6e7066b

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: conntrack: remove sprintf usage
Replace it with scnprintf, the buffer sizes are expected to be large enough to hold the result, no need for snprintf+overflow check. Increase buffer size in mangle_content_len() while at it. BUG: KASAN: stack-out-of-bounds in vsnprintf+0xea5/0x1270 Write of size 1 at addr [..] vsnprintf+0xea5/0x1270 sprintf+0xb1/0xe0 mangle_content_len+0x1ac/0x280 nf_nat_sdp_session+0x1cc/0x240 process_sdp+0x8f8/0xb80 process_invite_request+0x108/0x2b0 process_sip_msg+0x5da/0xf50 sip_help_tcp+0x45e/0x780 nf_confirm+0x34d/0x990 [..] Fixes: 9fafcd7 ("[NETFILTER]: nf_conntrack/nf_nat: add SIP helper port") Reported-by: Yiming Qian <yimingqian591@gmail.com> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent 2195574 commit 6e7066b

2 files changed

Lines changed: 19 additions & 16 deletions

File tree

net/netfilter/nf_nat_amanda.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ static unsigned int help(struct sk_buff *skb,
5050
return NF_DROP;
5151
}
5252

53-
sprintf(buffer, "%u", port);
53+
snprintf(buffer, sizeof(buffer), "%u", port);
5454
if (!nf_nat_mangle_udp_packet(skb, exp->master, ctinfo,
5555
protoff, matchoff, matchlen,
5656
buffer, strlen(buffer))) {

net/netfilter/nf_nat_sip.c

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,25 +68,27 @@ static unsigned int mangle_packet(struct sk_buff *skb, unsigned int protoff,
6868
}
6969

7070
static int sip_sprintf_addr(const struct nf_conn *ct, char *buffer,
71+
size_t size,
7172
const union nf_inet_addr *addr, bool delim)
7273
{
7374
if (nf_ct_l3num(ct) == NFPROTO_IPV4)
74-
return sprintf(buffer, "%pI4", &addr->ip);
75+
return scnprintf(buffer, size, "%pI4", &addr->ip);
7576
else {
7677
if (delim)
77-
return sprintf(buffer, "[%pI6c]", &addr->ip6);
78+
return scnprintf(buffer, size, "[%pI6c]", &addr->ip6);
7879
else
79-
return sprintf(buffer, "%pI6c", &addr->ip6);
80+
return scnprintf(buffer, size, "%pI6c", &addr->ip6);
8081
}
8182
}
8283

8384
static int sip_sprintf_addr_port(const struct nf_conn *ct, char *buffer,
85+
size_t size,
8486
const union nf_inet_addr *addr, u16 port)
8587
{
8688
if (nf_ct_l3num(ct) == NFPROTO_IPV4)
87-
return sprintf(buffer, "%pI4:%u", &addr->ip, port);
89+
return scnprintf(buffer, size, "%pI4:%u", &addr->ip, port);
8890
else
89-
return sprintf(buffer, "[%pI6c]:%u", &addr->ip6, port);
91+
return scnprintf(buffer, size, "[%pI6c]:%u", &addr->ip6, port);
9092
}
9193

9294
static int map_addr(struct sk_buff *skb, unsigned int protoff,
@@ -119,7 +121,7 @@ static int map_addr(struct sk_buff *skb, unsigned int protoff,
119121
if (nf_inet_addr_cmp(&newaddr, addr) && newport == port)
120122
return 1;
121123

122-
buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, ntohs(newport));
124+
buflen = sip_sprintf_addr_port(ct, buffer, sizeof(buffer), &newaddr, ntohs(newport));
123125
return mangle_packet(skb, protoff, dataoff, dptr, datalen,
124126
matchoff, matchlen, buffer, buflen);
125127
}
@@ -212,7 +214,7 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff,
212214
&addr, true) > 0 &&
213215
nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.src.u3) &&
214216
!nf_inet_addr_cmp(&addr, &ct->tuplehash[!dir].tuple.dst.u3)) {
215-
buflen = sip_sprintf_addr(ct, buffer,
217+
buflen = sip_sprintf_addr(ct, buffer, sizeof(buffer),
216218
&ct->tuplehash[!dir].tuple.dst.u3,
217219
true);
218220
if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
@@ -229,7 +231,7 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff,
229231
&addr, false) > 0 &&
230232
nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.dst.u3) &&
231233
!nf_inet_addr_cmp(&addr, &ct->tuplehash[!dir].tuple.src.u3)) {
232-
buflen = sip_sprintf_addr(ct, buffer,
234+
buflen = sip_sprintf_addr(ct, buffer, sizeof(buffer),
233235
&ct->tuplehash[!dir].tuple.src.u3,
234236
false);
235237
if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
@@ -247,7 +249,7 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff,
247249
htons(n) == ct->tuplehash[dir].tuple.dst.u.udp.port &&
248250
htons(n) != ct->tuplehash[!dir].tuple.src.u.udp.port) {
249251
__be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port;
250-
buflen = sprintf(buffer, "%u", ntohs(p));
252+
buflen = scnprintf(buffer, sizeof(buffer), "%u", ntohs(p));
251253
if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
252254
poff, plen, buffer, buflen)) {
253255
nf_ct_helper_log(skb, ct, "cannot mangle rport");
@@ -418,7 +420,8 @@ static unsigned int nf_nat_sip_expect(struct sk_buff *skb, unsigned int protoff,
418420

419421
if (!nf_inet_addr_cmp(&exp->tuple.dst.u3, &exp->saved_addr) ||
420422
exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) {
421-
buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, port);
423+
buflen = sip_sprintf_addr_port(ct, buffer, sizeof(buffer),
424+
&newaddr, port);
422425
if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
423426
matchoff, matchlen, buffer, buflen)) {
424427
nf_ct_helper_log(skb, ct, "cannot mangle packet");
@@ -438,8 +441,8 @@ static int mangle_content_len(struct sk_buff *skb, unsigned int protoff,
438441
{
439442
enum ip_conntrack_info ctinfo;
440443
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
444+
char buffer[sizeof("4294967295")];
441445
unsigned int matchoff, matchlen;
442-
char buffer[sizeof("65536")];
443446
int buflen, c_len;
444447

445448
/* Get actual SDP length */
@@ -454,7 +457,7 @@ static int mangle_content_len(struct sk_buff *skb, unsigned int protoff,
454457
&matchoff, &matchlen) <= 0)
455458
return 0;
456459

457-
buflen = sprintf(buffer, "%u", c_len);
460+
buflen = scnprintf(buffer, sizeof(buffer), "%u", c_len);
458461
return mangle_packet(skb, protoff, dataoff, dptr, datalen,
459462
matchoff, matchlen, buffer, buflen);
460463
}
@@ -491,7 +494,7 @@ static unsigned int nf_nat_sdp_addr(struct sk_buff *skb, unsigned int protoff,
491494
char buffer[INET6_ADDRSTRLEN];
492495
unsigned int buflen;
493496

494-
buflen = sip_sprintf_addr(ct, buffer, addr, false);
497+
buflen = sip_sprintf_addr(ct, buffer, sizeof(buffer), addr, false);
495498
if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen,
496499
sdpoff, type, term, buffer, buflen))
497500
return 0;
@@ -509,7 +512,7 @@ static unsigned int nf_nat_sdp_port(struct sk_buff *skb, unsigned int protoff,
509512
char buffer[sizeof("nnnnn")];
510513
unsigned int buflen;
511514

512-
buflen = sprintf(buffer, "%u", port);
515+
buflen = scnprintf(buffer, sizeof(buffer), "%u", port);
513516
if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
514517
matchoff, matchlen, buffer, buflen))
515518
return 0;
@@ -529,7 +532,7 @@ static unsigned int nf_nat_sdp_session(struct sk_buff *skb, unsigned int protoff
529532
unsigned int buflen;
530533

531534
/* Mangle session description owner and contact addresses */
532-
buflen = sip_sprintf_addr(ct, buffer, addr, false);
535+
buflen = sip_sprintf_addr(ct, buffer, sizeof(buffer), addr, false);
533536
if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, sdpoff,
534537
SDP_HDR_OWNER, SDP_HDR_MEDIA, buffer, buflen))
535538
return 0;

0 commit comments

Comments
 (0)