From patchwork Fri Jul 10 16:18:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Eric W. Biederman" X-Patchwork-Id: 6766961 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CC7E0C05AC for ; Fri, 10 Jul 2015 16:24:00 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EB747205D8 for ; Fri, 10 Jul 2015 16:23:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EADB8205E4 for ; Fri, 10 Jul 2015 16:23:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932268AbbGJQX5 (ORCPT ); Fri, 10 Jul 2015 12:23:57 -0400 Received: from out02.mta.xmission.com ([166.70.13.232]:51834 "EHLO out02.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932205AbbGJQXz (ORCPT ); Fri, 10 Jul 2015 12:23:55 -0400 Received: from in01.mta.xmission.com ([166.70.13.51]) by out02.mta.xmission.com with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.82) (envelope-from ) id 1ZDb5f-00046U-1g; Fri, 10 Jul 2015 10:23:55 -0600 Received: from 67-3-205-90.omah.qwest.net ([67.3.205.90] helo=x220.int.ebiederm.org.xmission.com) by in01.mta.xmission.com with esmtpsa (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.82) (envelope-from ) id 1ZDb5d-0000DY-Ny; Fri, 10 Jul 2015 10:23:54 -0600 From: ebiederm@xmission.com (Eric W. Biederman) To: Linux Containers Cc: Linus Torvalds , , Linux API , Andy Lutomirski , "Serge E. Hallyn" , Richard Weinberger , Kenton Varda , Michael Kerrisk-manpages , =?utf-8?Q?St=C3=A9phane?= Graber , Eric Windisch , Greg Kroah-Hartman , Tejun Heo , Seth Forshee , Omar Sandoval , Ivan Delalande , Al Viro References: <87381eyz26.fsf@x220.int.ebiederm.org> <87pp4eqktr.fsf@x220.int.ebiederm.org> <20150704231118.GT17109@ZenIV.linux.org.uk> <87mvz4yomp.fsf_-_@x220.int.ebiederm.org> Date: Fri, 10 Jul 2015 11:18:17 -0500 In-Reply-To: <87mvz4yomp.fsf_-_@x220.int.ebiederm.org> (Eric W. Biederman's message of "Fri, 10 Jul 2015 11:16:14 -0500") Message-ID: <87bnfkyoja.fsf_-_@x220.int.ebiederm.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 X-XM-AID: U2FsdGVkX1/jKsmqLABfLAiRr/hI1shV395PnQW5P1c= X-SA-Exim-Connect-IP: 67.3.205.90 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-DCC: XMission; sa06 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: ***;Linux Containers X-Spam-Relay-Country: X-Spam-Timing: total 867 ms - load_scoreonly_sql: 0.07 (0.0%), signal_user_changed: 4.4 (0.5%), b_tie_ro: 3.0 (0.3%), parse: 1.55 (0.2%), extract_message_metadata: 14 (1.7%), get_uri_detail_list: 2.0 (0.2%), tests_pri_-1000: 7 (0.9%), tests_pri_-950: 1.50 (0.2%), tests_pri_-900: 1.18 (0.1%), tests_pri_-400: 26 (3.0%), check_bayes: 25 (2.9%), b_tokenize: 9 (1.0%), b_tok_get_all: 8 (0.9%), b_comp_prob: 2.1 (0.2%), b_tok_touch_all: 3.7 (0.4%), b_finish: 0.73 (0.1%), tests_pri_0: 798 (92.1%), tests_pri_500: 7 (0.8%), rewrite_mail: 0.00 (0.0%) Subject: [REVIEW][PATCH 2/2] mnt: fs_fully_visible enforce noexec and nosuid if !SB_I_NOEXEC 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-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The filesystems proc and sysfs do not have executable files do not have exectuable files today and portions of userspace break if we do enforce nosuid and noexec consistency of nosuid and noexec flags between previous mounts and new mounts of proc and sysfs. Add the code to enforce consistency of the nosuid and noexec flags, and use the presence of SB_I_NOEXEC to signal that there is no need to bother. This results in a completely userspace invisible change that makes it clear fs_fully_visible can only skip the enforcement of noexec and nosuid because it is known the filesystems in question do not support executables. Signed-off-by: "Eric W. Biederman" --- fs/namespace.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index c7cb8a526c05..ce428cadd41f 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3194,6 +3194,8 @@ static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags) down_read(&namespace_sem); list_for_each_entry(mnt, &ns->list, mnt_list) { struct mount *child; + int mnt_flags; + if (mnt->mnt.mnt_sb->s_type != type) continue; @@ -3203,17 +3205,30 @@ static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags) if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root) continue; + /* Read the mount flags and filter out flags that + * may safely be ignored. + */ + mnt_flags = mnt->mnt.mnt_flags; + if (mnt->mnt.mnt_sb->s_iflags & SB_I_NOEXEC) + mnt_flags &= ~(MNT_LOCK_NOSUID | MNT_LOCK_NOEXEC); + /* Verify the mount flags are equal to or more permissive * than the proposed new mount. */ - if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) && + if ((mnt_flags & MNT_LOCK_READONLY) && !(new_flags & MNT_READONLY)) continue; - if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) && + if ((mnt_flags & MNT_LOCK_NODEV) && !(new_flags & MNT_NODEV)) continue; - if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) && - ((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK))) + if ((mnt_flags & MNT_LOCK_NOSUID) && + !(new_flags & MNT_NOSUID)) + continue; + if ((mnt_flags & MNT_LOCK_NOEXEC) && + !(new_flags & MNT_NOEXEC)) + continue; + if ((mnt_flags & MNT_LOCK_ATIME) && + ((mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK))) continue; /* This mount is not fully visible if there are any @@ -3223,16 +3238,18 @@ static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags) list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) { struct inode *inode = child->mnt_mountpoint->d_inode; /* Only worry about locked mounts */ - if (!(mnt->mnt.mnt_flags & MNT_LOCKED)) + if (!(mnt_flags & MNT_LOCKED)) continue; /* Is the directory permanetly empty? */ if (!is_empty_dir_inode(inode)) goto next; } /* Preserve the locked attributes */ - *new_mnt_flags |= mnt->mnt.mnt_flags & (MNT_LOCK_READONLY | \ - MNT_LOCK_NODEV | \ - MNT_LOCK_ATIME); + *new_mnt_flags |= mnt_flags & (MNT_LOCK_READONLY | \ + MNT_LOCK_NODEV | \ + MNT_LOCK_NOSUID | \ + MNT_LOCK_NOEXEC | \ + MNT_LOCK_ATIME); visible = true; goto found; next: ;