Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750890AbcDOPvc (ORCPT ); Fri, 15 Apr 2016 11:51:32 -0400 Received: from out01.mta.xmission.com ([166.70.13.231]:51756 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751738AbcDOPuL (ORCPT ); Fri, 15 Apr 2016 11:50:11 -0400 From: "Eric W. Biederman" To: Linus Torvalds Cc: "H. Peter Anvin" , Andy Lutomirski , security@debian.org, security@kernel.org, Al Viro , security@ubuntu.com, Peter Hurley , Serge Hallyn , Willy Tarreau , Aurelien Jarno , One Thousand Gnomes , Jann Horn , Greg KH , Linux Kernel Mailing List , Jiri Slaby , Florian Weimer , "Eric W. Biederman" Date: Fri, 15 Apr 2016 10:35:31 -0500 Message-Id: <1460734532-20134-15-git-send-email-ebiederm@xmission.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1460734532-20134-1-git-send-email-ebiederm@xmission.com> References: <877ffyzy1j.fsf_-_@x220.int.ebiederm.org> <1460734532-20134-1-git-send-email-ebiederm@xmission.com> X-XM-AID: U2FsdGVkX19B1Sr08bBMtF2RR0/dDxPGc+MIEJ1LVZQ= X-SA-Exim-Connect-IP: 67.3.249.252 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-Report: * -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP * 1.5 XMNoVowels Alpha-numberic number with no vowels * 0.7 XMSubLong Long Subject * 0.0 TVD_RCVD_IP Message was received from an IP address * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.5000] * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa05 1397; Body=1 Fuz1=1 Fuz2=29] X-Spam-DCC: XMission; sa05 1397; Body=1 Fuz1=1 Fuz2=29 X-Spam-Combo: **;Linus Torvalds X-Spam-Relay-Country: X-Spam-Timing: total 322 ms - load_scoreonly_sql: 0.06 (0.0%), signal_user_changed: 4.8 (1.5%), b_tie_ro: 3.3 (1.0%), parse: 1.33 (0.4%), extract_message_metadata: 14 (4.2%), get_uri_detail_list: 2.8 (0.9%), tests_pri_-1000: 6 (1.8%), tests_pri_-950: 1.10 (0.3%), tests_pri_-900: 0.94 (0.3%), tests_pri_-400: 26 (8.0%), check_bayes: 24 (7.5%), b_tokenize: 7 (2.2%), b_tok_get_all: 8 (2.4%), b_comp_prob: 2.8 (0.9%), b_tok_touch_all: 3.5 (1.1%), b_finish: 0.98 (0.3%), tests_pri_0: 258 (80.4%), check_dkim_signature: 0.47 (0.1%), check_dkim_adsp: 4.2 (1.3%), tests_pri_500: 6 (1.9%), rewrite_mail: 0.00 (0.0%) Subject: [PATCH 15/16] devpts: Always return a distinct instance when mounting X-Spam-Flag: No X-SA-Exim-Version: 4.2.1 (built Wed, 24 Sep 2014 11:00:52 -0600) X-SA-Exim-Scanned: Yes (on in01.mta.xmission.com) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2584 Lines: 82 When devpts is mounted and the newinstance flag is not passed the code first checks to see if the system devpts instance has been exported to userspace. If it has not the system devpts instance is returned otherwise a fresh instance of devpts is allocated and returned. If newinstance is passed a fresh devpts instance is always returned. Combined with the earlier work to cause mounts of devpts to fail if devpts is mounted over itself, this ensures that the system devpts is mounted on /dev/pts on all of the systems I have tested. This has been verified to work properly on openwrt-15.05, centos5, centos6, centos7, debian-6.0.2, debian-7.9, debian-8.2, ubuntu-14.04.3, ubuntu-15.10, fedora23, magia-5, mint-17.3, opensuse-42.1, slackware-14.1, gentoo-20151225 (13.0?), archlinux-2015-12-01 Signed-off-by: "Eric W. Biederman" --- fs/devpts/inode.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index c1c346190f35..e5e533fe824a 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -430,13 +430,6 @@ fail: } #ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES -static int compare_init_pts_sb(struct super_block *s, void *p) -{ - if (devpts_mnt) - return devpts_mnt->mnt_sb == s; - return 0; -} - /* * devpts_mount() * @@ -467,28 +460,26 @@ static int compare_init_pts_sb(struct super_block *s, void *p) static struct dentry *devpts_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { - struct super_block *s; + struct dentry *root; bool newinstance; newinstance = parse_newinstance(data); + if (flags & MS_KERNMOUNT) + newinstance = true; - /* Require newinstance for all user namespace mounts to ensure + /* Force newinstance for all user namespace mounts to ensure * the mount options are not changed. */ - if ((current_user_ns() != &init_user_ns) && !newinstance) - return ERR_PTR(-EINVAL); - - if (newinstance) - return mount_nodev(fs_type, flags, data, devpts_fill_super); - - s = sget(fs_type, compare_init_pts_sb, set_anon_super, flags, NULL); - if (IS_ERR(s)) - return ERR_CAST(s); + if (current_user_ns() != &init_user_ns) + newinstance = true; - /* Match mount_single ignore errors on remount */ - devpts_remount(s, &flags, data); + root = NULL; + if (!newinstance) + root = mount_super_once(devpts_mnt->mnt_sb, flags, data); + if (IS_ERR_OR_NULL(root)) + root = mount_nodev(fs_type, flags, data, devpts_fill_super); - return dget(s->s_root); + return root; } #else -- 2.8.1