Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp9403828pxu; Mon, 28 Dec 2020 15:21:45 -0800 (PST) X-Google-Smtp-Source: ABdhPJzJ9O1qTTveVsKaY7JZJl/NwmltgvE8AyCQ8ZmuraHV2Jjiz+q91RUC2jpdqG0aobxe1MJn X-Received: by 2002:a05:6402:1383:: with SMTP id b3mr43238573edv.100.1609197704867; Mon, 28 Dec 2020 15:21:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609197704; cv=none; d=google.com; s=arc-20160816; b=RensZyUAuemCUZ77ZVXPcssw2srf0muqpxmyiUYjnYicgLt21QPQZ9lAhhEk21gImX cnzcb8jYFAOmDMnvLTYTW70i5b9S8kKafQ6YcXSlJI4SP1bIfhfxQFh1M2NmaSbp/iaS jNyNMSM/LPiylodD/G7d2OAA7elH80/ZoHvf7O8OcBKye4j3YW7RU+3m5uBlpj0cdIPP Tu9aWtmP3lrPsBGEFXwBIzKBaKTrzXrwtlTssd3uw242/mKukvlRVFAGxRIGCw+6OvqP ATvV7xq+GfLreArrevoYGBy7H70TOvim/cHLaIZkvyxNhHbJ0f2sgKaLz2i8usY5O/fX rQ2Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Yp4vAfYjo20DmrBA+GDvCJbR+GQ0vvahQT6PUt0oPvI=; b=xU/lp18G99x3EIlB31OpvDYdzeP+JY1WjX0blHEqqWVm0oAV/ZHxZe0xV8hNJ2Er0+ uBj2JsxNED3yfL3VAckza6HH/MJKUiUgw9QHYll0CW9hqMSBRYYZXQO+kZRFbottyPdE A0g40frusJkk9mpwbMaA0Sjy+8f6rysnEIBk6jRF7rs3hLo7PGRW/AgQdFcE40oc+YNL fYhTRdRZKTuQqlAMkoM5cLnoYwixzjoamtag7KF4BMsAqDCnpwMm2y4g60Ti+rmKPVe7 07njil/hpAT0eIhiN0clTy2H2xCIhBrdF/Gx7FFQLHt8kactx9FK3mDFtiCl5yVQdwjg AplA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="L/e5b1+0"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id de20si20332568edb.171.2020.12.28.15.21.22; Mon, 28 Dec 2020 15:21:44 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="L/e5b1+0"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2501881AbgL1OVj (ORCPT + 99 others); Mon, 28 Dec 2020 09:21:39 -0500 Received: from mail.kernel.org ([198.145.29.99]:56598 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2502291AbgL1OVI (ORCPT ); Mon, 28 Dec 2020 09:21:08 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 32EE7206E5; Mon, 28 Dec 2020 14:20:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1609165227; bh=vRFUL+1pz6to4bIUX6Fz9GCHt3FzbSN5eqBIwWBQnzk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L/e5b1+0sKNBplH1WXiSujfpo+31Eh3miyTw6vG14PTRLvPM/ZBO36VUIqf4w81gW gIP4BJpVr1Oqkh47rS3nHCHW9zTUlFycHp8rTvIjyPQVFsyXZ5YLDYNy5tCVf247CW 6cpEu0ec0aRzX5hO3rG5O2UBD2/DNZTLu1gV81F0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Alexey Dobriyan , "Rantala, Tommi T. (Nokia - FI/Espoo)" , Al Viro , Andrew Morton , Linus Torvalds , Sasha Levin Subject: [PATCH 5.10 458/717] proc: fix lookup in /proc/net subdirectories after setns(2) Date: Mon, 28 Dec 2020 13:47:36 +0100 Message-Id: <20201228125042.911923213@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201228125020.963311703@linuxfoundation.org> References: <20201228125020.963311703@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alexey Dobriyan [ Upstream commit c6c75deda81344c3a95d1d1f606d5cee109e5d54 ] Commit 1fde6f21d90f ("proc: fix /proc/net/* after setns(2)") only forced revalidation of regular files under /proc/net/ However, /proc/net/ is unusual in the sense of /proc/net/foo handlers take netns pointer from parent directory which is old netns. Steps to reproduce: (void)open("/proc/net/sctp/snmp", O_RDONLY); unshare(CLONE_NEWNET); int fd = open("/proc/net/sctp/snmp", O_RDONLY); read(fd, &c, 1); Read will read wrong data from original netns. Patch forces lookup on every directory under /proc/net . Link: https://lkml.kernel.org/r/20201205160916.GA109739@localhost.localdomain Fixes: 1da4d377f943 ("proc: revalidate misc dentries") Signed-off-by: Alexey Dobriyan Reported-by: "Rantala, Tommi T. (Nokia - FI/Espoo)" Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- fs/proc/generic.c | 24 ++++++++++++++++++++++-- fs/proc/internal.h | 7 +++++++ fs/proc/proc_net.c | 16 ---------------- include/linux/proc_fs.h | 8 +++++++- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/fs/proc/generic.c b/fs/proc/generic.c index b84663252adda..6c0a05f55d6b1 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -349,6 +349,16 @@ static const struct file_operations proc_dir_operations = { .iterate_shared = proc_readdir, }; +static int proc_net_d_revalidate(struct dentry *dentry, unsigned int flags) +{ + return 0; +} + +const struct dentry_operations proc_net_dentry_ops = { + .d_revalidate = proc_net_d_revalidate, + .d_delete = always_delete_dentry, +}; + /* * proc directories can do almost nothing.. */ @@ -471,8 +481,8 @@ struct proc_dir_entry *proc_symlink(const char *name, } EXPORT_SYMBOL(proc_symlink); -struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode, - struct proc_dir_entry *parent, void *data) +struct proc_dir_entry *_proc_mkdir(const char *name, umode_t mode, + struct proc_dir_entry *parent, void *data, bool force_lookup) { struct proc_dir_entry *ent; @@ -484,10 +494,20 @@ struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode, ent->data = data; ent->proc_dir_ops = &proc_dir_operations; ent->proc_iops = &proc_dir_inode_operations; + if (force_lookup) { + pde_force_lookup(ent); + } ent = proc_register(parent, ent); } return ent; } +EXPORT_SYMBOL_GPL(_proc_mkdir); + +struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode, + struct proc_dir_entry *parent, void *data) +{ + return _proc_mkdir(name, mode, parent, data, false); +} EXPORT_SYMBOL_GPL(proc_mkdir_data); struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 917cc85e34663..afbe96b6bf77d 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -310,3 +310,10 @@ extern unsigned long task_statm(struct mm_struct *, unsigned long *, unsigned long *, unsigned long *, unsigned long *); extern void task_mem(struct seq_file *, struct mm_struct *); + +extern const struct dentry_operations proc_net_dentry_ops; +static inline void pde_force_lookup(struct proc_dir_entry *pde) +{ + /* /proc/net/ entries can be changed under us by setns(CLONE_NEWNET) */ + pde->proc_dops = &proc_net_dentry_ops; +} diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index ed8a6306990c4..1aa9236bf1af5 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -39,22 +39,6 @@ static struct net *get_proc_net(const struct inode *inode) return maybe_get_net(PDE_NET(PDE(inode))); } -static int proc_net_d_revalidate(struct dentry *dentry, unsigned int flags) -{ - return 0; -} - -static const struct dentry_operations proc_net_dentry_ops = { - .d_revalidate = proc_net_d_revalidate, - .d_delete = always_delete_dentry, -}; - -static void pde_force_lookup(struct proc_dir_entry *pde) -{ - /* /proc/net/ entries can be changed under us by setns(CLONE_NEWNET) */ - pde->proc_dops = &proc_net_dentry_ops; -} - static int seq_open_net(struct inode *inode, struct file *file) { unsigned int state_size = PDE(inode)->state_size; diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 270cab43ca3da..000cc0533c336 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -80,6 +80,7 @@ extern void proc_flush_pid(struct pid *); extern struct proc_dir_entry *proc_symlink(const char *, struct proc_dir_entry *, const char *); +struct proc_dir_entry *_proc_mkdir(const char *, umode_t, struct proc_dir_entry *, void *, bool); extern struct proc_dir_entry *proc_mkdir(const char *, struct proc_dir_entry *); extern struct proc_dir_entry *proc_mkdir_data(const char *, umode_t, struct proc_dir_entry *, void *); @@ -162,6 +163,11 @@ static inline struct proc_dir_entry *proc_symlink(const char *name, static inline struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent) {return NULL;} static inline struct proc_dir_entry *proc_create_mount_point(const char *name) { return NULL; } +static inline struct proc_dir_entry *_proc_mkdir(const char *name, umode_t mode, + struct proc_dir_entry *parent, void *data, bool force_lookup) +{ + return NULL; +} static inline struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode, struct proc_dir_entry *parent, void *data) { return NULL; } static inline struct proc_dir_entry *proc_mkdir_mode(const char *name, @@ -199,7 +205,7 @@ struct net; static inline struct proc_dir_entry *proc_net_mkdir( struct net *net, const char *name, struct proc_dir_entry *parent) { - return proc_mkdir_data(name, 0, parent, net); + return _proc_mkdir(name, 0, parent, net, true); } struct ns_common; -- 2.27.0