From patchwork Tue Feb 25 17:31:13 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Serge E. Hallyn" X-Patchwork-Id: 324044 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 997D02C0142 for ; Wed, 26 Feb 2014 04:31:39 +1100 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1WILqv-0005Hz-Nh; Tue, 25 Feb 2014 17:31:33 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1WILqg-0005HF-Vv for kernel-team@lists.ubuntu.com; Tue, 25 Feb 2014 17:31:18 +0000 Received: from c-71-239-248-29.hsd1.il.comcast.net ([71.239.248.29] helo=sergelap) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1WILqg-0006Hz-1f; Tue, 25 Feb 2014 17:31:18 +0000 Date: Tue, 25 Feb 2014 11:31:13 -0600 From: Serge Hallyn To: linux-fsdevel@vger.kernel.org, kernel-team@lists.ubuntu.com, =?us-ascii?B?PT9pc28tODg1OS0xP1E/U3Q9RTlwaGFuZT89?= Graber , Andy Whitcroft , Miklos Szeredi Subject: [PATCH RFC] overlayfs,xattr: allow unprivileged users to whiteout Message-ID: <20140225173113.GA14257@sergelap> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com To mark a file which exists in the lower layer as deleted, it creates a symbolic link to a file called "(overlay-whiteout)" in the writeable mount, and sets a "trusted.overlay" xattr on that link. 1. When the create the symbolic link as container root, not as the global root 2. Allow root in a container to edit "trusted.overlay*" xattrs. Generally only global root is allowed to edit "trusted.*" With this patch, I'm able to delete files and directories in a user-namespace-based overlayfs-backed container. The overlay writeable layer after "rm ab/ab; rmdir ab; mv xxx yyy;" ends up looking like: ls -l .local/share/lxc/u11/delta0/home/ubuntu/ total 0 lrwxrwxrwx 1 150000 150000 18 Feb 13 22:30 ab -> (overlay-whiteout) lrwxrwxrwx 1 150000 150000 18 Feb 13 22:30 xxx -> (overlay-whiteout) -rw-rw-r-- 1 151000 151000 0 Feb 13 03:53 yyy (with 150000 being the mapped container root) Note - the fs/xattr.c hunk could presumably be dropped if we switched to using "user.overlay". This could however cause problems with pre-existing overlay deltas. I don't really care how this is done, but am wondering whether there is any good reason why making overlay whiteouts should require root on the host rather than only in the userns. Signed-off-by: Serge Hallyn --- fs/overlayfs/dir.c | 9 +++++++-- fs/xattr.c | 5 ++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index a209409..3c4657b 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "overlayfs.h" static const char *ovl_whiteout_symlink = "(overlay-whiteout)"; @@ -38,8 +39,12 @@ static int ovl_whiteout(struct dentry *upperdir, struct dentry *dentry) cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN); cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE); cap_raise(override_cred->cap_effective, CAP_FOWNER); - override_cred->fsuid = GLOBAL_ROOT_UID; - override_cred->fsgid = GLOBAL_ROOT_GID; + override_cred->fsuid = make_kuid(current_user_ns(), 0); + if (!uid_valid(override_cred->fsuid)) + override_cred->fsuid = GLOBAL_ROOT_UID; + override_cred->fsgid = make_kgid(current_user_ns(), 0); + if (!gid_valid(override_cred->fsgid)) + override_cred->fsgid = GLOBAL_ROOT_GID; old_cred = override_creds(override_cred); newdentry = lookup_one_len(dentry->d_name.name, upperdir, diff --git a/fs/xattr.c b/fs/xattr.c index 3377dff..edd826c 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -52,7 +52,10 @@ xattr_permission(struct inode *inode, const char *name, int mask) * The trusted.* namespace can only be accessed by privileged users. */ if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) { - if (!capable(CAP_SYS_ADMIN)) + if (strncmp(name, "trusted.overlay", 15) == 0) { + if (!inode_capable(inode, CAP_SYS_ADMIN)) + return (mask & MAY_WRITE) ? -EPERM : -ENODATA; + } else if (!capable(CAP_SYS_ADMIN)) return (mask & MAY_WRITE) ? -EPERM : -ENODATA; return 0; }