Received: by 2002:ac0:946b:0:0:0:0:0 with SMTP id j40csp913187imj; Fri, 15 Feb 2019 08:51:49 -0800 (PST) X-Google-Smtp-Source: AHgI3IYmG6vtodo84fFflu335REvjShst4h8KES9niJN/J3bv3NHjYXTQmgjj8ifr0gIgRTvIff2 X-Received: by 2002:a62:a1a:: with SMTP id s26mr10757548pfi.31.1550249509858; Fri, 15 Feb 2019 08:51:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550249509; cv=none; d=google.com; s=arc-20160816; b=dhayJUn8QZD182nQZahOVPxlWdnGj2pl/S1yRPvkRQ5j61CTjXzzI54JqjlxWzgj3s v9eESxkalWb2+P3Nznmq7xKzntsg7NFB+N05FBsiOg0szIB+naVpqPNzzb9YQWyV6udM tSXeoh4sBOcho/ptv7UPBI7GVvmkJ3EIfxVi073krb0TxrZfA1VYw0XDe8JsWPngxNHC gU76Vx7qJQt1fPeTYQoRN4Ol0hgPh/YVt8ThtBxqgIdjXoYmEkjHJoPDzxKQ1N/Shafo Q3SXVQNYKqwCjOuPZAVeqgEMHuapy/Q4FODNrSStzzDzuGWDhAfDIuDm4A8Rzi2d8Wdd DIAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject:organization; bh=P8TRJo/PE3ev5h7IIAZjUDe7/KcFJUgXEjowGTi5aRM=; b=crCcvtzw9U6Q8ziybDcC0aKhMbNYpjHhopMm41wdyFFndT5VLbKZDI7aJtuJRE6RCN 4fzCjbRm0kUUr8JlvOpHAODnq4vQra9BP/Hnj8t4daOBxeZfG82fKh7jaceLmZ8RXT1W Fwe5rKecWfDmerTXuWun6PTLH47KL8mBMhZBk69i9uuKKRJGfY3Q2wQV3N2Nss1dIKis gI44pF7oyphFRlc5EPI1gpku1hyZITmAJv3GAuzb7ddMbLYrzliCaQrE5NiD7w15G6eC tv2iPLJgy8gouSnrb3lsLQboXU1wtNsH/XTfGwl0mrYZNc63DwMf1/6bpmDCfjg2VZRy yRJA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p9si6045684pgc.448.2019.02.15.08.51.33; Fri, 15 Feb 2019 08:51:49 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404090AbfBOQJC (ORCPT + 99 others); Fri, 15 Feb 2019 11:09:02 -0500 Received: from mx1.redhat.com ([209.132.183.28]:44798 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729453AbfBOQJB (ORCPT ); Fri, 15 Feb 2019 11:09:01 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3ACCC4FCDB; Fri, 15 Feb 2019 16:09:00 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-129.rdu2.redhat.com [10.10.121.129]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3E992600C7; Fri, 15 Feb 2019 16:08:58 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [RFC PATCH 10/27] containers: Provide fs_context op for container setting From: David Howells To: keyrings@vger.kernel.org, trond.myklebust@hammerspace.com, sfrench@samba.org Cc: linux-security-module@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-fsdevel@vger.kernel.org, rgb@redhat.com, dhowells@redhat.com, linux-kernel@vger.kernel.org Date: Fri, 15 Feb 2019 16:08:57 +0000 Message-ID: <155024693750.21651.5133054585005541648.stgit@warthog.procyon.org.uk> In-Reply-To: <155024683432.21651.14153938339749694146.stgit@warthog.procyon.org.uk> References: <155024683432.21651.14153938339749694146.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 15 Feb 2019 16:09:00 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Provide an fs_context op to notify a filesystem that a container has been set. The filesystem should do whatever cleanup it needs, then call do_set_container() and then re-set its container/namespace dependent stuff. This allows the following: (1) proc and mqueue mounts to set the correct pid and ipc namespaces respectively. (2) afs to discard the old default cell before the net namespace is changed (ie. while it is still pinned), after which it can get the new default cell. Signed-off-by: David Howells --- fs/afs/super.c | 18 ++++++++++++++++++ fs/fs_context.c | 32 ++++++++++++++++++++++++++------ fs/proc/root.c | 9 +++++++++ include/linux/fs_context.h | 2 ++ ipc/mqueue.c | 10 ++++++++++ 5 files changed, 65 insertions(+), 6 deletions(-) diff --git a/fs/afs/super.c b/fs/afs/super.c index 4e33a7038bc5..a349e213bdc8 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -569,6 +569,23 @@ static int afs_get_tree(struct fs_context *fc) return ret; } +static void afs_set_container(struct fs_context *fc) +{ + struct afs_fs_context *ctx = fc->fs_private; + struct afs_cell *cell; + + afs_put_cell(ctx->net, ctx->cell); + do_set_container(fc); + + /* Default to the workstation cell. */ + rcu_read_lock(); + cell = afs_lookup_cell_rcu(ctx->net, NULL, 0); + rcu_read_unlock(); + if (IS_ERR(cell)) + cell = NULL; + ctx->cell = cell; +} + static void afs_free_fc(struct fs_context *fc) { struct afs_fs_context *ctx = fc->fs_private; @@ -583,6 +600,7 @@ static void afs_free_fc(struct fs_context *fc) static const struct fs_context_operations afs_context_ops = { .free = afs_free_fc, .parse_param = afs_parse_param, + .set_container = afs_set_container, .get_tree = afs_get_tree, }; diff --git a/fs/fs_context.c b/fs/fs_context.c index fc76ac02d618..c0f333cc0e16 100644 --- a/fs/fs_context.c +++ b/fs/fs_context.c @@ -170,18 +170,38 @@ int vfs_parse_fs_param(struct fs_context *fc, struct fs_parameter *param) } EXPORT_SYMBOL(vfs_parse_fs_param); +/** + * do_set_container - Helper to set container + * @fc: The fs_context to adjust + * + * This is called to effect the change of namespaces associated with the + * container. The reason that this isn't rolled into vfs_set_container() is + * that the filesystem may need to do some cleanup on the old namespaces (which + * are currently pinned by the container) before calling this. + * + * The user namespace is not changed as that is used for security checks. + */ +void do_set_container(struct fs_context *fc) +{ + put_net(fc->net_ns); + fc->net_ns = get_net(fc->container->ns->net_ns); +} +EXPORT_SYMBOL(do_set_container); + /* - * Specify a container in which a superblock will exist. + * Specify a container in which a superblock will exist. This should be called + * before calling vfs_parse_fs_param. If ->set_container() is supplied by the + * filesystem, it should call do_set_container(). */ void vfs_set_container(struct fs_context *fc, struct container *container) { if (container) { - put_user_ns(fc->user_ns); - put_net(fc->net_ns); - + put_container(fc->container); fc->container = get_container(container); - fc->user_ns = get_user_ns(container->cred->user_ns); - fc->net_ns = get_net(container->ns->net_ns); + if (fc->ops->set_container) + fc->ops->set_container(fc); + else + do_set_container(fc); } } diff --git a/fs/proc/root.c b/fs/proc/root.c index aa802006d855..f8e124ce0888 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -164,6 +164,14 @@ static int proc_get_tree(struct fs_context *fc) return vfs_get_super(fc, vfs_get_keyed_super, proc_fill_super); } +static void proc_set_container(struct fs_context *fc) +{ + struct proc_fs_context *ctx = fc->fs_private; + + put_pid_ns(ctx->pid_ns); + ctx->pid_ns = get_pid_ns(fc->container->pid_ns); +} + static void proc_fs_context_free(struct fs_context *fc) { struct proc_fs_context *ctx = fc->fs_private; @@ -176,6 +184,7 @@ static void proc_fs_context_free(struct fs_context *fc) static const struct fs_context_operations proc_fs_context_ops = { .free = proc_fs_context_free, .parse_param = proc_parse_param, + .set_container = proc_set_container, .get_tree = proc_get_tree, .reconfigure = proc_reconfigure, }; diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h index 45486080eb84..086e4f24705a 100644 --- a/include/linux/fs_context.h +++ b/include/linux/fs_context.h @@ -118,6 +118,7 @@ struct fs_context_operations { int (*dup)(struct fs_context *fc, struct fs_context *src_fc); int (*parse_param)(struct fs_context *fc, struct fs_parameter *param); int (*parse_monolithic)(struct fs_context *fc, void *data); + void (*set_container)(struct fs_context *fc); int (*get_tree)(struct fs_context *fc); int (*reconfigure)(struct fs_context *fc); }; @@ -138,6 +139,7 @@ extern int vfs_parse_fs_param(struct fs_context *fc, struct fs_parameter *param) extern int vfs_parse_fs_string(struct fs_context *fc, const char *key, const char *value, size_t v_size); extern int generic_parse_monolithic(struct fs_context *fc, void *data); +extern void do_set_container(struct fs_context *fc); extern void vfs_set_container(struct fs_context *fc, struct container *container); extern int vfs_get_tree(struct fs_context *fc); extern void put_fs_context(struct fs_context *fc); diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 2a9a8be49f5b..821fb227800f 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -329,6 +330,14 @@ static struct inode *mqueue_get_inode(struct super_block *sb, return ERR_PTR(ret); } +static void mqueue_set_container(struct fs_context *fc) +{ + struct mqueue_fs_context *ctx = fc->fs_private; + + put_ipc_ns(ctx->ipc_ns); + ctx->ipc_ns = get_ipc_ns(fc->container->ns->ipc_ns); +} + static int mqueue_fill_super(struct super_block *sb, struct fs_context *fc) { struct inode *inode; @@ -1569,6 +1578,7 @@ static const struct super_operations mqueue_super_ops = { static const struct fs_context_operations mqueue_fs_context_ops = { .free = mqueue_fs_context_free, + .set_container = mqueue_set_container, .get_tree = mqueue_get_tree, };