Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756025AbdGKRM0 (ORCPT ); Tue, 11 Jul 2017 13:12:26 -0400 Received: from h2.hallyn.com ([78.46.35.8]:45270 "EHLO h2.hallyn.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755911AbdGKRMZ (ORCPT ); Tue, 11 Jul 2017 13:12:25 -0400 Date: Tue, 11 Jul 2017 12:12:22 -0500 From: "Serge E. Hallyn" To: Stefan Berger Cc: ebiederm@xmission.com, containers@lists.linux-foundation.org, lkp@01.org, linux-kernel@vger.kernel.org, zohar@linux.vnet.ibm.com, tycho@docker.com, serge@hallyn.com, James.Bottomley@HansenPartnership.com, vgoyal@redhat.com, christian.brauner@mailbox.org, amir73il@gmail.com, linux-security-module@vger.kernel.org, casey@schaufler-ca.com, Stefan Berger Subject: Re: [PATCH v2] xattr: Enable security.capability in user namespaces Message-ID: <20170711171222.GB31603@mail.hallyn.com> References: <1499785511-17192-1-git-send-email-stefanb@linux.vnet.ibm.com> <1499785511-17192-2-git-send-email-stefanb@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1499785511-17192-2-git-send-email-stefanb@linux.vnet.ibm.com> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4956 Lines: 150 Quoting Stefan Berger (Stefan Bergerstefanb@linux.vnet.ibm.com): > er.kernel.org> > X-Mailing-List: linux-kernel@vger.kernel.org > Content-Length: 19839 > Lines: 700 > X-UID: 24770 > Status: RO > > From: Stefan Berger > > This patch enables security.capability in user namespaces but also > takes a more general approach to enabling extended attributes in user > namespaces. > > The following rules describe the approach using security.foo as a > 'user namespace enabled' extended attribute: > > Reading of extended attributes: > > 1a) Reading security.foo from a user namespace will read > security.foo@uid= of the parent user namespace instead with uid > being the mapping of root in that parent user namespace. An > exception is if root is mapped to uid 0 on the host, and in this case > we will read security.foo directly. > --> reading security.foo will read security.foo@uid=1000 for uid > mapping of root to 1000. > > 1b) If security.foo@uid= is not available, the security.foo of the > parent namespace is tried to be read. This procedure is repeated up to > the init user namespace. This step only applies for reading of extended > attributes and provides the same behavior as older system where the > host's extended attributes applied to user namespaces. > > 2) All security.foo@uid= with valid uid mapping in the user namespace > can be read. The uid within the user namespace will be mapped to the > corresponding uid on the host and that uid will be used in the name of > the extended attribute. > -> reading security.foo@uid=1 will read security.foo@uid=1001 for uid > mapping of root to 1000, size of at least 2. > > All security.foo@uid= can be read (by root) on the host with values > of also being subject to checking for valid mappings. > > 3) No other security.foo* can be read. > > The same rules for reading apply to writing and removing of user > namespace enabled extended attributes. > > When listing extended attributes of a file, only those are presented > to the user namespace that have a valid mapping. Besides that, names > of the extended attributes are adjusted to represent the mapping. > This means that if root is mapped to uid 1000 on the host, the > security.foo@uid=1000 will be listed as security.foo in the user > namespace, security.foo@uid=1001 becomes security.foo@uid=1 and so on. > > Signed-off-by: Stefan Berger > Signed-off-by: Serge Hallyn > Reviewed-by: Serge Hallyn > --- > fs/xattr.c | 509 +++++++++++++++++++++++++++++++++++++++++++++-- > security/commoncap.c | 36 +++- > security/selinux/hooks.c | 9 +- > 3 files changed, 523 insertions(+), 31 deletions(-) > > diff --git a/fs/xattr.c b/fs/xattr.c > index 464c94b..eacad9e 100644 > --- a/fs/xattr.c > +++ b/fs/xattr.c > @@ -133,20 +133,440 @@ xattr_permission(struct inode *inode, const char *name, int mask) > return inode_permission(inode, mask); > } > > +/* > + * A list of extended attributes that are supported in user namespaces > + */ > +static const char *const userns_xattrs[] = { > + XATTR_NAME_CAPS, > + NULL > +}; > + > +/* > + * xattrs_is_userns_supported - Check whether an xattr is supported in userns > + * > + * @name: full name of the extended attribute > + * @prefix: do a prefix match (true) or a full match (false) > + * > + * This function returns < 0 if not supported, an index into userns_xattrs[] > + * otherwise. > + */ > +static int > +xattr_is_userns_supported(const char *name, int prefix) > +{ > + int i; > + > + if (!name) > + return -1; > + > + for (i = 0; userns_xattrs[i]; i++) { > + if (prefix) { > + if (!strncmp(userns_xattrs[i], name, > + strlen(userns_xattrs[i]))) > + return i; I think you here need to also check that the next char is either '\0' or '.' (or maybe '@') > + } else { > + if (!strcmp(userns_xattrs[i], name)) > + return i; > + } > + } > + return -1; > +} > + > +/* > + * xattr_write_uid - print a string in the format of "%s@uid=%u", which > + * includes a prefix string > + * > + * @uid: the uid > + * @prefix: prefix string; may be NULL > + * > + * This function returns a buffer with the string, or a NULL pointer in > + * case of out-of-memory error. > + */ > +static char * > +xattr_write_uid(uid_t uid, const char *prefix) > +{ > + size_t buflen; > + char *buffer; > + > + buflen = sizeof("@uid=") - 1 + sizeof("4294967295") - 1 + 1; > + if (prefix) > + buflen += strlen(prefix); > + > + buffer = kmalloc(buflen, GFP_KERNEL); > + if (!buffer) > + return NULL; > + > + if (uid == 0) > + *buffer = 0; Do you need to print out the prefix here? > + else > + sprintf(buffer, "%s@uid=%u", > + (prefix) ? prefix : "", > + uid); > + > + return buffer; > +}