]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Jun 2022 10:49:12 +0000 (12:49 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Jun 2022 10:49:12 +0000 (12:49 +0200)
added patches:
l2tp-don-t-use-inet_shutdown-on-ppp-session-destroy.patch
l2tp-fix-race-in-pppol2tp_release-with-session-object-destroy.patch

queue-4.9/l2tp-don-t-use-inet_shutdown-on-ppp-session-destroy.patch [new file with mode: 0644]
queue-4.9/l2tp-fix-race-in-pppol2tp_release-with-session-object-destroy.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/l2tp-don-t-use-inet_shutdown-on-ppp-session-destroy.patch b/queue-4.9/l2tp-don-t-use-inet_shutdown-on-ppp-session-destroy.patch
new file mode 100644 (file)
index 0000000..078b06d
--- /dev/null
@@ -0,0 +1,118 @@
+From 225eb26489d05c679a4c4197ffcb81c81e9dcaf4 Mon Sep 17 00:00:00 2001
+From: James Chapman <jchapman@katalix.com>
+Date: Fri, 23 Feb 2018 17:45:44 +0000
+Subject: l2tp: don't use inet_shutdown on ppp session destroy
+
+From: James Chapman <jchapman@katalix.com>
+
+commit 225eb26489d05c679a4c4197ffcb81c81e9dcaf4 upstream.
+
+Previously, if a ppp session was closed, we called inet_shutdown to mark
+the socket as unconnected such that userspace would get errors and
+then close the socket. This could race with userspace closing the
+socket. Instead, leave userspace to close the socket in its own time
+(our session will be detached anyway).
+
+BUG: KASAN: use-after-free in inet_shutdown+0x5d/0x1c0
+Read of size 4 at addr ffff880010ea3ac0 by task syzbot_347bd5ac/8296
+
+CPU: 3 PID: 8296 Comm: syzbot_347bd5ac Not tainted 4.16.0-rc1+ #91
+Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
+Call Trace:
+ dump_stack+0x101/0x157
+ ? inet_shutdown+0x5d/0x1c0
+ print_address_description+0x78/0x260
+ ? inet_shutdown+0x5d/0x1c0
+ kasan_report+0x240/0x360
+ __asan_load4+0x78/0x80
+ inet_shutdown+0x5d/0x1c0
+ ? pppol2tp_show+0x80/0x80
+ pppol2tp_session_close+0x68/0xb0
+ l2tp_tunnel_closeall+0x199/0x210
+ ? udp_v6_flush_pending_frames+0x90/0x90
+ l2tp_udp_encap_destroy+0x6b/0xc0
+ ? l2tp_tunnel_del_work+0x2e0/0x2e0
+ udpv6_destroy_sock+0x8c/0x90
+ sk_common_release+0x47/0x190
+ udp_lib_close+0x15/0x20
+ inet_release+0x85/0xd0
+ inet6_release+0x43/0x60
+ sock_release+0x53/0x100
+ ? sock_alloc_file+0x260/0x260
+ sock_close+0x1b/0x20
+ __fput+0x19f/0x380
+ ____fput+0x1a/0x20
+ task_work_run+0xd2/0x110
+ exit_to_usermode_loop+0x18d/0x190
+ do_syscall_64+0x389/0x3b0
+ entry_SYSCALL_64_after_hwframe+0x26/0x9b
+RIP: 0033:0x7fe240a45259
+RSP: 002b:00007fe241132df8 EFLAGS: 00000297 ORIG_RAX: 0000000000000003
+RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00007fe240a45259
+RDX: 00007fe240a45259 RSI: 0000000000000000 RDI: 00000000000000a5
+RBP: 00007fe241132e20 R08: 00007fe241133700 R09: 0000000000000000
+R10: 00007fe241133700 R11: 0000000000000297 R12: 0000000000000000
+R13: 00007ffc49aff84f R14: 0000000000000000 R15: 00007fe241141040
+
+Allocated by task 8331:
+ save_stack+0x43/0xd0
+ kasan_kmalloc+0xad/0xe0
+ kasan_slab_alloc+0x12/0x20
+ kmem_cache_alloc+0x144/0x3e0
+ sock_alloc_inode+0x22/0x130
+ alloc_inode+0x3d/0xf0
+ new_inode_pseudo+0x1c/0x90
+ sock_alloc+0x30/0x110
+ __sock_create+0xaa/0x4c0
+ SyS_socket+0xbe/0x130
+ do_syscall_64+0x128/0x3b0
+ entry_SYSCALL_64_after_hwframe+0x26/0x9b
+
+Freed by task 8314:
+ save_stack+0x43/0xd0
+ __kasan_slab_free+0x11a/0x170
+ kasan_slab_free+0xe/0x10
+ kmem_cache_free+0x88/0x2b0
+ sock_destroy_inode+0x49/0x50
+ destroy_inode+0x77/0xb0
+ evict+0x285/0x340
+ iput+0x429/0x530
+ dentry_unlink_inode+0x28c/0x2c0
+ __dentry_kill+0x1e3/0x2f0
+ dput.part.21+0x500/0x560
+ dput+0x24/0x30
+ __fput+0x2aa/0x380
+ ____fput+0x1a/0x20
+ task_work_run+0xd2/0x110
+ exit_to_usermode_loop+0x18d/0x190
+ do_syscall_64+0x389/0x3b0
+ entry_SYSCALL_64_after_hwframe+0x26/0x9b
+
+Fixes: fd558d186df2c ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts")
+Signed-off-by: James Chapman <jchapman@katalix.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/l2tp/l2tp_ppp.c |   10 ----------
+ 1 file changed, 10 deletions(-)
+
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -439,16 +439,6 @@ abort:
+  */
+ static void pppol2tp_session_close(struct l2tp_session *session)
+ {
+-      struct sock *sk;
+-
+-      BUG_ON(session->magic != L2TP_SESSION_MAGIC);
+-
+-      sk = pppol2tp_session_get_sock(session);
+-      if (sk) {
+-              if (sk->sk_socket)
+-                      inet_shutdown(sk->sk_socket, SEND_SHUTDOWN);
+-              sock_put(sk);
+-      }
+ }
+ /* Really kill the session socket. (Called from sock_put() if
diff --git a/queue-4.9/l2tp-fix-race-in-pppol2tp_release-with-session-object-destroy.patch b/queue-4.9/l2tp-fix-race-in-pppol2tp_release-with-session-object-destroy.patch
new file mode 100644 (file)
index 0000000..a1650cc
--- /dev/null
@@ -0,0 +1,172 @@
+From d02ba2a6110c530a32926af8ad441111774d2893 Mon Sep 17 00:00:00 2001
+From: James Chapman <jchapman@katalix.com>
+Date: Fri, 23 Feb 2018 17:45:46 +0000
+Subject: l2tp: fix race in pppol2tp_release with session object destroy
+
+From: James Chapman <jchapman@katalix.com>
+
+commit d02ba2a6110c530a32926af8ad441111774d2893 upstream.
+
+pppol2tp_release uses call_rcu to put the final ref on its socket. But
+the session object doesn't hold a ref on the session socket so may be
+freed while the pppol2tp_put_sk RCU callback is scheduled. Fix this by
+having the session hold a ref on its socket until the session is
+destroyed. It is this ref that is dropped via call_rcu.
+
+Sessions are also deleted via l2tp_tunnel_closeall. This must now also put
+the final ref via call_rcu. So move the call_rcu call site into
+pppol2tp_session_close so that this happens in both destroy paths. A
+common destroy path should really be implemented, perhaps with
+l2tp_tunnel_closeall calling l2tp_session_delete like pppol2tp_release
+does, but this will be looked at later.
+
+ODEBUG: activate active (active state 1) object type: rcu_head hint:           (null)
+WARNING: CPU: 3 PID: 13407 at lib/debugobjects.c:291 debug_print_object+0x166/0x220
+Modules linked in:
+CPU: 3 PID: 13407 Comm: syzbot_19c09769 Not tainted 4.16.0-rc2+ #38
+Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
+RIP: 0010:debug_print_object+0x166/0x220
+RSP: 0018:ffff880013647a00 EFLAGS: 00010082
+RAX: dffffc0000000008 RBX: 0000000000000003 RCX: ffffffff814d3333
+RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff88001a59f6d0
+RBP: ffff880013647a40 R08: 0000000000000000 R09: 0000000000000001
+R10: ffff8800136479a8 R11: 0000000000000000 R12: 0000000000000001
+R13: ffffffff86161420 R14: ffffffff85648b60 R15: 0000000000000000
+FS:  0000000000000000(0000) GS:ffff88001a580000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000020e77000 CR3: 0000000006022000 CR4: 00000000000006e0
+Call Trace:
+ debug_object_activate+0x38b/0x530
+ ? debug_object_assert_init+0x3b0/0x3b0
+ ? __mutex_unlock_slowpath+0x85/0x8b0
+ ? pppol2tp_session_destruct+0x110/0x110
+ __call_rcu.constprop.66+0x39/0x890
+ ? __call_rcu.constprop.66+0x39/0x890
+ call_rcu_sched+0x17/0x20
+ pppol2tp_release+0x2c7/0x440
+ ? fcntl_setlk+0xca0/0xca0
+ ? sock_alloc_file+0x340/0x340
+ sock_release+0x92/0x1e0
+ sock_close+0x1b/0x20
+ __fput+0x296/0x6e0
+ ____fput+0x1a/0x20
+ task_work_run+0x127/0x1a0
+ do_exit+0x7f9/0x2ce0
+ ? SYSC_connect+0x212/0x310
+ ? mm_update_next_owner+0x690/0x690
+ ? up_read+0x1f/0x40
+ ? __do_page_fault+0x3c8/0xca0
+ do_group_exit+0x10d/0x330
+ ? do_group_exit+0x330/0x330
+ SyS_exit_group+0x22/0x30
+ do_syscall_64+0x1e0/0x730
+ ? trace_hardirqs_off_thunk+0x1a/0x1c
+ entry_SYSCALL_64_after_hwframe+0x42/0xb7
+RIP: 0033:0x7f362e471259
+RSP: 002b:00007ffe389abe08 EFLAGS: 00000202 ORIG_RAX: 00000000000000e7
+RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f362e471259
+RDX: 00007f362e471259 RSI: 000000000000002e RDI: 0000000000000000
+RBP: 00007ffe389abe30 R08: 0000000000000000 R09: 00007f362e944270
+R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000400b60
+R13: 00007ffe389abf50 R14: 0000000000000000 R15: 0000000000000000
+Code: 8d 3c dd a0 8f 64 85 48 89 fa 48 c1 ea 03 80 3c 02 00 75 7b 48 8b 14 dd a0 8f 64 85 4c 89 f6 48 c7 c7 20 85 64 85 e
+8 2a 55 14 ff <0f> 0b 83 05 ad 2a 68 04 01 48 83 c4 18 5b 41 5c 41 5d 41 5e 41
+
+Fixes: ee40fb2e1eb5b ("l2tp: protect sock pointer of struct pppol2tp_session with RCU")
+Signed-off-by: James Chapman <jchapman@katalix.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/l2tp/l2tp_ppp.c |   52 +++++++++++++++++++++++++++-------------------------
+ 1 file changed, 27 insertions(+), 25 deletions(-)
+
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -435,10 +435,28 @@ abort:
+  * Session (and tunnel control) socket create/destroy.
+  *****************************************************************************/
++static void pppol2tp_put_sk(struct rcu_head *head)
++{
++      struct pppol2tp_session *ps;
++
++      ps = container_of(head, typeof(*ps), rcu);
++      sock_put(ps->__sk);
++}
++
+ /* Called by l2tp_core when a session socket is being closed.
+  */
+ static void pppol2tp_session_close(struct l2tp_session *session)
+ {
++      struct pppol2tp_session *ps;
++
++      ps = l2tp_session_priv(session);
++      mutex_lock(&ps->sk_lock);
++      ps->__sk = rcu_dereference_protected(ps->sk,
++                                           lockdep_is_held(&ps->sk_lock));
++      RCU_INIT_POINTER(ps->sk, NULL);
++      if (ps->__sk)
++              call_rcu(&ps->rcu, pppol2tp_put_sk);
++      mutex_unlock(&ps->sk_lock);
+ }
+ /* Really kill the session socket. (Called from sock_put() if
+@@ -458,14 +476,6 @@ static void pppol2tp_session_destruct(st
+       }
+ }
+-static void pppol2tp_put_sk(struct rcu_head *head)
+-{
+-      struct pppol2tp_session *ps;
+-
+-      ps = container_of(head, typeof(*ps), rcu);
+-      sock_put(ps->__sk);
+-}
+-
+ /* Called when the PPPoX socket (session) is closed.
+  */
+ static int pppol2tp_release(struct socket *sock)
+@@ -489,26 +499,17 @@ static int pppol2tp_release(struct socke
+       sock_orphan(sk);
+       sock->sk = NULL;
++      /* If the socket is associated with a session,
++       * l2tp_session_delete will call pppol2tp_session_close which
++       * will drop the session's ref on the socket.
++       */
+       session = pppol2tp_sock_to_session(sk);
+-
+-      if (session != NULL) {
+-              struct pppol2tp_session *ps;
+-
++      if (session) {
+               l2tp_session_delete(session);
+-
+-              ps = l2tp_session_priv(session);
+-              mutex_lock(&ps->sk_lock);
+-              ps->__sk = rcu_dereference_protected(ps->sk,
+-                                                   lockdep_is_held(&ps->sk_lock));
+-              RCU_INIT_POINTER(ps->sk, NULL);
+-              mutex_unlock(&ps->sk_lock);
+-              call_rcu(&ps->rcu, pppol2tp_put_sk);
+-
+-              /* Rely on the sock_put() call at the end of the function for
+-               * dropping the reference held by pppol2tp_sock_to_session().
+-               * The last reference will be dropped by pppol2tp_put_sk().
+-               */
++              /* drop the ref obtained by pppol2tp_sock_to_session */
++              sock_put(sk);
+       }
++
+       release_sock(sk);
+       /* This will delete the session context via
+@@ -817,6 +818,7 @@ static int pppol2tp_connect(struct socke
+ out_no_ppp:
+       /* This is how we get the session context from the socket. */
++      sock_hold(sk);
+       sk->sk_user_data = session;
+       rcu_assign_pointer(ps->sk, sk);
+       mutex_unlock(&ps->sk_lock);
index c9e8370e2052ed059def5fe6700ea3bb6d3f43ff..8215c5972d86ef2fcc1d593460ea4c07ec2fbf59 100644 (file)
@@ -248,3 +248,5 @@ dm-mirror-log-round-up-region-bitmap-size-to-bits_per_long.patch
 ext4-fix-bug_on-ext4_mb_use_inode_pa.patch
 ext4-make-variable-count-signed.patch
 ext4-add-reserved-gdt-blocks-check.patch
+l2tp-don-t-use-inet_shutdown-on-ppp-session-destroy.patch
+l2tp-fix-race-in-pppol2tp_release-with-session-object-destroy.patch