Commit 017679c4 authored by David Howells's avatar David Howells Committed by Linus Torvalds

[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: default avatarDavid Howells <dhowells@redhat.com>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: Alexander Zangerl <az@bond.edu.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent cd140a5c
...@@ -498,7 +498,7 @@ The keyctl syscall functions are: ...@@ -498,7 +498,7 @@ The keyctl syscall functions are:
keyring is full, error ENFILE will result. keyring is full, error ENFILE will result.
The link procedure checks the nesting of the keyrings, returning ELOOP if 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: (*) Unlink a key or keyring from another keyring:
...@@ -628,6 +628,19 @@ The keyctl syscall functions are: ...@@ -628,6 +628,19 @@ The keyctl syscall functions are:
there is one, otherwise the user default session keyring. 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 KERNEL SERVICES
=============== ===============
......
...@@ -46,5 +46,6 @@ ...@@ -46,5 +46,6 @@
#define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */ #define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */
#define KEYCTL_NEGATE 13 /* negate 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_REQKEY_KEYRING 14 /* set default request-key keyring */
#define KEYCTL_SET_TIMEOUT 15 /* set key timeout */
#endif /* _LINUX_KEYCTL_H */ #endif /* _LINUX_KEYCTL_H */
...@@ -74,6 +74,9 @@ asmlinkage long compat_sys_keyctl(u32 option, ...@@ -74,6 +74,9 @@ asmlinkage long compat_sys_keyctl(u32 option,
case KEYCTL_SET_REQKEY_KEYRING: case KEYCTL_SET_REQKEY_KEYRING:
return keyctl_set_reqkey_keyring(arg2); return keyctl_set_reqkey_keyring(arg2);
case KEYCTL_SET_TIMEOUT:
return keyctl_set_timeout(arg2, arg3);
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
...@@ -136,6 +136,7 @@ extern long keyctl_instantiate_key(key_serial_t, const void __user *, ...@@ -136,6 +136,7 @@ extern long keyctl_instantiate_key(key_serial_t, const void __user *,
size_t, key_serial_t); size_t, key_serial_t);
extern long keyctl_negate_key(key_serial_t, unsigned, 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_reqkey_keyring(int);
extern long keyctl_set_timeout(key_serial_t, unsigned);
/* /*
......
...@@ -965,6 +965,46 @@ long keyctl_set_reqkey_keyring(int reqkey_defl) ...@@ -965,6 +965,46 @@ long keyctl_set_reqkey_keyring(int reqkey_defl)
} /* end keyctl_set_reqkey_keyring() */ } /* end keyctl_set_reqkey_keyring() */
/*****************************************************************************/
/*
* 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 * the key control system call
...@@ -1038,6 +1078,10 @@ 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: case KEYCTL_SET_REQKEY_KEYRING:
return keyctl_set_reqkey_keyring(arg2); return keyctl_set_reqkey_keyring(arg2);
case KEYCTL_SET_TIMEOUT:
return keyctl_set_timeout((key_serial_t) arg2,
(unsigned) arg3);
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment