summaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
authorDavid Howells2013-11-06 15:01:51 +0100
committerDavid Howells2013-11-06 15:01:51 +0100
commitfbf8c53f1a2ac7610ed124043600dc074992e71b (patch)
treef0a6e0226507a85389737e650879aa6ee0dfe4ad /security/keys
parentKEYS: The RSA public key algorithm needs to select MPILIB (diff)
downloadkernel-qcow2-linux-fbf8c53f1a2ac7610ed124043600dc074992e71b.tar.gz
kernel-qcow2-linux-fbf8c53f1a2ac7610ed124043600dc074992e71b.tar.xz
kernel-qcow2-linux-fbf8c53f1a2ac7610ed124043600dc074992e71b.zip
KEYS: Fix UID check in keyctl_get_persistent()
If the UID is specified by userspace when calling the KEYCTL_GET_PERSISTENT function and the process does not have the CAP_SETUID capability, then the function will return -EPERM if the current process's uid, suid, euid and fsuid all match the requested UID. This is incorrect. Fix it such that when a non-privileged caller requests a persistent keyring by a specific UID they can only request their own (ie. the specified UID matches either then process's UID or the process's EUID). This can be tested by logging in as the user and doing: keyctl get_persistent @p keyctl get_persistent @p `id -u` keyctl get_persistent @p 0 The first two should successfully print the same key ID. The third should do the same if called by UID 0 or indicate Operation Not Permitted otherwise. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Stephen Gallagher <sgallagh@redhat.com>
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/persistent.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/security/keys/persistent.c b/security/keys/persistent.c
index 82f4957a7acf..0ad3ee283781 100644
--- a/security/keys/persistent.c
+++ b/security/keys/persistent.c
@@ -144,10 +144,8 @@ long keyctl_get_persistent(uid_t _uid, key_serial_t destid)
/* You can only see your own persistent cache if you're not
* sufficiently privileged.
*/
- if (uid_eq(uid, current_uid()) &&
- uid_eq(uid, current_suid()) &&
- uid_eq(uid, current_euid()) &&
- uid_eq(uid, current_fsuid()) &&
+ if (!uid_eq(uid, current_uid()) &&
+ !uid_eq(uid, current_euid()) &&
!ns_capable(ns, CAP_SETUID))
return -EPERM;
}