aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r--security/keys/keyctl.c151
1 files changed, 128 insertions, 23 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index b7a468fabdf9..3d2ebae029c1 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -834,6 +834,17 @@ long keyctl_instantiate_key(key_serial_t id,
834 if (plen > 32767) 834 if (plen > 32767)
835 goto error; 835 goto error;
836 836
837 /* the appropriate instantiation authorisation key must have been
838 * assumed before calling this */
839 ret = -EPERM;
840 instkey = current->request_key_auth;
841 if (!instkey)
842 goto error;
843
844 rka = instkey->payload.data;
845 if (rka->target_key->serial != id)
846 goto error;
847
837 /* pull the payload in if one was supplied */ 848 /* pull the payload in if one was supplied */
838 payload = NULL; 849 payload = NULL;
839 850
@@ -848,15 +859,6 @@ long keyctl_instantiate_key(key_serial_t id,
848 goto error2; 859 goto error2;
849 } 860 }
850 861
851 /* find the instantiation authorisation key */
852 instkey = key_get_instantiation_authkey(id);
853 if (IS_ERR(instkey)) {
854 ret = PTR_ERR(instkey);
855 goto error2;
856 }
857
858 rka = instkey->payload.data;
859
860 /* find the destination keyring amongst those belonging to the 862 /* find the destination keyring amongst those belonging to the
861 * requesting task */ 863 * requesting task */
862 keyring_ref = NULL; 864 keyring_ref = NULL;
@@ -865,7 +867,7 @@ long keyctl_instantiate_key(key_serial_t id,
865 KEY_WRITE); 867 KEY_WRITE);
866 if (IS_ERR(keyring_ref)) { 868 if (IS_ERR(keyring_ref)) {
867 ret = PTR_ERR(keyring_ref); 869 ret = PTR_ERR(keyring_ref);
868 goto error3; 870 goto error2;
869 } 871 }
870 } 872 }
871 873
@@ -874,11 +876,17 @@ long keyctl_instantiate_key(key_serial_t id,
874 key_ref_to_ptr(keyring_ref), instkey); 876 key_ref_to_ptr(keyring_ref), instkey);
875 877
876 key_ref_put(keyring_ref); 878 key_ref_put(keyring_ref);
877 error3: 879
878 key_put(instkey); 880 /* discard the assumed authority if it's just been disabled by
879 error2: 881 * instantiation of the key */
882 if (ret == 0) {
883 key_put(current->request_key_auth);
884 current->request_key_auth = NULL;
885 }
886
887error2:
880 kfree(payload); 888 kfree(payload);
881 error: 889error:
882 return ret; 890 return ret;
883 891
884} /* end keyctl_instantiate_key() */ 892} /* end keyctl_instantiate_key() */
@@ -895,14 +903,16 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
895 key_ref_t keyring_ref; 903 key_ref_t keyring_ref;
896 long ret; 904 long ret;
897 905
898 /* find the instantiation authorisation key */ 906 /* the appropriate instantiation authorisation key must have been
899 instkey = key_get_instantiation_authkey(id); 907 * assumed before calling this */
900 if (IS_ERR(instkey)) { 908 ret = -EPERM;
901 ret = PTR_ERR(instkey); 909 instkey = current->request_key_auth;
910 if (!instkey)
902 goto error; 911 goto error;
903 }
904 912
905 rka = instkey->payload.data; 913 rka = instkey->payload.data;
914 if (rka->target_key->serial != id)
915 goto error;
906 916
907 /* find the destination keyring if present (which must also be 917 /* find the destination keyring if present (which must also be
908 * writable) */ 918 * writable) */
@@ -911,7 +921,7 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
911 keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 921 keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
912 if (IS_ERR(keyring_ref)) { 922 if (IS_ERR(keyring_ref)) {
913 ret = PTR_ERR(keyring_ref); 923 ret = PTR_ERR(keyring_ref);
914 goto error2; 924 goto error;
915 } 925 }
916 } 926 }
917 927
@@ -920,9 +930,15 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
920 key_ref_to_ptr(keyring_ref), instkey); 930 key_ref_to_ptr(keyring_ref), instkey);
921 931
922 key_ref_put(keyring_ref); 932 key_ref_put(keyring_ref);
923 error2: 933
924 key_put(instkey); 934 /* discard the assumed authority if it's just been disabled by
925 error: 935 * instantiation of the key */
936 if (ret == 0) {
937 key_put(current->request_key_auth);
938 current->request_key_auth = NULL;
939 }
940
941error:
926 return ret; 942 return ret;
927 943
928} /* end keyctl_negate_key() */ 944} /* end keyctl_negate_key() */
@@ -967,6 +983,88 @@ long keyctl_set_reqkey_keyring(int reqkey_defl)
967 983
968/*****************************************************************************/ 984/*****************************************************************************/
969/* 985/*
986 * set or clear the timeout for a key
987 */
988long keyctl_set_timeout(key_serial_t id, unsigned timeout)
989{
990 struct timespec now;
991 struct key *key;
992 key_ref_t key_ref;
993 time_t expiry;
994 long ret;
995
996 key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
997 if (IS_ERR(key_ref)) {
998 ret = PTR_ERR(key_ref);
999 goto error;
1000 }
1001
1002 key = key_ref_to_ptr(key_ref);
1003
1004 /* make the changes with the locks held to prevent races */
1005 down_write(&key->sem);
1006
1007 expiry = 0;
1008 if (timeout > 0) {
1009 now = current_kernel_time();
1010 expiry = now.tv_sec + timeout;
1011 }
1012
1013 key->expiry = expiry;
1014
1015 up_write(&key->sem);
1016 key_put(key);
1017
1018 ret = 0;
1019error:
1020 return ret;
1021
1022} /* end keyctl_set_timeout() */
1023
1024/*****************************************************************************/
1025/*
1026 * assume the authority to instantiate the specified key
1027 */
1028long keyctl_assume_authority(key_serial_t id)
1029{
1030 struct key *authkey;
1031 long ret;
1032
1033 /* special key IDs aren't permitted */
1034 ret = -EINVAL;
1035 if (id < 0)
1036 goto error;
1037
1038 /* we divest ourselves of authority if given an ID of 0 */
1039 if (id == 0) {
1040 key_put(current->request_key_auth);
1041 current->request_key_auth = NULL;
1042 ret = 0;
1043 goto error;
1044 }
1045
1046 /* attempt to assume the authority temporarily granted to us whilst we
1047 * instantiate the specified key
1048 * - the authorisation key must be in the current task's keyrings
1049 * somewhere
1050 */
1051 authkey = key_get_instantiation_authkey(id);
1052 if (IS_ERR(authkey)) {
1053 ret = PTR_ERR(authkey);
1054 goto error;
1055 }
1056
1057 key_put(current->request_key_auth);
1058 current->request_key_auth = authkey;
1059 ret = authkey->serial;
1060
1061error:
1062 return ret;
1063
1064} /* end keyctl_assume_authority() */
1065
1066/*****************************************************************************/
1067/*
970 * the key control system call 1068 * the key control system call
971 */ 1069 */
972asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, 1070asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
@@ -1038,6 +1136,13 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
1038 case KEYCTL_SET_REQKEY_KEYRING: 1136 case KEYCTL_SET_REQKEY_KEYRING:
1039 return keyctl_set_reqkey_keyring(arg2); 1137 return keyctl_set_reqkey_keyring(arg2);
1040 1138
1139 case KEYCTL_SET_TIMEOUT:
1140 return keyctl_set_timeout((key_serial_t) arg2,
1141 (unsigned) arg3);
1142
1143 case KEYCTL_ASSUME_AUTHORITY:
1144 return keyctl_assume_authority((key_serial_t) arg2);
1145
1041 default: 1146 default:
1042 return -EOPNOTSUPP; 1147 return -EOPNOTSUPP;
1043 } 1148 }