2c9cd10
From: Daniel Borkmann <dborkman@redhat.com>
2c9cd10
Date: Mon, 10 Nov 2014 17:54:26 +0100
2c9cd10
Subject: [PATCH] net: sctp: fix NULL pointer dereference in
2c9cd10
 af->from_addr_param on malformed packet
2c9cd10
2c9cd10
An SCTP server doing ASCONF will panic on malformed INIT ping-of-death
2c9cd10
in the form of:
2c9cd10
2c9cd10
  ------------ INIT[PARAM: SET_PRIMARY_IP] ------------>
2c9cd10
2c9cd10
While the INIT chunk parameter verification dissects through many things
2c9cd10
in order to detect malformed input, it misses to actually check parameters
2c9cd10
inside of parameters. E.g. RFC5061, section 4.2.4 proposes a 'set primary
2c9cd10
IP address' parameter in ASCONF, which has as a subparameter an address
2c9cd10
parameter.
2c9cd10
2c9cd10
So an attacker may send a parameter type other than SCTP_PARAM_IPV4_ADDRESS
2c9cd10
or SCTP_PARAM_IPV6_ADDRESS, param_type2af() will subsequently return 0
2c9cd10
and thus sctp_get_af_specific() returns NULL, too, which we then happily
2c9cd10
dereference unconditionally through af->from_addr_param().
2c9cd10
2c9cd10
The trace for the log:
2c9cd10
2c9cd10
BUG: unable to handle kernel NULL pointer dereference at 0000000000000078
2c9cd10
IP: [<ffffffffa01e9c62>] sctp_process_init+0x492/0x990 [sctp]
2c9cd10
PGD 0
2c9cd10
Oops: 0000 [#1] SMP
2c9cd10
[...]
2c9cd10
Pid: 0, comm: swapper Not tainted 2.6.32-504.el6.x86_64 #1 Bochs Bochs
2c9cd10
RIP: 0010:[<ffffffffa01e9c62>]  [<ffffffffa01e9c62>] sctp_process_init+0x492/0x990 [sctp]
2c9cd10
[...]
2c9cd10
Call Trace:
2c9cd10
 <IRQ>
2c9cd10
 [<ffffffffa01f2add>] ? sctp_bind_addr_copy+0x5d/0xe0 [sctp]
2c9cd10
 [<ffffffffa01e1fcb>] sctp_sf_do_5_1B_init+0x21b/0x340 [sctp]
2c9cd10
 [<ffffffffa01e3751>] sctp_do_sm+0x71/0x1210 [sctp]
2c9cd10
 [<ffffffffa01e5c09>] ? sctp_endpoint_lookup_assoc+0xc9/0xf0 [sctp]
2c9cd10
 [<ffffffffa01e61f6>] sctp_endpoint_bh_rcv+0x116/0x230 [sctp]
2c9cd10
 [<ffffffffa01ee986>] sctp_inq_push+0x56/0x80 [sctp]
2c9cd10
 [<ffffffffa01fcc42>] sctp_rcv+0x982/0xa10 [sctp]
2c9cd10
 [<ffffffffa01d5123>] ? ipt_local_in_hook+0x23/0x28 [iptable_filter]
2c9cd10
 [<ffffffff8148bdc9>] ? nf_iterate+0x69/0xb0
2c9cd10
 [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0
2c9cd10
 [<ffffffff8148bf86>] ? nf_hook_slow+0x76/0x120
2c9cd10
 [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0
2c9cd10
[...]
2c9cd10
2c9cd10
A minimal way to address this is to check for NULL as we do on all
2c9cd10
other such occasions where we know sctp_get_af_specific() could
2c9cd10
possibly return with NULL.
2c9cd10
2c9cd10
Fixes: d6de3097592b ("[SCTP]: Add the handling of "Set Primary IP Address" parameter to INIT")
2c9cd10
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
2c9cd10
Cc: Vlad Yasevich <vyasevich@gmail.com>
2c9cd10
Acked-by: Neil Horman <nhorman@tuxdriver.com>
2c9cd10
Signed-off-by: David S. Miller <davem@davemloft.net>
2c9cd10
---
2c9cd10
 net/sctp/sm_make_chunk.c | 3 +++
2c9cd10
 1 file changed, 3 insertions(+)
2c9cd10
2c9cd10
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
2c9cd10
index ab734be8cb20..9f32741abb1c 100644
2c9cd10
--- a/net/sctp/sm_make_chunk.c
2c9cd10
+++ b/net/sctp/sm_make_chunk.c
2c9cd10
@@ -2609,6 +2609,9 @@ do_addr_param:
2c9cd10
 		addr_param = param.v + sizeof(sctp_addip_param_t);
2c9cd10
 
2c9cd10
 		af = sctp_get_af_specific(param_type2af(param.p->type));
2c9cd10
+		if (af == NULL)
2c9cd10
+			break;
2c9cd10
+
2c9cd10
 		af->from_addr_param(&addr, addr_param,
2c9cd10
 				    htons(asoc->peer.port), 0);
2c9cd10
 
2c9cd10
-- 
2c9cd10
1.9.3
2c9cd10