All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Seth Forshee (DigitalOcean)" <sforshee@kernel.org>
To: Christian Brauner <brauner@kernel.org>,
	Serge Hallyn <serge@hallyn.com>,
	 Paul Moore <paul@paul-moore.com>, Eric Paris <eparis@redhat.com>,
	 James Morris <jmorris@namei.org>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	 Miklos Szeredi <miklos@szeredi.hu>,
	Amir Goldstein <amir73il@gmail.com>
Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	 linux-security-module@vger.kernel.org, audit@vger.kernel.org,
	 linux-unionfs@vger.kernel.org,
	 "Seth Forshee (DigitalOcean)" <sforshee@kernel.org>
Subject: [PATCH 06/16] capability: provide a helper for converting vfs_caps to xattr for userspace
Date: Wed, 29 Nov 2023 15:50:24 -0600	[thread overview]
Message-ID: <20231129-idmap-fscap-refactor-v1-6-da5a26058a5b@kernel.org> (raw)
In-Reply-To: <20231129-idmap-fscap-refactor-v1-0-da5a26058a5b@kernel.org>

cap_inode_getsecurity() implements a handful of policies for capability
xattrs read by userspace:

 - It returns EINVAL if the on-disk capability is in v1 format.

 - It masks off all bits in magic_etc except for the version and
   VFS_CAP_FLAGS_EFFECTIVE.

 - v3 capabilities are converted to v2 format if the rootid returned to
   userspace would be 0 or if the rootid corresponds to root in an
   ancestor user namespace.

 - It returns EOVERFLOW for a v3 capability whose rootid does not map to
   a valid id in current_user_ns() or to root in an ancestor namespace.

These policies must be maintained when converting vfs_caps to an xattr
for userspace. Provide a vfs_caps_to_user_xattr() helper which will
enforce these policies.

Signed-off-by: Seth Forshee (DigitalOcean) <sforshee@kernel.org>
---
 include/linux/capability.h |  4 +++
 security/commoncap.c       | 68 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/include/linux/capability.h b/include/linux/capability.h
index cdd7d2d8855e..c0bd9447685b 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -218,6 +218,10 @@ int vfs_caps_to_xattr(struct mnt_idmap *idmap,
 		      struct user_namespace *dest_userns,
 		      const struct vfs_caps *vfs_caps,
 		      void *data, int size);
+int vfs_caps_to_user_xattr(struct mnt_idmap *idmap,
+			   struct user_namespace *dest_userns,
+			   const struct vfs_caps *vfs_caps,
+			   void *data, int size);
 
 /* audit system wants to get cap info from files as well */
 int get_vfs_caps_from_disk(struct mnt_idmap *idmap,
diff --git a/security/commoncap.c b/security/commoncap.c
index ef37966f3522..c645330f83a0 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -789,6 +789,74 @@ int vfs_caps_to_xattr(struct mnt_idmap *idmap,
 	return ret;
 }
 
+/**
+ * vfs_caps_to_user_xattr - convert vfs_caps to caps xattr for userspace
+ *
+ * @idmap:       idmap of the mount the inode was found from
+ * @dest_userns: user namespace for ids in xattr data
+ * @vfs_caps:    source vfs_caps data
+ * @data:        destination buffer for rax xattr caps data
+ * @size:        size of the @data buffer
+ *
+ * Converts a kernel-interrnal capability into the raw security.capability
+ * xattr format. Includes permission checking and v2->v3 conversion as
+ * appropriate.
+ *
+ * If the xattr is being read or written through an idmapped mount the
+ * idmap of the vfsmount must be passed through @idmap. This function
+ * will then take care to map the rootid according to @idmap.
+ *
+ * Return: On success, return 0; on error, return < 0.
+ */
+int vfs_caps_to_user_xattr(struct mnt_idmap *idmap,
+			   struct user_namespace *dest_userns,
+			   const struct vfs_caps *vfs_caps,
+			   void *data, int size)
+{
+	struct vfs_ns_cap_data *ns_caps = data;
+	bool is_v3;
+	u32 magic;
+
+	/* Preserve previous behavior of returning EINVAL for v1 caps */
+	if ((vfs_caps->magic_etc & VFS_CAP_REVISION_MASK) == VFS_CAP_REVISION_1)
+		return -EINVAL;
+
+	size = __vfs_caps_to_xattr(idmap, dest_userns, vfs_caps, data, size);
+	if (size < 0)
+		return size;
+
+	magic = vfs_caps->magic_etc &
+		(VFS_CAP_REVISION_MASK | VFS_CAP_FLAGS_EFFECTIVE);
+	ns_caps->magic_etc = cpu_to_le32(magic);
+
+	/*
+	 * If this is a v3 capability with a valid, non-zero rootid, return
+	 * the v3 capability to userspace. A v3 capability with a rootid of
+	 * 0 will be converted to a v2 capability below for compatibility
+	 * with old userspace.
+	 */
+	is_v3 = (vfs_caps->magic_etc & VFS_CAP_REVISION_MASK) == VFS_CAP_REVISION_3;
+	if (is_v3) {
+		uid_t rootid = le32_to_cpu(ns_caps->rootid);
+		if (rootid != (uid_t)-1 && rootid != (uid_t)0)
+			return size;
+	}
+
+	if (!rootid_owns_currentns(vfs_caps->rootid))
+		return -EOVERFLOW;
+
+	/* This comes from a parent namespace. Return as a v2 capability. */
+	if (is_v3) {
+		magic = VFS_CAP_REVISION_2 |
+			(vfs_caps->magic_etc & VFS_CAP_FLAGS_EFFECTIVE);
+		ns_caps->magic_etc = cpu_to_le32(magic);
+		ns_caps->rootid = cpu_to_le32(0);
+		size = XATTR_CAPS_SZ_2;
+	}
+
+	return size;
+}
+
 /**
  * get_vfs_caps_from_disk - retrieve vfs caps from disk
  *

-- 
2.43.0


  parent reply	other threads:[~2023-11-29 21:50 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-29 21:50 [PATCH 00/16] fs: use type-safe uid representation for filesystem capabilities Seth Forshee (DigitalOcean)
2023-11-29 21:50 ` [PATCH 01/16] mnt_idmapping: split out core vfs[ug]id_t definitions into vfsid.h Seth Forshee (DigitalOcean)
2023-11-29 21:50 ` [PATCH 02/16] mnt_idmapping: include cred.h Seth Forshee (DigitalOcean)
2023-11-29 21:50 ` [PATCH 03/16] capability: rename cpu_vfs_cap_data to vfs_caps Seth Forshee (DigitalOcean)
2023-12-01 15:50   ` Christian Brauner
2023-12-05 21:25   ` [PATCH 3/16] " Paul Moore
2023-11-29 21:50 ` [PATCH 04/16] capability: use vfsuid_t for vfs_caps rootids Seth Forshee (DigitalOcean)
2023-12-05 21:25   ` [PATCH 4/16] " Paul Moore
2023-11-29 21:50 ` [PATCH 05/16] capability: provide helpers for converting between xattrs and vfs_caps Seth Forshee (DigitalOcean)
2023-12-01 16:41   ` Christian Brauner
2023-12-01 17:09     ` Seth Forshee (DigitalOcean)
2023-11-29 21:50 ` Seth Forshee (DigitalOcean) [this message]
2023-12-01 16:57   ` [PATCH 06/16] capability: provide a helper for converting vfs_caps to xattr for userspace Christian Brauner
2023-12-01 17:23     ` Seth Forshee (DigitalOcean)
2023-11-29 21:50 ` [PATCH 07/16] fs: add inode operations to get/set/remove fscaps Seth Forshee (DigitalOcean)
2023-11-30  5:32   ` Amir Goldstein
2023-11-30 15:36     ` Seth Forshee (DigitalOcean)
2023-12-01 17:02   ` Christian Brauner
2023-12-01 17:38     ` Seth Forshee (DigitalOcean)
2023-12-05 11:50       ` Christian Brauner
2023-11-29 21:50 ` [PATCH 08/16] fs: add vfs_get_fscaps() Seth Forshee (DigitalOcean)
2023-12-01 17:09   ` Christian Brauner
2023-12-01 17:41     ` Seth Forshee (DigitalOcean)
2023-11-29 21:50 ` [PATCH 09/16] fs: add vfs_set_fscaps() Seth Forshee (DigitalOcean)
2023-11-30  8:01   ` Amir Goldstein
2023-11-30 15:38     ` Seth Forshee (DigitalOcean)
2023-12-01 17:39   ` Christian Brauner
2023-12-01 18:18     ` Seth Forshee (DigitalOcean)
2023-12-07 14:42       ` Seth Forshee (DigitalOcean)
2023-12-10 16:41         ` Amir Goldstein
2023-11-29 21:50 ` [PATCH 10/16] fs: add vfs_remove_fscaps() Seth Forshee (DigitalOcean)
2023-11-29 21:50 ` [PATCH 11/16] ovl: add fscaps handlers Seth Forshee (DigitalOcean)
2023-11-30  5:56   ` Amir Goldstein
2023-11-30 16:01     ` Seth Forshee (DigitalOcean)
2023-11-29 21:50 ` [PATCH 12/16] ovl: use vfs_{get,set}_fscaps() for copy-up Seth Forshee (DigitalOcean)
2023-11-30  6:23   ` Amir Goldstein
2023-11-30 16:43     ` Seth Forshee (DigitalOcean)
2023-11-29 21:50 ` [PATCH 13/16] fs: use vfs interfaces for capabilities xattrs Seth Forshee (DigitalOcean)
2023-11-29 21:50 ` [PATCH 14/16] commoncap: remove cap_inode_getsecurity() Seth Forshee (DigitalOcean)
2023-12-05 21:25   ` Paul Moore
2023-11-29 21:50 ` [PATCH 15/16] commoncap: use vfs fscaps interfaces for killpriv checks Seth Forshee (DigitalOcean)
2023-12-11  7:57   ` kernel test robot
2023-11-29 21:50 ` [PATCH 16/16] vfs: return -EOPNOTSUPP for fscaps from vfs_*xattr() Seth Forshee (DigitalOcean)
2023-11-30  6:10   ` Amir Goldstein
2023-11-30 16:40     ` Seth Forshee (DigitalOcean)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231129-idmap-fscap-refactor-v1-6-da5a26058a5b@kernel.org \
    --to=sforshee@kernel.org \
    --cc=amir73il@gmail.com \
    --cc=audit@vger.kernel.org \
    --cc=brauner@kernel.org \
    --cc=eparis@redhat.com \
    --cc=jmorris@namei.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=paul@paul-moore.com \
    --cc=serge@hallyn.com \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.