Commit 017679c4d45783158dba1dd6f79e712c22bb3d9a

Authored by David Howells
Committed by Linus Torvalds
1 parent cd140a5c1f

[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>

Showing 5 changed files with 63 additions and 1 deletions Side-by-side Diff

Documentation/keys.txt
... ... @@ -498,7 +498,7 @@
498 498 keyring is full, error ENFILE will result.
499 499  
500 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 504 (*) Unlink a key or keyring from another keyring:
... ... @@ -626,6 +626,19 @@
626 626 [1] The default default is: the thread keyring if there is one, otherwise
627 627 the process keyring if there is one, otherwise the session keyring if
628 628 there is one, otherwise the user default session keyring.
  629 +
  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.
629 642  
630 643  
631 644 ===============
include/linux/keyctl.h
... ... @@ -46,6 +46,7 @@
46 46 #define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */
47 47 #define KEYCTL_NEGATE 13 /* negate a partially constructed key */
48 48 #define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */
  49 +#define KEYCTL_SET_TIMEOUT 15 /* set key timeout */
49 50  
50 51 #endif /* _LINUX_KEYCTL_H */
security/keys/compat.c
... ... @@ -74,6 +74,9 @@
74 74 case KEYCTL_SET_REQKEY_KEYRING:
75 75 return keyctl_set_reqkey_keyring(arg2);
76 76  
  77 + case KEYCTL_SET_TIMEOUT:
  78 + return keyctl_set_timeout(arg2, arg3);
  79 +
77 80 default:
78 81 return -EOPNOTSUPP;
79 82 }
security/keys/internal.h
... ... @@ -136,6 +136,7 @@
136 136 size_t, key_serial_t);
137 137 extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
138 138 extern long keyctl_set_reqkey_keyring(int);
  139 +extern long keyctl_set_timeout(key_serial_t, unsigned);
139 140  
140 141  
141 142 /*
security/keys/keyctl.c
... ... @@ -967,6 +967,46 @@
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 1010 * the key control system call
971 1011 */
972 1012 asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
... ... @@ -1037,6 +1077,10 @@
1037 1077  
1038 1078 case KEYCTL_SET_REQKEY_KEYRING:
1039 1079 return keyctl_set_reqkey_keyring(arg2);
  1080 +
  1081 + case KEYCTL_SET_TIMEOUT:
  1082 + return keyctl_set_timeout((key_serial_t) arg2,
  1083 + (unsigned) arg3);
1040 1084  
1041 1085 default:
1042 1086 return -EOPNOTSUPP;