aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/keys.txt15
-rw-r--r--include/linux/keyctl.h1
-rw-r--r--security/keys/compat.c3
-rw-r--r--security/keys/internal.h1
-rw-r--r--security/keys/keyctl.c44
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===============
632KERNEL SERVICES 645KERNEL 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);
137extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t); 137extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
138extern long keyctl_set_reqkey_keyring(int); 138extern long keyctl_set_reqkey_keyring(int);
139extern 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 */
972long 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;
1003error:
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 */
972asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, 1012asmlinkage 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 }