From patchwork Sat May 16 02:06:56 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: 6418711 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 57FD09F318 for ; Sat, 16 May 2015 02:11:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 72A1E20573 for ; Sat, 16 May 2015 02:11:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 62A8320570 for ; Sat, 16 May 2015 02:11:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2992584AbbEPCLr (ORCPT ); Fri, 15 May 2015 22:11:47 -0400 Received: from out03.mta.xmission.com ([166.70.13.233]:51223 "EHLO out03.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2992574AbbEPCLq (ORCPT ); Fri, 15 May 2015 22:11:46 -0400 Received: from in02.mta.xmission.com ([166.70.13.52]) by out03.mta.xmission.com with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.82) (envelope-from ) id 1YtRZp-0000CW-Pv; Fri, 15 May 2015 20:11:45 -0600 Received: from 67-3-205-90.omah.qwest.net ([67.3.205.90] helo=x220.int.ebiederm.org.xmission.com) by in02.mta.xmission.com with esmtpsa (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.82) (envelope-from ) id 1YtRZo-00026Q-Uu; Fri, 15 May 2015 20:11:45 -0600 From: ebiederm@xmission.com (Eric W. Biederman) To: Linux Containers Cc: , Linux API , "Serge E. Hallyn" , Andy Lutomirski , Richard Weinberger , Kenton Varda , Michael Kerrisk , =?utf-8?Q?St=C3=A9phane?= Graber , Eric Windisch , Greg Kroah-Hartman , Tejun Heo References: <87pp63jcca.fsf@x220.int.ebiederm.org> <87siaxuvik.fsf@x220.int.ebiederm.org> Date: Fri, 15 May 2015 21:06:56 -0500 In-Reply-To: <87siaxuvik.fsf@x220.int.ebiederm.org> (Eric W. Biederman's message of "Fri, 15 May 2015 21:05:39 -0500") Message-ID: <87h9rduvgf.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+fA0wbCCEyEsIa0Yy/czMNF6IIqvM5Wbk= 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=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-DCC: XMission; sa07 1397; Body=2 Fuz1=2 Fuz2=2 X-Spam-Combo: ***;Linux Containers X-Spam-Relay-Country: X-Spam-Timing: total 334 ms - load_scoreonly_sql: 0.18 (0.1%), signal_user_changed: 6 (1.7%), b_tie_ro: 3.8 (1.1%), parse: 1.77 (0.5%), extract_message_metadata: 15 (4.5%), get_uri_detail_list: 2.3 (0.7%), tests_pri_-1000: 7 (2.0%), tests_pri_-950: 1.43 (0.4%), tests_pri_-900: 1.18 (0.4%), tests_pri_-400: 25 (7.5%), check_bayes: 24 (7.1%), b_tokenize: 8 (2.4%), b_tok_get_all: 8 (2.3%), b_comp_prob: 2.6 (0.8%), b_tok_touch_all: 3.2 (0.9%), b_finish: 0.84 (0.3%), tests_pri_0: 266 (79.7%), tests_pri_500: 6 (1.9%), rewrite_mail: 0.00 (0.0%) Subject: [CFT][PATCH 02/10] mnt: Modify fs_fully_visible to deal with mount attributes X-SA-Exim-Version: 4.2.1 (built Wed, 24 Sep 2014 11:00:52 -0600) X-SA-Exim-Scanned: Yes (on in02.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 Ignore an existing mount if it's locked attributes are less permissive than the new mounts attributes. On success ensure the new mount locks all of the same attributes as the old mount. Cc: stable@vger.kernel.org Signed-off-by: "Eric W. Biederman" --- fs/namespace.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 8e7edaf60fe1..fccee9924e8c 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2332,7 +2332,7 @@ unlock: return err; } -static bool fs_fully_visible(struct file_system_type *fs_type); +static bool fs_fully_visible(struct file_system_type *fs_type, int *new_mnt_flags); /* * create a new mount for userspace and request it to be added into the @@ -2366,7 +2366,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags, mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV; } if (type->fs_flags & FS_USERNS_VISIBLE) { - if (!fs_fully_visible(type)) + if (!fs_fully_visible(type, &mnt_flags)) return -EPERM; } } @@ -3170,9 +3170,10 @@ bool current_chrooted(void) return chrooted; } -static bool fs_fully_visible(struct file_system_type *type) +static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags) { struct mnt_namespace *ns = current->nsproxy->mnt_ns; + int new_flags = *new_mnt_flags; struct mount *mnt; bool visible = false; @@ -3191,6 +3192,25 @@ static bool fs_fully_visible(struct file_system_type *type) if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root) continue; + /* Verify the mount flags are equal to or more permissive + * than the proposed new mount. + */ + if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) && + !(new_flags & MNT_READONLY)) + continue; + if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) && + !(new_flags & MNT_NODEV)) + continue; + if ((mnt->mnt.mnt_flags & MNT_LOCK_NOSUID) && + !(new_flags & MNT_NOSUID)) + continue; + if ((mnt->mnt.mnt_flags & MNT_LOCK_NOEXEC) && + !(new_flags & MNT_NOEXEC)) + continue; + if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) && + ((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK))) + continue; + /* This mount is not fully visible if there are any child mounts * that cover anything except for empty directories. */ @@ -3201,6 +3221,12 @@ static bool fs_fully_visible(struct file_system_type *type) if (inode->i_nlink > 2) goto next; } + /* Preserve the locked attributes */ + *new_mnt_flags |= mnt->mnt.mnt_flags & (MNT_LOCK_READONLY | \ + MNT_LOCK_NODEV | \ + MNT_LOCK_NOSUID | \ + MNT_LOCK_NOEXEC | \ + MNT_LOCK_ATIME); visible = true; goto found; next: ;