diff options
Diffstat (limited to 'security/keys/compat.c')
-rw-r--r-- | security/keys/compat.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/security/keys/compat.c b/security/keys/compat.c index 17c99d0149ec..338b510e9027 100644 --- a/security/keys/compat.c +++ b/security/keys/compat.c | |||
@@ -12,9 +12,52 @@ | |||
12 | #include <linux/syscalls.h> | 12 | #include <linux/syscalls.h> |
13 | #include <linux/keyctl.h> | 13 | #include <linux/keyctl.h> |
14 | #include <linux/compat.h> | 14 | #include <linux/compat.h> |
15 | #include <linux/slab.h> | ||
15 | #include "internal.h" | 16 | #include "internal.h" |
16 | 17 | ||
17 | /* | 18 | /* |
19 | * Instantiate a key with the specified compatibility multipart payload and | ||
20 | * link the key into the destination keyring if one is given. | ||
21 | * | ||
22 | * The caller must have the appropriate instantiation permit set for this to | ||
23 | * work (see keyctl_assume_authority). No other permissions are required. | ||
24 | * | ||
25 | * If successful, 0 will be returned. | ||
26 | */ | ||
27 | long compat_keyctl_instantiate_key_iov( | ||
28 | key_serial_t id, | ||
29 | const struct compat_iovec __user *_payload_iov, | ||
30 | unsigned ioc, | ||
31 | key_serial_t ringid) | ||
32 | { | ||
33 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; | ||
34 | long ret; | ||
35 | |||
36 | if (_payload_iov == 0 || ioc == 0) | ||
37 | goto no_payload; | ||
38 | |||
39 | ret = compat_rw_copy_check_uvector(WRITE, _payload_iov, ioc, | ||
40 | ARRAY_SIZE(iovstack), | ||
41 | iovstack, &iov); | ||
42 | if (ret < 0) | ||
43 | return ret; | ||
44 | if (ret == 0) | ||
45 | goto no_payload_free; | ||
46 | |||
47 | ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid); | ||
48 | |||
49 | if (iov != iovstack) | ||
50 | kfree(iov); | ||
51 | return ret; | ||
52 | |||
53 | no_payload_free: | ||
54 | if (iov != iovstack) | ||
55 | kfree(iov); | ||
56 | no_payload: | ||
57 | return keyctl_instantiate_key_common(id, NULL, 0, 0, ringid); | ||
58 | } | ||
59 | |||
60 | /* | ||
18 | * The key control system call, 32-bit compatibility version for 64-bit archs | 61 | * The key control system call, 32-bit compatibility version for 64-bit archs |
19 | * | 62 | * |
20 | * This should only be called if the 64-bit arch uses weird pointers in 32-bit | 63 | * This should only be called if the 64-bit arch uses weird pointers in 32-bit |
@@ -88,6 +131,10 @@ asmlinkage long compat_sys_keyctl(u32 option, | |||
88 | case KEYCTL_REJECT: | 131 | case KEYCTL_REJECT: |
89 | return keyctl_reject_key(arg2, arg3, arg4, arg5); | 132 | return keyctl_reject_key(arg2, arg3, arg4, arg5); |
90 | 133 | ||
134 | case KEYCTL_INSTANTIATE_IOV: | ||
135 | return compat_keyctl_instantiate_key_iov( | ||
136 | arg2, compat_ptr(arg3), arg4, arg5); | ||
137 | |||
91 | default: | 138 | default: |
92 | return -EOPNOTSUPP; | 139 | return -EOPNOTSUPP; |
93 | } | 140 | } |