Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752245AbcDOPq7 (ORCPT ); Fri, 15 Apr 2016 11:46:59 -0400 Received: from out03.mta.xmission.com ([166.70.13.233]:37357 "EHLO out03.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752171AbcDOPq5 (ORCPT ); Fri, 15 Apr 2016 11:46:57 -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:25 -0500 Message-Id: <1460734532-20134-9-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: U2FsdGVkX1+plj2cP/NMBV7Qxh8oNB2l8FErP4FbJiI= 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 * 0.0 TVD_RCVD_IP Message was received from an IP address * 1.5 XMNoVowels Alpha-numberic number with no vowels * 0.7 XMSubLong Long Subject * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.5000] * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa07 1397; Body=1 Fuz1=1 Fuz2=27] * 0.0 T_TooManySym_02 5+ unique symbols in subject * 0.0 T_TooManySym_01 4+ unique symbols in subject * 0.2 T_XMDrugObfuBody_14 obfuscated drug references X-Spam-DCC: XMission; sa07 1397; Body=1 Fuz1=1 Fuz2=27 X-Spam-Combo: **;Linus Torvalds X-Spam-Relay-Country: X-Spam-Timing: total 471 ms - load_scoreonly_sql: 0.04 (0.0%), signal_user_changed: 3.9 (0.8%), b_tie_ro: 2.8 (0.6%), parse: 1.01 (0.2%), extract_message_metadata: 15 (3.1%), get_uri_detail_list: 2.1 (0.4%), tests_pri_-1000: 7 (1.4%), tests_pri_-950: 1.32 (0.3%), tests_pri_-900: 1.12 (0.2%), tests_pri_-400: 26 (5.5%), check_bayes: 25 (5.2%), b_tokenize: 8 (1.7%), b_tok_get_all: 8 (1.7%), b_comp_prob: 2.3 (0.5%), b_tok_touch_all: 3.4 (0.7%), b_finish: 0.85 (0.2%), tests_pri_0: 406 (86.1%), check_dkim_signature: 0.84 (0.2%), check_dkim_adsp: 3.6 (0.8%), tests_pri_500: 5 (1.1%), rewrite_mail: 0.00 (0.0%) Subject: [PATCH 09/16] devpts: Fail early (if appropriate) on overmount 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: 3072 Lines: 92 Update the vfs with a may_overmount superblock operation, allowing devpts to fail early if the primary mount of devpts is going to be mounted on top of itself. This change is in preparation for each mount of devpts being distinct from every other mount of devpts. To maintain a backward compatible notion of a primary mount of devpts we need overmounts of the mount to fail (as they do now), which requires a little vfs support so the case can be detected. Cause failed over mounts of devpts to go through the devpts remount path. This already happens as overmounts have previously been detected late, and it looks like CentOS 6 may actually depend on this behavior to allow changing devpts mount options by placing them in /etc/fstab. Signed-off-by: "Eric W. Biederman" --- fs/devpts/inode.c | 15 +++++++++++++++ fs/namespace.c | 8 ++++++++ include/linux/fs.h | 1 + 3 files changed, 24 insertions(+) diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 1266abd3251e..051a2657be36 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -339,10 +339,25 @@ static int devpts_show_options(struct seq_file *seq, struct dentry *root) return 0; } +bool devpts_may_overmount(struct super_block *sb, + int flags, const char *dev_name, void *data) +{ + if ((sb == devpts_mnt->mnt_sb) && + (current_user_ns() == &init_user_ns) && + !parse_newinstance(data)) { + down_write(&sb->s_umount); + devpts_remount(sb, &flags, data); + up_write(&sb->s_umount); + return false; + } + return true; +} + static const struct super_operations devpts_sops = { .statfs = simple_statfs, .remount_fs = devpts_remount, .show_options = devpts_show_options, + .may_overmount = devpts_may_overmount, }; static void *new_pts_fs_info(void) diff --git a/fs/namespace.c b/fs/namespace.c index 278ecb7b8e8e..01ad3207c3a2 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2401,6 +2401,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags, { struct file_system_type *type; struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns; + struct super_block *path_sb; struct vfsmount *mnt; int err; @@ -2429,6 +2430,13 @@ static int do_new_mount(struct path *path, const char *fstype, int flags, } } + path_sb = path->mnt->mnt_sb; + if ((path_sb->s_type == type) && + (path->mnt->mnt_root == path->dentry) && + path_sb->s_op->may_overmount && + !path_sb->s_op->may_overmount(path_sb, flags, name, data)) + return -EBUSY; + mnt = vfs_kern_mount(type, flags, name, data); if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) && !mnt->mnt_sb->s_subtype) diff --git a/include/linux/fs.h b/include/linux/fs.h index 14a97194b34b..aade033bed49 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1755,6 +1755,7 @@ struct super_operations { struct shrink_control *); long (*free_cached_objects)(struct super_block *, struct shrink_control *); + bool (*may_overmount)(struct super_block *, int, const char *, void *); }; /* -- 2.8.1