Patch "pptp: fix illegal memory access caused by multiple bind()s" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
pptp: fix illegal memory access caused by multiple bind()s
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
pptp-fix-illegal-memory-access-caused-by-multiple-bind-s.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Mon Feb 29 14:33:50 PST 2016
From: Hannes Frederic Sowa <[email protected]>
Date: Fri, 22 Jan 2016 01:39:43 +0100
Subject: pptp: fix illegal memory access caused by multiple bind()s
From: Hannes Frederic Sowa <[email protected]>
[ Upstream commit 9a368aff9cb370298fa02feeffa861f2db497c18 ]
Several times already this has been reported as kasan reports caused by syzkaller and trinity and people always looked at RCU races, but it is much more simple. :)
In case we bind a pptp socket multiple times, we simply add it to the callid_sock list but don't remove the old binding. Thus the old socket stays in the bucket with unused call_id indexes and doesn't get cleaned up. This causes various forms of kasan reports which were hard to pinpoint.
Simply don't allow multiple binds and correct error handling in pptp_bind. Also keep sk_state bits in place in pptp_connect.
--- drivers/net/ppp/pptp.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-)
drivers/net/ppp/pptp.c +24 -10
@@ -129,24 +129,27 @@ static int lookup_chan_dst(u16 call_id,return i <MAX_CALLID ; } -static int add_chan (struct pppox_sock *sock) +static int add_chan (struct pppox_sock *sock, +struct pptp_addr *sa) {static int call_id;spin_lock (&chan_lock); -if (!sock->proto.pptp.src_addr.call_id) { +if (!sa->call_id) { call_id =find_next_zero_bit (callid_bitmap,MAX_CALLID , call_id +1 );if (call_id ==MAX_CALLID ) { call_id =find_next_zero_bit (callid_bitmap,MAX_CALLID ,1 );if (call_id ==MAX_CALLID ) goto out_err; } - sock->proto.pptp.src_addr.call_id = call_id; - }else if (test_bit (sock->proto.pptp.src_addr.call_id, callid_bitmap)) + sa->call_id = call_id; + }else if (test_bit (sa->call_id, callid_bitmap)) { goto out_err; + } -set_bit (sock->proto.pptp.src_addr.call_id, callid_bitmap); -rcu_assign_pointer (callid_sock[sock->proto.pptp.src_addr.call_id], sock); + sock->proto.pptp.src_addr = *sa; +set_bit (sa->call_id, callid_bitmap); +rcu_assign_pointer (callid_sock[sa->call_id], sock);spin_unlock (&chan_lock);return 0 ;
@@ -416,7 +419,6 @@ static int pptp_bind(struct socket *sockstruct sock *sk = sock->sk;struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;struct pppox_sock *po =pppox_sk (sk); -struct pptp_opt *opt = &po->proto.pptp;int error =0 ;if (sockaddr_len <sizeof (struct sockaddr_pppox ))
@@ -424,10 +426,22 @@ static int pptp_bind(struct socket *socklock_sock (sk); - opt->src_addr = sp->sa_addr.pptp; -if (add_chan (po)) +if (sk->sk_state &PPPOX_DEAD ) { + error = -EALREADY ; + goto out; + } + +if (sk->sk_state &PPPOX_BOUND ) { error = -EBUSY ; + goto out; + } + +if (add_chan (po, &sp->sa_addr.pptp)) + error = -EBUSY ; +else + sk->sk_state |=PPPOX_BOUND ; +out:release_sock (sk);return error; }
@@ -498,7 +512,7 @@ static int pptp_connect(struct socket *s } opt->dst_addr = sp->sa_addr.pptp; - sk->sk_state =PPPOX_CONNECTED ; + sk->sk_state |=PPPOX_CONNECTED ; end:release_sock (sk);
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/ipv6-udp-use-sticky-pktinfo-egress-ifindex-on-connect.patch queue-4.4/pptp-fix-illegal-memory-access-caused-by-multiple-bind-s.patch queue-4.4/ipv6-fix-a-lockdep-splat.patch queue-4.4/ipv6-addrconf-fix-recursive-spin-lock-call.patch queue-4.4/unix-correctly-track-in-flight-fds-in-sending-process-user_struct.patch queue-4.4/ipv6-enforce-flowi6_oif-usage-in-ip6_dst_lookup_tail.patch queue-4.4/route-check-and-remove-route-cache-when-we-get-route.patch