Skip to contentSkip to conversation

Make key management use syscalls not prctls

PATCH In review David Howells 2 participants 3 messages Sep 6, 2004 – Sep 7, 2004

Subsystems (4)
lore
Share & tools
lore

David Howells

author maintainer
#0 lore raw

PATCH 1/1 Make key management use syscalls not prctls

The attached patch makes the key management patch use syscalls instead of prctls, though only the i386 arch is so furnished by this patch.

This patch creates three new syscalls: add_key(), request_key() and keyctl(), the last of which is provides all the other key and keyring manipulation operations that used to be prctls.

Doing this allows simplification of the interface... those calls that take a payload no longer look for the payload length in the first two bytes of the buffer but take it instead as a syscall argument.

http://people.redhat.com/~dhowells/keys/keyctl.c has been updated to match.

---

warthog>diffstat keys-syscalls-269rc1mm2.diff

 Documentation/keys.txt       |  146 ++++++-----
 arch/i386/kernel/entry.S     |    5 
 include/asm-generic/errno.h  |    2 
 include/asm-i386/unistd.h    |    9 
 include/linux/key.h          |   21 +
 include/linux/keyctl.h       |   39 +++
 include/linux/prctl.h        |   26 --
 kernel/sys.c                 |   14 -
 security/keys/keyctl.c       |  531 +++++++++++++++++++++++--------------------
 security/keys/process_keys.c |   80 ------
 10 files changed, 440 insertions(+), 433 deletions(-)
arch/i386/kernel/entry.S +4 -1
diff -uNr linux-2.6.9-rc1-mm2-keys-reqkey/arch/i386/kernel/entry.S linux-2.6.9-rc1-mm2-keys-syscalls/arch/i386/kernel/entry.S
@@ -943,6 +943,9 @@
 	.long sys_vperfctr_unlink
 	.long sys_vperfctr_iresume
 	.long sys_vperfctr_read
-	.long sys_waitid
+	.long sys_waitid		/* 290 */
+	.long sys_add_key
+	.long sys_request_key
+	.long sys_keyctl
 
 syscall_table_size=(.-sys_call_table)
Documentation/keys.txt +76 -70

202 lines not on this page · raw message

include/asm-generic/errno.h +2 -0
diff -uNr linux-2.6.9-rc1-mm2-keys-reqkey/include/asm-generic/errno.h linux-2.6.9-rc1-mm2-keys-syscalls/include/asm-generic/errno.h
@@ -101,4 +101,6 @@
 #define	EKEYREVOKED	127	/* Key has been revoked */
 #define	EKEYREJECTED	128	/* Key was rejected by service */
 
+#define	__ERRNO_LAST	128
+
 #endif
include/asm-i386/unistd.h +6 -3
diff -uNr linux-2.6.9-rc1-mm2-keys-reqkey/include/asm-i386/unistd.h linux-2.6.9-rc1-mm2-keys-syscalls/include/asm-i386/unistd.h
@@ -296,14 +296,17 @@
 #define __NR_vperfctr_iresume	(__NR_perfctr_info+4)
 #define __NR_vperfctr_read	(__NR_perfctr_info+5)
 #define __NR_waitid		290
+#define __NR_add_key		291
+#define __NR_request_key	292
+#define __NR_keyctl		293
 
-#define NR_syscalls 291
+#define NR_syscalls 294
 
-/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
+/* user-visible error numbers are in the range -1 - -128: see <asm-i386/errno.h> */
 
 #define __syscall_return(type, res) \
 do { \
-	if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+	if ((unsigned long)(res) >= (unsigned long)(-(__ERRNO_LAST + 1))) { \
 		errno = -(res); \
 		res = -1; \
 	} \
include/linux/keyctl.h +39 -0
diff -uNr linux-2.6.9-rc1-mm2-keys-reqkey/include/linux/keyctl.h linux-2.6.9-rc1-mm2-keys-syscalls/include/linux/keyctl.h
@@ -0,0 +1,39 @@
+/* keyctl.h: keyctl command IDs
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_KEYCTL_H
+#define _LINUX_KEYCTL_H 
+
+/* special process keyring shortcut IDs */
+#define KEY_SPEC_THREAD_KEYRING		-1	/* - key ID for thread-specific keyring */
+#define KEY_SPEC_PROCESS_KEYRING	-2	/* - key ID for process-specific keyring */
+#define KEY_SPEC_SESSION_KEYRING	-3	/* - key ID for session-specific keyring */
+#define KEY_SPEC_USER_KEYRING		-4	/* - key ID for UID-specific keyring */
+#define KEY_SPEC_USER_SESSION_KEYRING	-5	/* - key ID for UID-session keyring */
+#define KEY_SPEC_GROUP_KEYRING		-6	/* - key ID for GID-specific keyring */
+
+/* keyctl commands */
+#define KEYCTL_GET_KEYRING_ID		0	/* ask for a keyring's ID */
+#define KEYCTL_JOIN_SESSION_KEYRING	1	/* join or start named session keyring */
+#define KEYCTL_UPDATE			2	/* update a key */
+#define KEYCTL_REVOKE			3	/* revoke a key */
+#define KEYCTL_CHOWN			4	/* set ownership of a key */
+#define KEYCTL_SETPERM			5	/* set perms on a key */
+#define KEYCTL_DESCRIBE			6	/* describe a key */
+#define KEYCTL_CLEAR			7	/* clear contents of a keyring */
+#define KEYCTL_LINK			8	/* link a key into a keyring */
+#define KEYCTL_UNLINK			9	/* unlink a key from a keyring */
+#define KEYCTL_SEARCH			10	/* search for a key in a keyring */
+#define KEYCTL_READ			11	/* read a key or keyring's contents */
+#define KEYCTL_INSTANTIATE		12	/* instantiate a partially constructed key */
+#define KEYCTL_NEGATE			13	/* negate a partially constructed key */
+
+#endif /*  _LINUX_KEYCTL_H */
include/linux/key.h +15 -6
diff -uNr linux-2.6.9-rc1-mm2-keys-reqkey/include/linux/key.h linux-2.6.9-rc1-mm2-keys-syscalls/include/linux/key.h
@@ -250,10 +250,19 @@
 extern int exec_keys(struct task_struct *tsk);
 extern void key_fsuid_changed(struct task_struct *tsk);
 extern void key_fsgid_changed(struct task_struct *tsk);
-extern long get_process_keyring_ID(key_serial_t id, int create);
-extern long join_session_keyring_user(const char __user *name);
 
-asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
+asmlinkage long sys_add_key(const char __user *_type,
+			    const char __user *_description,
+			    const void __user *_payload,
+			    size_t plen,
+			    key_serial_t destringid);
+
+asmlinkage long sys_request_key(const char __user *_type,
+				const char __user *_description,
+				const char __user *_callout_info,
+				key_serial_t destringid);
+
+asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3,
 			   unsigned long arg4, unsigned long arg5);
 
 #else /* CONFIG_KEYS */
@@ -267,9 +276,9 @@
 #define exec_keys(t)			do { } while(0)
 #define key_fsuid_changed(t)		do { } while(0)
 #define key_fsgid_changed(t)		do { } while(0)
-#define get_process_keyring_ID(s,c)	(-EINVAL)
-#define join_session_keyring_user(n)	(-EINVAL)
-#define sys_keyctl(o,b,c,d,e)		(-EINVAL)
+#define sys_addkey(a,b,c,d,e)		(-ENOSYS)
+#define sys_request_key(a,b,c,d,e)	(-ENOSYS)
+#define sys_keyctl(a,b,c,d,e)		(-ENOSYS)
 
 #endif /* CONFIG_KEYS */
 #endif /* __KERNEL__ */
include/linux/prctl.h +0 -26
diff -uNr linux-2.6.9-rc1-mm2-keys-reqkey/include/linux/prctl.h linux-2.6.9-rc1-mm2-keys-syscalls/include/linux/prctl.h
@@ -49,30 +49,4 @@
 # define PR_TIMING_TIMESTAMP    1       /* Accurate timestamp based
                                                    process timing */
 
-/* Manage a process's keyrings */
-#define PR_SPEC_THREAD_KEYRING		-1	/* - key ID for thread-specific keyring */
-#define PR_SPEC_PROCESS_KEYRING		-2	/* - key ID for process-specific keyring */
-#define PR_SPEC_SESSION_KEYRING		-3	/* - key ID for session-specific keyring */
-#define PR_SPEC_USER_KEYRING		-4	/* - key ID for UID-specific keyring */
-#define PR_SPEC_USER_SESSION_KEYRING	-5	/* - key ID for UID-session keyring */
-#define PR_SPEC_GROUP_KEYRING		-6	/* - key ID for GID-specific keyring */
-
-#define PR_GET_KEYRING_ID		15	/* ask for a keyring's ID */
-#define PR_JOIN_SESSION_KEYRING		16	/* join or start named session keyring */
-#define KEYCTL_NEW			0x100	/* create a key and add to specified keyring */
-#define KEYCTL_UPDATE			0x101	/* update a key */
-#define KEYCTL_REVOKE			0x102	/* revoke a key */
-#define KEYCTL_CHOWN			0x103	/* set ownership of a key */
-#define KEYCTL_SETPERM			0x104	/* set perms on a key */
-#define KEYCTL_DESCRIBE			0x105	/* describe a key */
-#define KEYCTL_CLEAR			0x106	/* clear contents of a keyring */
-#define KEYCTL_LINK			0x107	/* link a key into a keyring */
-#define KEYCTL_UNLINK			0x108	/* unlink a key from a keyring */
-#define KEYCTL_SEARCH			0x109	/* search for a key in a keyring */
-#define KEYCTL_READ			0x10a	/* read a key or keyring's contents */
-#define KEYCTL_REQUEST_KEY		0x10b	/* request a key from the process's keyrings */
-#define KEYCTL_INSTANTIATE		0x10c	/* instantiate a partially constructed key */
-#define KEYCTL_NEGATE			0x10d	/* negate a partially constructed key */
-#define __KEYCTL_LAST			0x10d
-
 #endif /* _LINUX_PRCTL_H */
kernel/sys.c +3 -11
diff -uNr linux-2.6.9-rc1-mm2-keys-reqkey/kernel/sys.c linux-2.6.9-rc1-mm2-keys-syscalls/kernel/sys.c
@@ -279,6 +279,9 @@
 cond_syscall(sys_get_mempolicy)
 cond_syscall(sys_set_mempolicy)
 cond_syscall(compat_get_mempolicy)
+cond_syscall(sys_add_key)
+cond_syscall(sys_request_key)
+cond_syscall(sys_keyctl)
 
 /* arch-specific weak syscall entries */
 cond_syscall(sys_pciconfig_read)
@@ -1783,17 +1786,6 @@
 			current->keep_capabilities = arg2;
 			break;
 
-		case PR_GET_KEYRING_ID:
-			error = get_process_keyring_ID((key_serial_t) arg2, arg3);
-			break;
-		case PR_JOIN_SESSION_KEYRING:
-			error = join_session_keyring_user((const char __user *) arg2);
-			break;
-
-		case KEYCTL_NEW ... __KEYCTL_LAST:
-			error = sys_keyctl(option, arg2, arg3, arg4, arg5);
-			break;
-
 		default:
 			error = -EINVAL;
 			break;
security/keys/keyctl.c +288 -243

784 lines not on this page · raw message

security/keys/process_keys.c +7 -73

127 lines not on this page · raw message

#1 lore raw

Umm, sys_keyctl is one of those ioctl lookalikes that are an incredible pain for 32bit compat and we agreed to not add anymore.

author maintainer
#2 lore raw
Quoted 3 lines

Umm, sys_keyctl is one of those ioctl lookalikes that are an incredible pain for 32bit compat and we agreed to not add anymore.

Fixing up should be trivial in this case. It should just be a matter of clearing the top 32 bits of every 64-bit argument. There are no structs that need grabbing from userspace and fixing up.

David