Message ID | 20171207150700.12824-3-kleber.souza@canonical.com |
---|---|
State | New |
Headers | show |
Series | [SRU,Xenial,Zesty,Artful,1/1] sctp: do not peel off an assoc from one netns to another one | expand |
On 07/12/17 15:07, Kleber Sacilotto de Souza wrote: > From: Xin Long <lucien.xin@gmail.com> > > Now when peeling off an association to the sock in another netns, all > transports in this assoc are not to be rehashed and keep use the old > key in hashtable. > > As a transport uses sk->net as the hash key to insert into hashtable, > it would miss removing these transports from hashtable due to the new > netns when closing the sock and all transports are being freeed, then > later an use-after-free issue could be caused when looking up an asoc > and dereferencing those transports. > > This is a very old issue since very beginning, ChunYu found it with > syzkaller fuzz testing with this series: > > socket$inet6_sctp() > bind$inet6() > sendto$inet6() > unshare(0x40000000) > getsockopt$inet_sctp6_SCTP_GET_ASSOC_ID_LIST() > getsockopt$inet_sctp6_SCTP_SOCKOPT_PEELOFF() > > This patch is to block this call when peeling one assoc off from one > netns to another one, so that the netns of all transport would not > go out-sync with the key in hashtable. > > Note that this patch didn't fix it by rehashing transports, as it's > difficult to handle the situation when the tuple is already in use > in the new netns. Besides, no one would like to peel off one assoc > to another netns, considering ipaddrs, ifaces, etc. are usually > different. > > Reported-by: ChunYu Wang <chunwang@redhat.com> > Signed-off-by: Xin Long <lucien.xin@gmail.com> > Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> > Acked-by: Neil Horman <nhorman@tuxdriver.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > > CVE-2017-15115 > (cherry picked from commit df80cd9b28b9ebaa284a41df611dbf3a2d05ca74) > Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> > --- > net/sctp/socket.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/net/sctp/socket.c b/net/sctp/socket.c > index d4730ada7f32..17841ab30798 100644 > --- a/net/sctp/socket.c > +++ b/net/sctp/socket.c > @@ -4906,6 +4906,10 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) > struct socket *sock; > int err = 0; > > + /* Do not peel off from one netns to another one. */ > + if (!net_eq(current->nsproxy->net_ns, sock_net(sk))) > + return -EINVAL; > + > if (!asoc) > return -EINVAL; > > Clean cherry pick. Acked-by: Colin Ian King <colin.king@canonical.com>
Applied to xenial, zesty and artful master-next branches. Thanks. Cascardo. Applied-to: xenial/master-next Applied-to: zesty/master-next Applied-to: artful/master-next
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index d4730ada7f32..17841ab30798 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4906,6 +4906,10 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) struct socket *sock; int err = 0; + /* Do not peel off from one netns to another one. */ + if (!net_eq(current->nsproxy->net_ns, sock_net(sk))) + return -EINVAL; + if (!asoc) return -EINVAL;