On Sat, Oct 10, 2015 at 7:59 AM, Dirk Steinmetz <public@xxxxxxxxxxxxxxxxxx> wrote: > 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@xxxxxxxxxxxxxxxxxx> Sorry for the delay: was travelling when I got put on CC. (FWIW, in the future, please check the scripts/get_maintainer.pl script with --git-blame to build CC lists, then I would have been CCed earlier.) I think Eric's already taken this patch, but it looks correct to me: Acked-by: Kees Cook <keescook@xxxxxxxxxxxx> I'll hop on the other thread to discuss the setgid issue. -Kees > --- > fs/namei.c | 7 ++----- > 1 file changed, 2 insertions(+), 5 deletions(-) > > diff --git a/fs/namei.c b/fs/namei.c > index 726d211..29fc6a6 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); > -- > 2.1.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ -- Kees Cook Chrome OS Security -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html