diff options
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r-- | security/keys/keyctl.c | 103 |
1 files changed, 96 insertions, 7 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 0d7b1946ff94..427fddcaeb19 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -913,6 +913,21 @@ static int keyctl_change_reqkey_auth(struct key *key) | |||
913 | } | 913 | } |
914 | 914 | ||
915 | /* | 915 | /* |
916 | * Copy the iovec data from userspace | ||
917 | */ | ||
918 | static long copy_from_user_iovec(void *buffer, const struct iovec *iov, | ||
919 | unsigned ioc) | ||
920 | { | ||
921 | for (; ioc > 0; ioc--) { | ||
922 | if (copy_from_user(buffer, iov->iov_base, iov->iov_len) != 0) | ||
923 | return -EFAULT; | ||
924 | buffer += iov->iov_len; | ||
925 | iov++; | ||
926 | } | ||
927 | return 0; | ||
928 | } | ||
929 | |||
930 | /* | ||
916 | * Instantiate a key with the specified payload and link the key into the | 931 | * Instantiate a key with the specified payload and link the key into the |
917 | * destination keyring if one is given. | 932 | * destination keyring if one is given. |
918 | * | 933 | * |
@@ -921,10 +936,11 @@ static int keyctl_change_reqkey_auth(struct key *key) | |||
921 | * | 936 | * |
922 | * If successful, 0 will be returned. | 937 | * If successful, 0 will be returned. |
923 | */ | 938 | */ |
924 | long keyctl_instantiate_key(key_serial_t id, | 939 | long keyctl_instantiate_key_common(key_serial_t id, |
925 | const void __user *_payload, | 940 | const struct iovec *payload_iov, |
926 | size_t plen, | 941 | unsigned ioc, |
927 | key_serial_t ringid) | 942 | size_t plen, |
943 | key_serial_t ringid) | ||
928 | { | 944 | { |
929 | const struct cred *cred = current_cred(); | 945 | const struct cred *cred = current_cred(); |
930 | struct request_key_auth *rka; | 946 | struct request_key_auth *rka; |
@@ -953,7 +969,7 @@ long keyctl_instantiate_key(key_serial_t id, | |||
953 | /* pull the payload in if one was supplied */ | 969 | /* pull the payload in if one was supplied */ |
954 | payload = NULL; | 970 | payload = NULL; |
955 | 971 | ||
956 | if (_payload) { | 972 | if (payload_iov) { |
957 | ret = -ENOMEM; | 973 | ret = -ENOMEM; |
958 | payload = kmalloc(plen, GFP_KERNEL); | 974 | payload = kmalloc(plen, GFP_KERNEL); |
959 | if (!payload) { | 975 | if (!payload) { |
@@ -965,8 +981,8 @@ long keyctl_instantiate_key(key_serial_t id, | |||
965 | goto error; | 981 | goto error; |
966 | } | 982 | } |
967 | 983 | ||
968 | ret = -EFAULT; | 984 | ret = copy_from_user_iovec(payload, payload_iov, ioc); |
969 | if (copy_from_user(payload, _payload, plen) != 0) | 985 | if (ret < 0) |
970 | goto error2; | 986 | goto error2; |
971 | } | 987 | } |
972 | 988 | ||
@@ -997,6 +1013,72 @@ error: | |||
997 | } | 1013 | } |
998 | 1014 | ||
999 | /* | 1015 | /* |
1016 | * Instantiate a key with the specified payload and link the key into the | ||
1017 | * destination keyring if one is given. | ||
1018 | * | ||
1019 | * The caller must have the appropriate instantiation permit set for this to | ||
1020 | * work (see keyctl_assume_authority). No other permissions are required. | ||
1021 | * | ||
1022 | * If successful, 0 will be returned. | ||
1023 | */ | ||
1024 | long keyctl_instantiate_key(key_serial_t id, | ||
1025 | const void __user *_payload, | ||
1026 | size_t plen, | ||
1027 | key_serial_t ringid) | ||
1028 | { | ||
1029 | if (_payload && plen) { | ||
1030 | struct iovec iov[1] = { | ||
1031 | [0].iov_base = (void __user *)_payload, | ||
1032 | [0].iov_len = plen | ||
1033 | }; | ||
1034 | |||
1035 | return keyctl_instantiate_key_common(id, iov, 1, plen, ringid); | ||
1036 | } | ||
1037 | |||
1038 | return keyctl_instantiate_key_common(id, NULL, 0, 0, ringid); | ||
1039 | } | ||
1040 | |||
1041 | /* | ||
1042 | * Instantiate a key with the specified multipart payload and link the key into | ||
1043 | * the destination keyring if one is given. | ||
1044 | * | ||
1045 | * The caller must have the appropriate instantiation permit set for this to | ||
1046 | * work (see keyctl_assume_authority). No other permissions are required. | ||
1047 | * | ||
1048 | * If successful, 0 will be returned. | ||
1049 | */ | ||
1050 | long keyctl_instantiate_key_iov(key_serial_t id, | ||
1051 | const struct iovec __user *_payload_iov, | ||
1052 | unsigned ioc, | ||
1053 | key_serial_t ringid) | ||
1054 | { | ||
1055 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; | ||
1056 | long ret; | ||
1057 | |||
1058 | if (_payload_iov == 0 || ioc == 0) | ||
1059 | goto no_payload; | ||
1060 | |||
1061 | ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc, | ||
1062 | ARRAY_SIZE(iovstack), iovstack, &iov); | ||
1063 | if (ret < 0) | ||
1064 | return ret; | ||
1065 | if (ret == 0) | ||
1066 | goto no_payload_free; | ||
1067 | |||
1068 | ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid); | ||
1069 | |||
1070 | if (iov != iovstack) | ||
1071 | kfree(iov); | ||
1072 | return ret; | ||
1073 | |||
1074 | no_payload_free: | ||
1075 | if (iov != iovstack) | ||
1076 | kfree(iov); | ||
1077 | no_payload: | ||
1078 | return keyctl_instantiate_key_common(id, NULL, 0, 0, ringid); | ||
1079 | } | ||
1080 | |||
1081 | /* | ||
1000 | * Negatively instantiate the key with the given timeout (in seconds) and link | 1082 | * Negatively instantiate the key with the given timeout (in seconds) and link |
1001 | * the key into the destination keyring if one is given. | 1083 | * the key into the destination keyring if one is given. |
1002 | * | 1084 | * |
@@ -1528,6 +1610,13 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3, | |||
1528 | (unsigned) arg4, | 1610 | (unsigned) arg4, |
1529 | (key_serial_t) arg5); | 1611 | (key_serial_t) arg5); |
1530 | 1612 | ||
1613 | case KEYCTL_INSTANTIATE_IOV: | ||
1614 | return keyctl_instantiate_key_iov( | ||
1615 | (key_serial_t) arg2, | ||
1616 | (const struct iovec __user *) arg3, | ||
1617 | (unsigned) arg4, | ||
1618 | (key_serial_t) arg5); | ||
1619 | |||
1531 | default: | 1620 | default: |
1532 | return -EOPNOTSUPP; | 1621 | return -EOPNOTSUPP; |
1533 | } | 1622 | } |