diff options
author | David Howells <dhowells@redhat.com> | 2006-01-08 10:02:43 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-09 05:13:53 +0100 |
commit | 017679c4d45783158dba1dd6f79e712c22bb3d9a (patch) | |
tree | a536f0b581eacd88a64077f5ff15b29d23fc6405 | |
parent | [PATCH] kmsg_write: don't return printk return value (diff) | |
download | linux-017679c4d45783158dba1dd6f79e712c22bb3d9a.tar.xz linux-017679c4d45783158dba1dd6f79e712c22bb3d9a.zip |
[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: keyring is full, error ENFILE will result. The link procedure checks the nesting of the keyrings, returning ELOOP if - it appears to deep or EDEADLK if the link would introduce a cycle. + it appears too deep or EDEADLK if the link would introduce a cycle. (*) Unlink a key or keyring from another keyring: @@ -628,6 +628,19 @@ The keyctl syscall functions are: there is one, otherwise the user default session keyring. + (*) Set the timeout on a key. + + long keyctl(KEYCTL_SET_TIMEOUT, key_serial_t key, unsigned timeout); + + This sets or clears the timeout on a key. The timeout can be 0 to clear + the timeout or a number of seconds to set the expiry time that far into + the future. + + The process must have attribute modification access on a key to set its + timeout. Timeouts may not be set with this function on negative, revoked + or expired keys. + + =============== KERNEL SERVICES =============== 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 @@ #define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */ #define KEYCTL_NEGATE 13 /* negate a partially constructed key */ #define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */ +#define KEYCTL_SET_TIMEOUT 15 /* set key timeout */ #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, case KEYCTL_SET_REQKEY_KEYRING: return keyctl_set_reqkey_keyring(arg2); + case KEYCTL_SET_TIMEOUT: + return keyctl_set_timeout(arg2, arg3); + default: return -EOPNOTSUPP; } 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 *, size_t, key_serial_t); extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t); extern long keyctl_set_reqkey_keyring(int); +extern long keyctl_set_timeout(key_serial_t, unsigned); /* 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) /*****************************************************************************/ /* + * set or clear the timeout for a key + */ +long keyctl_set_timeout(key_serial_t id, unsigned timeout) +{ + struct timespec now; + struct key *key; + key_ref_t key_ref; + time_t expiry; + long ret; + + key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR); + if (IS_ERR(key_ref)) { + ret = PTR_ERR(key_ref); + goto error; + } + + key = key_ref_to_ptr(key_ref); + + /* make the changes with the locks held to prevent races */ + down_write(&key->sem); + + expiry = 0; + if (timeout > 0) { + now = current_kernel_time(); + expiry = now.tv_sec + timeout; + } + + key->expiry = expiry; + + up_write(&key->sem); + key_put(key); + + ret = 0; +error: + return ret; + +} /* end keyctl_set_timeout() */ + +/*****************************************************************************/ +/* * the key control system call */ 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, case KEYCTL_SET_REQKEY_KEYRING: return keyctl_set_reqkey_keyring(arg2); + case KEYCTL_SET_TIMEOUT: + return keyctl_set_timeout((key_serial_t) arg2, + (unsigned) arg3); + default: return -EOPNOTSUPP; } |