GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / s390 / char / uvdevice.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  Copyright IBM Corp. 2022
4  *  Author(s): Steffen Eiden <seiden@linux.ibm.com>
5  *
6  *  This file provides a Linux misc device to give userspace access to some
7  *  Ultravisor (UV) functions. The device only accepts IOCTLs and will only
8  *  be present if the Ultravisor facility (158) is present.
9  *
10  *  When userspace sends a valid IOCTL uvdevice will copy the input data to
11  *  kernel space, do some basic validity checks to avoid kernel/system
12  *  corruption. Any other check that the Ultravisor does will not be done by
13  *  the uvdevice to keep changes minimal when adding new functionalities
14  *  to existing UV-calls.
15  *  After the checks uvdevice builds a corresponding
16  *  Ultravisor Call Control Block, and sends the request to the Ultravisor.
17  *  Then, it copies the response, including the return codes, back to userspace.
18  *  It is the responsibility of the userspace to check for any error issued
19  *  by UV and to interpret the UV response. The uvdevice acts as a communication
20  *  channel for userspace to the Ultravisor.
21  */
22
23 #include <linux/module.h>
24 #include <linux/kernel.h>
25 #include <linux/miscdevice.h>
26 #include <linux/types.h>
27 #include <linux/stddef.h>
28 #include <linux/vmalloc.h>
29 #include <linux/slab.h>
30
31 #include <asm/uvdevice.h>
32 #include <asm/uv.h>
33
34 static int uvio_build_uvcb_attest(struct uv_cb_attest *uvcb_attest, u8 *arcb,
35                                   u8 *meas, u8 *add_data, struct uvio_attest *uvio_attest)
36 {
37         void __user *user_buf_arcb = (void __user *)uvio_attest->arcb_addr;
38
39         if (copy_from_user(arcb, user_buf_arcb, uvio_attest->arcb_len))
40                 return -EFAULT;
41
42         uvcb_attest->header.len = sizeof(*uvcb_attest);
43         uvcb_attest->header.cmd = UVC_CMD_RETR_ATTEST;
44         uvcb_attest->arcb_addr = (u64)arcb;
45         uvcb_attest->cont_token = 0;
46         uvcb_attest->user_data_len = uvio_attest->user_data_len;
47         memcpy(uvcb_attest->user_data, uvio_attest->user_data, sizeof(uvcb_attest->user_data));
48         uvcb_attest->meas_len = uvio_attest->meas_len;
49         uvcb_attest->meas_addr = (u64)meas;
50         uvcb_attest->add_data_len = uvio_attest->add_data_len;
51         uvcb_attest->add_data_addr = (u64)add_data;
52
53         return 0;
54 }
55
56 static int uvio_copy_attest_result_to_user(struct uv_cb_attest *uvcb_attest,
57                                            struct uvio_ioctl_cb *uv_ioctl,
58                                            u8 *measurement, u8 *add_data,
59                                            struct uvio_attest *uvio_attest)
60 {
61         struct uvio_attest __user *user_uvio_attest = (void __user *)uv_ioctl->argument_addr;
62         void __user *user_buf_add = (void __user *)uvio_attest->add_data_addr;
63         void __user *user_buf_meas = (void __user *)uvio_attest->meas_addr;
64         void __user *user_buf_uid = &user_uvio_attest->config_uid;
65
66         if (copy_to_user(user_buf_meas, measurement, uvio_attest->meas_len))
67                 return -EFAULT;
68         if (add_data && copy_to_user(user_buf_add, add_data, uvio_attest->add_data_len))
69                 return -EFAULT;
70         if (copy_to_user(user_buf_uid, uvcb_attest->config_uid, sizeof(uvcb_attest->config_uid)))
71                 return -EFAULT;
72         return 0;
73 }
74
75 static int get_uvio_attest(struct uvio_ioctl_cb *uv_ioctl, struct uvio_attest *uvio_attest)
76 {
77         u8 __user *user_arg_buf = (u8 __user *)uv_ioctl->argument_addr;
78
79         if (copy_from_user(uvio_attest, user_arg_buf, sizeof(*uvio_attest)))
80                 return -EFAULT;
81
82         if (uvio_attest->arcb_len > UVIO_ATT_ARCB_MAX_LEN)
83                 return -EINVAL;
84         if (uvio_attest->arcb_len == 0)
85                 return -EINVAL;
86         if (uvio_attest->meas_len > UVIO_ATT_MEASUREMENT_MAX_LEN)
87                 return -EINVAL;
88         if (uvio_attest->meas_len == 0)
89                 return -EINVAL;
90         if (uvio_attest->add_data_len > UVIO_ATT_ADDITIONAL_MAX_LEN)
91                 return -EINVAL;
92         if (uvio_attest->reserved136)
93                 return -EINVAL;
94         return 0;
95 }
96
97 /**
98  * uvio_attestation() - Perform a Retrieve Attestation Measurement UVC.
99  *
100  * @uv_ioctl: ioctl control block
101  *
102  * uvio_attestation() does a Retrieve Attestation Measurement Ultravisor Call.
103  * It verifies that the given userspace addresses are valid and request sizes
104  * are sane. Every other check is made by the Ultravisor (UV) and won't result
105  * in a negative return value. It copies the input to kernelspace, builds the
106  * request, sends the UV-call, and copies the result to userspace.
107  *
108  * The Attestation Request has two input and two outputs.
109  * ARCB and User Data are inputs for the UV generated by userspace.
110  * Measurement and Additional Data are outputs for userspace generated by UV.
111  *
112  * The Attestation Request Control Block (ARCB) is a cryptographically verified
113  * and secured request to UV and User Data is some plaintext data which is
114  * going to be included in the Attestation Measurement calculation.
115  *
116  * Measurement is a cryptographic measurement of the callers properties,
117  * optional data configured by the ARCB and the user data. If specified by the
118  * ARCB, UV will add some Additional Data to the measurement calculation.
119  * This Additional Data is then returned as well.
120  *
121  * If the Retrieve Attestation Measurement UV facility is not present,
122  * UV will return invalid command rc. This won't be fenced in the driver
123  * and does not result in a negative return value.
124  *
125  * Context: might sleep
126  *
127  * Return: 0 on success or a negative error code on error.
128  */
129 static int uvio_attestation(struct uvio_ioctl_cb *uv_ioctl)
130 {
131         struct uv_cb_attest *uvcb_attest = NULL;
132         struct uvio_attest *uvio_attest = NULL;
133         u8 *measurement = NULL;
134         u8 *add_data = NULL;
135         u8 *arcb = NULL;
136         int ret;
137
138         ret = -EINVAL;
139         if (uv_ioctl->argument_len != sizeof(*uvio_attest))
140                 goto out;
141
142         ret = -ENOMEM;
143         uvio_attest = kzalloc(sizeof(*uvio_attest), GFP_KERNEL);
144         if (!uvio_attest)
145                 goto out;
146
147         ret = get_uvio_attest(uv_ioctl, uvio_attest);
148         if (ret)
149                 goto out;
150
151         ret = -ENOMEM;
152         arcb = kvzalloc(uvio_attest->arcb_len, GFP_KERNEL);
153         measurement = kvzalloc(uvio_attest->meas_len, GFP_KERNEL);
154         if (!arcb || !measurement)
155                 goto out;
156
157         if (uvio_attest->add_data_len) {
158                 add_data = kvzalloc(uvio_attest->add_data_len, GFP_KERNEL);
159                 if (!add_data)
160                         goto out;
161         }
162
163         uvcb_attest = kzalloc(sizeof(*uvcb_attest), GFP_KERNEL);
164         if (!uvcb_attest)
165                 goto out;
166
167         ret = uvio_build_uvcb_attest(uvcb_attest, arcb,  measurement, add_data, uvio_attest);
168         if (ret)
169                 goto out;
170
171         uv_call_sched(0, (u64)uvcb_attest);
172
173         uv_ioctl->uv_rc = uvcb_attest->header.rc;
174         uv_ioctl->uv_rrc = uvcb_attest->header.rrc;
175
176         ret = uvio_copy_attest_result_to_user(uvcb_attest, uv_ioctl, measurement, add_data,
177                                               uvio_attest);
178 out:
179         kvfree(arcb);
180         kvfree(measurement);
181         kvfree(add_data);
182         kfree(uvio_attest);
183         kfree(uvcb_attest);
184         return ret;
185 }
186
187 static int uvio_copy_and_check_ioctl(struct uvio_ioctl_cb *ioctl, void __user *argp)
188 {
189         if (copy_from_user(ioctl, argp, sizeof(*ioctl)))
190                 return -EFAULT;
191         if (ioctl->flags != 0)
192                 return -EINVAL;
193         if (memchr_inv(ioctl->reserved14, 0, sizeof(ioctl->reserved14)))
194                 return -EINVAL;
195
196         return 0;
197 }
198
199 /*
200  * IOCTL entry point for the Ultravisor device.
201  */
202 static long uvio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
203 {
204         void __user *argp = (void __user *)arg;
205         struct uvio_ioctl_cb uv_ioctl = { };
206         long ret;
207
208         switch (cmd) {
209         case UVIO_IOCTL_ATT:
210                 ret = uvio_copy_and_check_ioctl(&uv_ioctl, argp);
211                 if (ret)
212                         return ret;
213                 ret = uvio_attestation(&uv_ioctl);
214                 break;
215         default:
216                 ret = -ENOIOCTLCMD;
217                 break;
218         }
219         if (ret)
220                 return ret;
221
222         if (copy_to_user(argp, &uv_ioctl, sizeof(uv_ioctl)))
223                 ret = -EFAULT;
224
225         return ret;
226 }
227
228 static const struct file_operations uvio_dev_fops = {
229         .owner = THIS_MODULE,
230         .unlocked_ioctl = uvio_ioctl,
231         .llseek = no_llseek,
232 };
233
234 static struct miscdevice uvio_dev_miscdev = {
235         .minor = MISC_DYNAMIC_MINOR,
236         .name = UVIO_DEVICE_NAME,
237         .fops = &uvio_dev_fops,
238 };
239
240 static void __exit uvio_dev_exit(void)
241 {
242         misc_deregister(&uvio_dev_miscdev);
243 }
244
245 static int __init uvio_dev_init(void)
246 {
247         if (!test_facility(158))
248                 return -ENXIO;
249         return misc_register(&uvio_dev_miscdev);
250 }
251
252 module_init(uvio_dev_init);
253 module_exit(uvio_dev_exit);
254
255 MODULE_AUTHOR("IBM Corporation");
256 MODULE_LICENSE("GPL");
257 MODULE_DESCRIPTION("Ultravisor UAPI driver");