linux/include/net
Daniel Borkmann e36b6ac9e0 net: sctp: fix skb_over_panic when receiving malformed ASCONF chunks
commit 9de7922bc7 upstream.

Commit 6f4c618ddb ("SCTP : Add paramters validity check for
ASCONF chunk") added basic verification of ASCONF chunks, however,
it is still possible to remotely crash a server by sending a
special crafted ASCONF chunk, even up to pre 2.6.12 kernels:

skb_over_panic: text:ffffffffa01ea1c3 len:31056 put:30768
 head:ffff88011bd81800 data:ffff88011bd81800 tail:0x7950
 end:0x440 dev:<NULL>
 ------------[ cut here ]------------
kernel BUG at net/core/skbuff.c:129!
[...]
Call Trace:
 <IRQ>
 [<ffffffff8144fb1c>] skb_put+0x5c/0x70
 [<ffffffffa01ea1c3>] sctp_addto_chunk+0x63/0xd0 [sctp]
 [<ffffffffa01eadaf>] sctp_process_asconf+0x1af/0x540 [sctp]
 [<ffffffff8152d025>] ? _read_unlock_bh+0x15/0x20
 [<ffffffffa01e0038>] sctp_sf_do_asconf+0x168/0x240 [sctp]
 [<ffffffffa01e3751>] sctp_do_sm+0x71/0x1210 [sctp]
 [<ffffffff8147645d>] ? fib_rules_lookup+0xad/0xf0
 [<ffffffffa01e6b22>] ? sctp_cmp_addr_exact+0x32/0x40 [sctp]
 [<ffffffffa01e8393>] sctp_assoc_bh_rcv+0xd3/0x180 [sctp]
 [<ffffffffa01ee986>] sctp_inq_push+0x56/0x80 [sctp]
 [<ffffffffa01fcc42>] sctp_rcv+0x982/0xa10 [sctp]
 [<ffffffffa01d5123>] ? ipt_local_in_hook+0x23/0x28 [iptable_filter]
 [<ffffffff8148bdc9>] ? nf_iterate+0x69/0xb0
 [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0
 [<ffffffff8148bf86>] ? nf_hook_slow+0x76/0x120
 [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0
 [<ffffffff81496ded>] ip_local_deliver_finish+0xdd/0x2d0
 [<ffffffff81497078>] ip_local_deliver+0x98/0xa0
 [<ffffffff8149653d>] ip_rcv_finish+0x12d/0x440
 [<ffffffff81496ac5>] ip_rcv+0x275/0x350
 [<ffffffff8145c88b>] __netif_receive_skb+0x4ab/0x750
 [<ffffffff81460588>] netif_receive_skb+0x58/0x60

This can be triggered e.g., through a simple scripted nmap
connection scan injecting the chunk after the handshake, for
example, ...

  -------------- INIT[ASCONF; ASCONF_ACK] ------------->
  <----------- INIT-ACK[ASCONF; ASCONF_ACK] ------------
  -------------------- COOKIE-ECHO -------------------->
  <-------------------- COOKIE-ACK ---------------------
  ------------------ ASCONF; UNKNOWN ------------------>

... where ASCONF chunk of length 280 contains 2 parameters ...

  1) Add IP address parameter (param length: 16)
  2) Add/del IP address parameter (param length: 255)

... followed by an UNKNOWN chunk of e.g. 4 bytes. Here, the
Address Parameter in the ASCONF chunk is even missing, too.
This is just an example and similarly-crafted ASCONF chunks
could be used just as well.

The ASCONF chunk passes through sctp_verify_asconf() as all
parameters passed sanity checks, and after walking, we ended
up successfully at the chunk end boundary, and thus may invoke
sctp_process_asconf(). Parameter walking is done with
WORD_ROUND() to take padding into account.

In sctp_process_asconf()'s TLV processing, we may fail in
sctp_process_asconf_param() e.g., due to removal of the IP
address that is also the source address of the packet containing
the ASCONF chunk, and thus we need to add all TLVs after the
failure to our ASCONF response to remote via helper function
sctp_add_asconf_response(), which basically invokes a
sctp_addto_chunk() adding the error parameters to the given
skb.

When walking to the next parameter this time, we proceed
with ...

  length = ntohs(asconf_param->param_hdr.length);
  asconf_param = (void *)asconf_param + length;

... instead of the WORD_ROUND()'ed length, thus resulting here
in an off-by-one that leads to reading the follow-up garbage
parameter length of 12336, and thus throwing an skb_over_panic
for the reply when trying to sctp_addto_chunk() next time,
which implicitly calls the skb_put() with that length.

Fix it by using sctp_walk_params() [ which is also used in
INIT parameter processing ] macro in the verification *and*
in ASCONF processing: it will make sure we don't spill over,
that we walk parameters WORD_ROUND()'ed. Moreover, we're being
more defensive and guard against unknown parameter types and
missized addresses.

Joint work with Vlad Yasevich.

Fixes: b896b82be4ae ("[SCTP] ADDIP: Support for processing incoming ASCONF_ACK chunks.")
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Cc: Josh Boyer <jwboyer@fedoraproject.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-21 09:23:06 -08:00
..
9p for-linus-3.12-merge minor 9p fixes and tweaks for 3.12 merge window 2013-09-11 12:34:13 -07:00
bluetooth Bluetooth: Add quirk for disabling Delete Stored Link Key command 2014-01-04 20:10:40 +02:00
caif caif_hsi.h: Remove extern from function prototypes 2013-09-23 16:29:41 -04:00
irda include/net/: Fix FSF address in file headers 2013-12-06 12:37:56 -05:00
iucv
netfilter netfilter: nf_conntrack: reserve two bytes for nf_ct_ext->len 2014-05-31 13:20:27 -07:00
netns ipv6: add flowlabel_consistency sysctl 2014-01-19 17:12:31 -08:00
nfc Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem 2014-01-17 14:43:17 -05:00
phonet
sctp net: sctp: fix skb_over_panic when receiving malformed ASCONF chunks 2014-11-21 09:23:06 -08:00
tc_act include/net/: Fix FSF address in file headers 2013-12-06 12:37:56 -05:00
Space.h drivers: net: Include new header file in sbni.c 2013-12-19 18:51:20 -05:00
act_api.h net_sched: act: export tcf_hash_search() instead of tcf_hash_lookup() 2014-01-21 14:43:16 -08:00
addrconf.h ipv6: enable anycast addresses as source addresses for datagrams 2014-01-22 21:57:05 -08:00
af_ieee802154.h
af_rxrpc.h af_rxrpc.h: Remove extern from function prototypes 2013-07-31 17:50:01 -07:00
af_unix.h af_unix: improve STREAM behavior with fragmented memory 2013-08-10 01:16:44 -07:00
af_vsock.h vsock: Make transport the proto owner 2014-05-31 13:20:36 -07:00
ah.h
arp.h arp: make arp_invalidate static 2013-12-28 17:02:46 -05:00
atmclip.h
ax25.h ax25.h: Remove extern from function prototypes 2013-07-31 17:50:02 -07:00
ax88796.h
busy_poll.h sched, net: Fixup busy_loop_us_clock() 2014-01-13 17:39:11 +01:00
cfg80211-wext.h
cfg80211.h cfg80211: add cfg80211_sched_scan_stopped_rtnl 2014-06-07 10:28:10 -07:00
checksum.h net: checksum: fix warning in skb_checksum 2013-11-04 15:27:08 -05:00
cipso_ipv4.h cipso: cleanup cipso_v4_translate() when !CONFIG_NETLABEL 2013-12-10 17:56:54 -05:00
cls_cgroup.h net: net_cls: move cgroupfs classid handling into core 2014-01-03 23:41:41 +01:00
codel.h net: introduce reciprocal_scale helper and convert users 2014-01-21 23:17:20 -08:00
compat.h compat.h: Remove extern from function prototypes 2013-09-20 14:49:32 -04:00
datalink.h net: Move prototype declaration to header file include/net/datalink.h from net/ipx/af_ipx.c 2014-02-09 17:32:50 -08:00
dcbevent.h include/net/: Fix FSF address in file headers 2013-12-06 12:37:56 -05:00
dcbnl.h include/net/: Fix FSF address in file headers 2013-12-06 12:37:56 -05:00
dn.h net: Move prototype declaration to header file include/net/dn.h from net/decnet/af_decnet.c 2014-02-09 17:32:49 -08:00
dn_dev.h dn_dev: add support for IFA_FLAGS nl attribute 2013-12-10 21:50:00 -05:00
dn_fib.h decnet (dn*.h): Remove extern from function prototypes 2013-09-20 14:49:32 -04:00
dn_neigh.h decnet (dn*.h): Remove extern from function prototypes 2013-09-20 14:49:32 -04:00
dn_nsp.h decnet (dn*.h): Remove extern from function prototypes 2013-09-20 14:49:32 -04:00
dn_route.h net: Move prototype declaration to appropriate header file from decnet/af_decnet.c 2014-02-09 17:32:49 -08:00
dsa.h
dsfield.h
dst.h xfrm: Generate queueing routes only from route lookup functions 2014-10-15 08:36:42 +02:00
dst_ops.h
esp.h net: move pskb_put() to core code 2013-11-07 19:28:58 -05:00
ethoc.h net: ethoc: set up MII management bus clock 2014-02-04 20:19:51 -08:00
fib_rules.h fib_rules.h: Remove extern from function prototypes 2013-09-20 14:49:33 -04:00
firewire.h
flow.h net: Remove FLOWI_FLAG_CAN_SLEEP 2013-12-06 07:24:39 +01:00
flow_keys.h flow_dissector: factor out the ports extraction in skb_flow_get_ports 2013-10-03 15:36:37 -04:00
garp.h garp.h: Remove extern from function prototypes 2013-09-20 14:49:33 -04:00
gen_stats.h gen_stats.h: Remove extern from function prototypes 2013-09-20 14:49:33 -04:00
genetlink.h genl: Add genlmsg_new_unicast() for unicast message allocation 2014-01-06 15:51:53 -08:00
gre.h gre_offload: statically build GRE offloading support 2014-01-06 20:28:34 -05:00
gro_cells.h
icmp.h icmp.h: Remove extern from function prototypes 2013-09-20 14:49:33 -04:00
ieee80211_radiotap.h mac80211: add radiotap flag and handling for 5/10 MHz 2013-07-16 09:58:05 +03:00
ieee802154.h
ieee802154_netdev.h
if_inet6.h ipv6: move DAD and addrconf_verify processing to workqueue 2014-03-28 16:54:50 -04:00
inet6_connection_sock.h inet*.h: Remove extern from function prototypes 2013-09-21 14:01:38 -04:00
inet6_hashtables.h ipv6: split inet6_ehashfn to hash functions per compilation unit 2013-10-19 19:45:34 -04:00
inet_common.h inet*.h: Remove extern from function prototypes 2013-09-21 14:01:38 -04:00
inet_connection_sock.h tcp: fix tcp_release_cb() to dispatch via address family for mtu_reduced() 2014-10-15 08:36:40 +02:00
inet_ecn.h
inet_frag.h inet: remove old fragmentation hash initializing 2013-10-23 17:01:41 -04:00
inet_hashtables.h tcp/dccp: remove twchain 2013-10-08 23:19:24 -04:00
inet_sock.h inet: convert inet_ehash_secret and ipv6_hash_secret to net_get_random_once 2013-10-19 19:45:35 -04:00
inet_timewait_sock.h ipv6: tcp: fix flowlabel value in ACK messages send from TIME_WAIT 2014-01-17 17:56:33 -08:00
inetpeer.h inetpeer: get rid of ip_id_count 2014-08-14 09:38:23 +08:00
ip.h ip: make IP identifiers less predictable 2014-08-14 09:38:23 +08:00
ip6_checksum.h net: fix build errors if ipv6 is disabled 2013-10-09 13:04:03 -04:00
ip6_fib.h ipv6: remove prune parameter for fib6_clean_all 2014-01-02 03:30:35 -05:00
ip6_route.h ipv6: Limit mtu to 65575 bytes 2014-05-31 13:20:33 -07:00
ip6_tunnel.h net: unify the pcpu_tstats and br_cpu_netstats as one 2014-01-04 20:10:24 -05:00
ip_fib.h ip*.h: Remove extern from function prototypes 2013-09-21 14:01:38 -04:00
ip_tunnels.h ip_tunnel(ipv4): fix tunnels with "local any remote $remote_ip" 2014-08-14 09:38:23 +08:00
ip_vs.h netfilter: push reasm skb through instead of original frag skbs 2013-11-11 00:19:35 -05:00
ipcomp.h
ipconfig.h
ipv6.h drivers/net, ipv6: Select IPv6 fragment idents for virtio UFO packets 2014-11-14 08:59:44 -08:00
ipx.h net: Move prototype declaration to header file include/net/ipx.h from net/ipx/af_ipx.c 2014-02-09 17:32:50 -08:00
iw_handler.h iw_handler.h: Remove extern from function prototypes 2013-09-21 14:01:39 -04:00
lapb.h lapb.h: Remove extern from function prototypes 2013-09-21 14:01:38 -04:00
lib80211.h
llc.h llc: make lock static 2014-01-03 20:56:48 -05:00
llc_c_ac.h llc*.h: Remove extern from function prototypes 2013-09-21 14:01:38 -04:00
llc_c_ev.h llc*.h: Remove extern from function prototypes 2013-09-21 14:01:38 -04:00
llc_c_st.h
llc_conn.h llc*.h: Remove extern from function prototypes 2013-09-21 14:01:38 -04:00
llc_if.h llc*.h: Remove extern from function prototypes 2013-09-21 14:01:38 -04:00
llc_pdu.h net: llc: fix order of evaluation in llc_conn_ac_inc_vr_by_1 2014-01-01 22:22:43 -05:00
llc_s_ac.h llc*.h: Remove extern from function prototypes 2013-09-21 14:01:38 -04:00
llc_s_ev.h llc*.h: Remove extern from function prototypes 2013-09-21 14:01:38 -04:00
llc_s_st.h
llc_sap.h llc*.h: Remove extern from function prototypes 2013-09-21 14:01:38 -04:00
mac80211.h mac80211: handle MMPDUs at EOSP correctly 2014-01-10 09:50:02 +01:00
mac802154.h mac802154: correct a typo in ieee802154_alloc_device() prototype 2013-10-21 18:56:23 -04:00
mip6.h include/net/: Fix FSF address in file headers 2013-12-06 12:37:56 -05:00
mld.h net: ipv6: mld: get rid of MLDV2_MRC and simplify calculation 2013-09-04 14:53:20 -04:00
mrp.h Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2013-10-01 17:06:14 -04:00
ndisc.h ndisc.h: Remove extern from function prototypes 2013-09-21 14:01:39 -04:00
neighbour.h neigh: use NEIGH_VAR_INIT in ndo_neigh_setup functions. 2014-01-16 11:31:58 -08:00
net_namespace.h net: Move prototype declaration to header file include/net/net_namespace.h from net/ipx/af_ipx.c 2014-02-09 17:32:50 -08:00
net_ratelimit.h
netdma.h
netevent.h netevent/netlink.h: Remove extern from function prototypes 2013-09-21 14:01:39 -04:00
netlabel.h Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2014-01-25 11:17:34 -08:00
netlink.h netevent/netlink.h: Remove extern from function prototypes 2013-09-21 14:01:39 -04:00
netprio_cgroup.h net: netprio: rename config to be more consistent with cgroup configs 2014-01-03 23:41:42 +01:00
netrom.h netrom.h: Remove extern from function prototypes 2013-09-21 14:01:39 -04:00
nexthop.h
nl802154.h
p8022.h p8022.h: Remove extern from function prototypes 2013-09-21 14:01:39 -04:00
ping.h ipv6: make IPV6_RECVPKTINFO work for ipv4 datagrams 2014-01-19 19:53:18 -08:00
pkt_cls.h net_sched: optimize tcf_match_indev() 2014-01-13 11:50:15 -08:00
pkt_sched.h pkt_sched: give visibility to mq slave qdiscs 2013-12-09 19:54:47 -05:00
protocol.h net: Add GRO support for UDP encapsulating protocols 2014-01-21 18:05:04 -08:00
psnap.h psnap.h: Remove extern from function prototypes 2013-09-23 01:51:08 -04:00
raw.h raw/rawv6.h: Remove extern from function prototypes 2013-09-23 01:51:08 -04:00
rawv6.h raw/rawv6.h: Remove extern from function prototypes 2013-09-23 01:51:08 -04:00
red.h reciprocal_divide: update/correction of the algorithm 2014-01-21 23:17:20 -08:00
regulatory.h regulatory: add NUL to alpha2 2014-10-05 14:52:20 -07:00
request_sock.h inet: includes a sock_common in request_sock 2013-10-10 00:08:07 -04:00
rose.h rose.h: Remove extern from function prototypes 2013-09-23 01:51:08 -04:00
route.h ipv4: introduce ip_dst_mtu_maybe_forward and protect forwarding path against pmtu spoofing 2014-01-13 11:22:54 -08:00
rtnetlink.h rtnetlink: provide api for getting and setting slave info 2014-01-22 21:57:05 -08:00
sch_generic.h net_sched: add struct net pointer to tcf_proto_ops->dump 2014-01-13 11:50:14 -08:00
scm.h scm.h: Remove extern from function prototypes 2013-09-23 01:51:09 -04:00
secure_seq.h inetpeer: get rid of ip_id_count 2014-08-14 09:38:23 +08:00
slhc_vj.h
snmp.h
sock.h tcp: fix tcp_release_cb() to dispatch via address family for mtu_reduced() 2014-10-15 08:36:40 +02:00
stp.h stp.h: Remove extern from function prototypes 2013-09-23 01:51:09 -04:00
tcp.h tcp: fix tcp_release_cb() to dispatch via address family for mtu_reduced() 2014-10-15 08:36:40 +02:00
tcp_memcontrol.h tcp_memcontrol: Kill struct tcp_memcontrol 2013-10-21 18:43:02 -04:00
tcp_states.h
timewait_sock.h
transp_v6.h ipv6: make IPV6_RECVPKTINFO work for ipv4 datagrams 2014-01-19 19:53:18 -08:00
udp.h udp: Remove unnecessary semicolon from do{}while (0) macro 2013-11-07 02:14:33 -05:00
udplite.h udplite.h: Remove extern from function prototypes 2013-09-23 16:29:40 -04:00
vsock_addr.h VSOCK: Move af_vsock.h and vsock_addr.h to include/net 2013-07-27 22:14:06 -07:00
vxlan.h net: Add GRO support for vxlan traffic 2014-01-21 18:05:04 -08:00
wext.h wext.h: Remove extern from function prototypes 2013-09-23 16:29:40 -04:00
wimax.h wimax.h: Remove extern from function prototypes 2013-09-23 16:29:41 -04:00
wpan-phy.h
x25.h x25.h: Remove extern from function prototypes 2013-09-23 16:29:41 -04:00
x25device.h
xfrm.h xfrm: Clone states properly on migration 2014-02-20 14:30:10 +01:00