diff mbox

[trusty/vivid/wily/xenial] namei: permit linking with CAP_FOWNER in userns

Message ID 1446143827-77177-1-git-send-email-seth.forshee@canonical.com
State New
Headers show

Commit Message

Seth Forshee Oct. 29, 2015, 6:37 p.m. UTC
From: Dirk Steinmetz <public@rsjtdrjgfuzkfg.com>

Attempting to hardlink to an unsafe file (e.g. a setuid binary) from
within an unprivileged user namespace fails, even if CAP_FOWNER is held
within the namespace. This may cause various failures, such as a gentoo
installation within a lxc container failing to build and install specific
packages.

This change permits hardlinking of files owned by mapped uids, if
CAP_FOWNER is held for that namespace. Furthermore, it improves consistency
by using the existing inode_owner_or_capable(), which is aware of
namespaced capabilities as of 23adbe12ef7d3 ("fs,userns: Change
inode_capable to capable_wrt_inode_uidgid").

Signed-off-by: Dirk Steinmetz <public@rsjtdrjgfuzkfg.com>

This is hitting us in Ubuntu during some dpkg upgrades in containers.
When upgrading a file dpkg creates a hard link to the old file to back
it up before overwriting it. When packages upgrade suid files owned by a
non-root user the link isn't permitted, and the package upgrade fails.
This patch fixes our problem.

Tested-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
(cherry picked from commit f2ca379642d7a843be972ea4167abdd3c8c9e5d1
 git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git)
BugLink: http://bugs.launchpad.net/bugs/1498162
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
---
 fs/namei.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

Comments

Tim Gardner Oct. 29, 2015, 8:07 p.m. UTC | #1
Positive test results
Stefan Bader Nov. 4, 2015, 2:41 p.m. UTC | #2
cherry-pick and positive testing
Brad Figg Nov. 4, 2015, 3:17 p.m. UTC | #3
Applied to the master-next branches of Trusty, Vivid and Wily.
diff mbox

Patch

diff --git a/fs/namei.c b/fs/namei.c
index ada73fd..2b28696 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -955,26 +955,23 @@  static bool safe_hardlink_source(struct inode *inode)
  *  - sysctl_protected_hardlinks enabled
  *  - fsuid does not match inode
  *  - hardlink source is unsafe (see safe_hardlink_source() above)
- *  - not CAP_FOWNER
+ *  - not CAP_FOWNER in a namespace with the inode owner uid mapped
  *
  * Returns 0 if successful, -ve on error.
  */
 static int may_linkat(struct path *link)
 {
-	const struct cred *cred;
 	struct inode *inode;
 
 	if (!sysctl_protected_hardlinks)
 		return 0;
 
-	cred = current_cred();
 	inode = link->dentry->d_inode;
 
 	/* Source inode owner (or CAP_FOWNER) can hardlink all they like,
 	 * otherwise, it must be a safe source.
 	 */
-	if (uid_eq(cred->fsuid, inode->i_uid) || safe_hardlink_source(inode) ||
-	    capable(CAP_FOWNER))
+	if (inode_owner_or_capable(inode) || safe_hardlink_source(inode))
 		return 0;
 
 	audit_log_link_denied("linkat", link);