aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/keys/compat.c3
-rw-r--r--security/keys/internal.h1
-rw-r--r--security/keys/keyctl.c44
3 files changed, 48 insertions, 0 deletions
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 }