Message ID | 5591049F.3040108@nokia.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Alexander Sverdlin <alexander.sverdlin@nokia.com> Date: Mon, 29 Jun 2015 10:41:03 +0200 > There is NULL pointer dereference possible during statistics update if the route > used for OOTB responce is removed at unfortunate time. If the route exists when > we receive OOTB packet and we finally jump into sctp_packet_transmit() to send > ABORT, but in the meantime route is removed under our feet, we take "no_route" > path and try to update stats with IP_INC_STATS(sock_net(asoc->base.sk), ...). > > But sctp_ootb_pkt_new() used to prepare responce packet doesn't call > sctp_transport_set_owner() and therefore there is no asoc associated with this > packet. Probably temporary asoc just for OOTB responces is overkill, so just > introduce a check like in all other places in sctp_packet_transmit(), where > "asoc" is dereferenced. > > To reproduce this, one needs to > 0. ensure that sctp module is loaded (otherwise ABORT is not generated) > 1. remove default route on the machine > 2. while true; do > ip route del [interface-specific route] > ip route add [interface-specific route] > done > 3. send enough OOTB packets (i.e. HB REQs) from another host to trigger ABORT > responce > > On x86_64 the crash looks like this: ... > Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com> > Acked-by: Neil Horman <nhorman@tuxdriver.com> > Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> > Acked-by: Vlad Yasevich <vyasevich@gmail.com> Applied and queued up for -stable, thanks. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/sctp/output.c b/net/sctp/output.c index fc5e45b..abe7c2d 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -599,7 +599,9 @@ out: return err; no_route: kfree_skb(nskb); - IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES); + + if (asoc) + IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES); /* FIXME: Returning the 'err' will effect all the associations * associated with a socket, although only one of the paths of the