[PATCH] selinux: Fix use of KEY_NEED_* instead of KEY__* perms

David Howells dhowells at redhat.com
Mon Apr 27 14:12:14 UTC 2020


Paul Moore <paul at paul-moore.com> wrote:

> Okay, can you send the next version of the patch to the SELinux list for
> review?

Here you go.  Note that I did this a few days ago and I actually used EACCES
rather than EPERM.  Which one is one preferred for this?

David
---
selinux: Fix use of KEY_NEED_* instead of KEY__* perms

selinux_key_getsecurity() is passing the KEY_NEED_* permissions to
security_sid_to_context() instead of the KEY__* values.  It happens to work
because the values are all coincident.

Fixes: d720024e94de ("[PATCH] selinux: add hooks for key subsystem")
Reported-by: Paul Moore <paul at paul-moore.com>
Signed-off-by: David Howells <dhowells at redhat.com>
---
 security/selinux/hooks.c |   22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 0b4e32161b77..6087955b49d8 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6539,20 +6539,38 @@ static void selinux_key_free(struct key *k)
 	kfree(ksec);
 }
 
+static unsigned int selinux_keyperm_to_av(unsigned int need_perm)
+{
+	switch (need_perm) {
+	case KEY_NEED_VIEW:	return KEY__VIEW;
+	case KEY_NEED_READ:	return KEY__READ;
+	case KEY_NEED_WRITE:	return KEY__WRITE;
+	case KEY_NEED_SEARCH:	return KEY__SEARCH;
+	case KEY_NEED_LINK:	return KEY__LINK;
+	case KEY_NEED_SETATTR:	return KEY__SETATTR;
+	default:
+		return 0;
+	}
+}
+
 static int selinux_key_permission(key_ref_t key_ref,
 				  const struct cred *cred,
-				  unsigned perm)
+				  unsigned need_perm)
 {
 	struct key *key;
 	struct key_security_struct *ksec;
+	unsigned int perm;
 	u32 sid;
 
 	/* if no specific permissions are requested, we skip the
 	   permission check. No serious, additional covert channels
 	   appear to be created. */
-	if (perm == 0)
+	if (need_perm == 0)
 		return 0;
 
+	perm = selinux_keyperm_to_av(need_perm);
+	if (perm == 0)
+		return -EACCES;
 	sid = cred_sid(cred);
 
 	key = key_ref_to_ptr(key_ref);



More information about the Linux-security-module-archive mailing list