[RHEL8,COMMIT] venetdev: check ve_ns is not null before dereferencing

Submitted by Konstantin Khorenko on Dec. 22, 2020, 1:48 p.m.

Details

Message ID 202012221348.0BMDm3HX228506@finist-co8.sw.ru
State New
Series "venetdev: check ve_ns is not null before dereferencing"
Headers show

Commit Message

Konstantin Khorenko Dec. 22, 2020, 1:48 p.m.
The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.3
------>
commit 64b9ec9f3dd51c53b048508ea1936dec57b146e6
Author: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Date:   Tue Dec 22 16:48:03 2020 +0300

    venetdev: check ve_ns is not null before dereferencing
    
    When testing criu on vz8 I got crash in venet_newlink on dereferencing
    zero ve_ns:
    
      BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
      PGD 8000000136ceb067 P4D 8000000136ceb067 PUD 137624067 PMD 0
      Oops: 0000 [#1] SMP PTI
      CPU: 0 PID: 6853 Comm: criu ve: ad7d77df-8614-42b4-8bf4-c9313fcb2a17
      Kdump: loaded Not tainted 4.18.0-193.6.3.vz8.4.18 #1 4.18
      Hardware name: Virtuozzo KVM, BIOS 1.11.0-2.vz7.2 04/01/2014
      RIP: 0010:venet_newlink+0x18/0xc0 [vznetdev]
    
    Small reproducer:
    
      # term 1
      echo $$
      # 407283
    
      # term 2
      mkdir /sys/fs/cgroup/ve/my_new_ve
      echo 666 > /sys/fs/cgroup/ve/my_new_ve/ve.veid
      echo 407283 > /sys/fs/cgroup/ve/my_new_ve/tasks
    
      # term 1
      unshare -n
      ip link add venet0 type venet
    
    If we create venet in network namespace which is owned by ve which is
    not started yet - we crash.
    
    Note on vz7 we are safe as there is no ve_ns.
    
    https://jira.sw.ru/browse/PSBM-123077
    
    Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
 drivers/net/venetdev.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/drivers/net/venetdev.c b/drivers/net/venetdev.c
index b5b3f7e16c58..cdf56b9e7ec1 100644
--- a/drivers/net/venetdev.c
+++ b/drivers/net/venetdev.c
@@ -7,6 +7,7 @@ 
 
 #include <linux/proc_fs.h>
 #include <linux/inet.h>
+#include <linux/nsproxy.h>
 #include <net/ip.h>
 
 #include <linux/venet.h>
@@ -733,6 +734,7 @@  static int venet_newlink(struct net *src_net,
 			 struct netlink_ext_ack *extack)
 {
 	struct ve_struct *ve = src_net->owner_ve;
+	struct nsproxy *ve_ns;
 	struct net *net;
 	int err = 0;
 
@@ -741,7 +743,10 @@  static int venet_newlink(struct net *src_net,
 	 * also referenced on assignment => ve won't die =>
 	 * rcu_read_lock()/unlock not needed here.
 	 */
-	net = rcu_dereference_check(ve->ve_ns, 1)->net_ns;
+	ve_ns = rcu_dereference_check(ve->ve_ns, 1);
+	if (!ve_ns)
+		return -EBUSY;
+	net = ve_ns->net_ns;
 	if (!net)
 		return -EBUSY;