diff options
author | David Howells <dhowells@redhat.com> | 2006-01-08 04:02:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-08 23:13:53 -0500 |
commit | 017679c4d45783158dba1dd6f79e712c22bb3d9a (patch) | |
tree | a536f0b581eacd88a64077f5ff15b29d23fc6405 | |
parent | cd140a5c1f456f50897af4a2e9a23d228a5fe719 (diff) |
[PATCH] keys: Permit key expiry time to be set
Add a new keyctl function that allows the expiry time to be set on a key or
removed from a key, provided the caller has attribute modification access.
Signed-off-by: David Howells <dhowells@redhat.com>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: Alexander Zangerl <az@bond.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | Documentation/keys.txt | 15 | ||||
-rw-r--r-- | include/linux/keyctl.h | 1 | ||||
-rw-r--r-- | security/keys/compat.c | 3 | ||||
-rw-r--r-- | security/keys/internal.h | 1 | ||||
-rw-r--r-- | security/keys/keyctl.c | 44 |
5 files changed, 63 insertions, 1 deletions
diff --git a/Documentation/keys.txt b/Documentation/keys.txt index 6304db59bfe4..c17c4ca74302 100644 --- a/Documentation/keys.txt +++ b/Documentation/keys.txt | |||
@@ -498,7 +498,7 @@ The keyctl syscall functions are: | |||
498 | keyring is full, error ENFILE will result. | 498 | keyring is full, error ENFILE will result. |
499 | 499 | ||
500 | The link procedure checks the nesting of the keyrings, returning ELOOP if | 500 | The link procedure checks the nesting of the keyrings, returning ELOOP if |
501 | it appears to deep or EDEADLK if the link would introduce a cycle. | 501 | it appears too deep or EDEADLK if the link would introduce a cycle. |
502 | 502 | ||
503 | 503 | ||
504 | (*) Unlink a key or keyring from another keyring: | 504 | (*) Unlink a key or keyring from another keyring: |
@@ -628,6 +628,19 @@ The keyctl syscall functions are: | |||
628 | there is one, otherwise the user default session keyring. | 628 | there is one, otherwise the user default session keyring. |
629 | 629 | ||
630 | 630 | ||
631 | (*) Set the timeout on a key. | ||
632 | |||
633 | long keyctl(KEYCTL_SET_TIMEOUT, key_serial_t key, unsigned timeout); | ||
634 | |||
635 | This sets or clears the timeout on a key. The timeout can be 0 to clear | ||
636 | the timeout or a number of seconds to set the expiry time that far into | ||
637 | the future. | ||
638 | |||
639 | The process must have attribute modification access on a key to set its | ||
640 | timeout. Timeouts may not be set with this function on negative, revoked | ||
641 | or expired keys. | ||
642 | |||
643 | |||
631 | =============== | 644 | =============== |
632 | KERNEL SERVICES | 645 | KERNEL SERVICES |
633 | =============== | 646 | =============== |
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h index 8d7c59a29e09..ec8f3d622a8d 100644 --- a/include/linux/keyctl.h +++ b/include/linux/keyctl.h | |||
@@ -46,5 +46,6 @@ | |||
46 | #define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */ | 46 | #define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */ |
47 | #define KEYCTL_NEGATE 13 /* negate a partially constructed key */ | 47 | #define KEYCTL_NEGATE 13 /* negate a partially constructed key */ |
48 | #define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */ | 48 | #define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */ |
49 | #define KEYCTL_SET_TIMEOUT 15 /* set key timeout */ | ||
49 | 50 | ||
50 | #endif /* _LINUX_KEYCTL_H */ | 51 | #endif /* _LINUX_KEYCTL_H */ |
diff --git a/security/keys/compat.c b/security/keys/compat.c index 3303673c636e..e8e7ef4a290c 100644 --- a/security/keys/compat.c +++ b/security/keys/compat.c | |||
@@ -74,6 +74,9 @@ asmlinkage long compat_sys_keyctl(u32 option, | |||
74 | case KEYCTL_SET_REQKEY_KEYRING: | 74 | case KEYCTL_SET_REQKEY_KEYRING: |
75 | return keyctl_set_reqkey_keyring(arg2); | 75 | return keyctl_set_reqkey_keyring(arg2); |
76 | 76 | ||
77 | case KEYCTL_SET_TIMEOUT: | ||
78 | return keyctl_set_timeout(arg2, arg3); | ||
79 | |||
77 | default: | 80 | default: |
78 | return -EOPNOTSUPP; | 81 | return -EOPNOTSUPP; |
79 | } | 82 | } |
diff --git a/security/keys/internal.h b/security/keys/internal.h index 39cba97c5eb9..51f37c0bdb32 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
@@ -136,6 +136,7 @@ extern long keyctl_instantiate_key(key_serial_t, const void __user *, | |||
136 | size_t, key_serial_t); | 136 | size_t, key_serial_t); |
137 | extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t); | 137 | extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t); |
138 | extern long keyctl_set_reqkey_keyring(int); | 138 | extern long keyctl_set_reqkey_keyring(int); |
139 | extern long keyctl_set_timeout(key_serial_t, unsigned); | ||
139 | 140 | ||
140 | 141 | ||
141 | /* | 142 | /* |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index b7a468fabdf9..299f0ae11cf0 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -967,6 +967,46 @@ long keyctl_set_reqkey_keyring(int reqkey_defl) | |||
967 | 967 | ||
968 | /*****************************************************************************/ | 968 | /*****************************************************************************/ |
969 | /* | 969 | /* |
970 | * set or clear the timeout for a key | ||
971 | */ | ||
972 | long keyctl_set_timeout(key_serial_t id, unsigned timeout) | ||
973 | { | ||
974 | struct timespec now; | ||
975 | struct key *key; | ||
976 | key_ref_t key_ref; | ||
977 | time_t expiry; | ||
978 | long ret; | ||
979 | |||
980 | key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR); | ||
981 | if (IS_ERR(key_ref)) { | ||
982 | ret = PTR_ERR(key_ref); | ||
983 | goto error; | ||
984 | } | ||
985 | |||
986 | key = key_ref_to_ptr(key_ref); | ||
987 | |||
988 | /* make the changes with the locks held to prevent races */ | ||
989 | down_write(&key->sem); | ||
990 | |||
991 | expiry = 0; | ||
992 | if (timeout > 0) { | ||
993 | now = current_kernel_time(); | ||
994 | expiry = now.tv_sec + timeout; | ||
995 | } | ||
996 | |||
997 | key->expiry = expiry; | ||
998 | |||
999 | up_write(&key->sem); | ||
1000 | key_put(key); | ||
1001 | |||
1002 | ret = 0; | ||
1003 | error: | ||
1004 | return ret; | ||
1005 | |||
1006 | } /* end keyctl_set_timeout() */ | ||
1007 | |||
1008 | /*****************************************************************************/ | ||
1009 | /* | ||
970 | * the key control system call | 1010 | * the key control system call |
971 | */ | 1011 | */ |
972 | asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, | 1012 | asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, |
@@ -1038,6 +1078,10 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, | |||
1038 | case KEYCTL_SET_REQKEY_KEYRING: | 1078 | case KEYCTL_SET_REQKEY_KEYRING: |
1039 | return keyctl_set_reqkey_keyring(arg2); | 1079 | return keyctl_set_reqkey_keyring(arg2); |
1040 | 1080 | ||
1081 | case KEYCTL_SET_TIMEOUT: | ||
1082 | return keyctl_set_timeout((key_serial_t) arg2, | ||
1083 | (unsigned) arg3); | ||
1084 | |||
1041 | default: | 1085 | default: |
1042 | return -EOPNOTSUPP; | 1086 | return -EOPNOTSUPP; |
1043 | } | 1087 | } |