Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  Copyright IBM Corp. 2022
0004  *  Author(s): Steffen Eiden <seiden@linux.ibm.com>
0005  *
0006  *  This file provides a Linux misc device to give userspace access to some
0007  *  Ultravisor (UV) functions. The device only accepts IOCTLs and will only
0008  *  be present if the Ultravisor facility (158) is present.
0009  *
0010  *  When userspace sends a valid IOCTL uvdevice will copy the input data to
0011  *  kernel space, do some basic validity checks to avoid kernel/system
0012  *  corruption. Any other check that the Ultravisor does will not be done by
0013  *  the uvdevice to keep changes minimal when adding new functionalities
0014  *  to existing UV-calls.
0015  *  After the checks uvdevice builds a corresponding
0016  *  Ultravisor Call Control Block, and sends the request to the Ultravisor.
0017  *  Then, it copies the response, including the return codes, back to userspace.
0018  *  It is the responsibility of the userspace to check for any error issued
0019  *  by UV and to interpret the UV response. The uvdevice acts as a communication
0020  *  channel for userspace to the Ultravisor.
0021  */
0022 
0023 #include <linux/module.h>
0024 #include <linux/kernel.h>
0025 #include <linux/miscdevice.h>
0026 #include <linux/types.h>
0027 #include <linux/stddef.h>
0028 #include <linux/vmalloc.h>
0029 #include <linux/slab.h>
0030 #include <linux/cpufeature.h>
0031 
0032 #include <asm/uvdevice.h>
0033 #include <asm/uv.h>
0034 
0035 static int uvio_build_uvcb_attest(struct uv_cb_attest *uvcb_attest, u8 *arcb,
0036                   u8 *meas, u8 *add_data, struct uvio_attest *uvio_attest)
0037 {
0038     void __user *user_buf_arcb = (void __user *)uvio_attest->arcb_addr;
0039 
0040     if (copy_from_user(arcb, user_buf_arcb, uvio_attest->arcb_len))
0041         return -EFAULT;
0042 
0043     uvcb_attest->header.len = sizeof(*uvcb_attest);
0044     uvcb_attest->header.cmd = UVC_CMD_RETR_ATTEST;
0045     uvcb_attest->arcb_addr = (u64)arcb;
0046     uvcb_attest->cont_token = 0;
0047     uvcb_attest->user_data_len = uvio_attest->user_data_len;
0048     memcpy(uvcb_attest->user_data, uvio_attest->user_data, sizeof(uvcb_attest->user_data));
0049     uvcb_attest->meas_len = uvio_attest->meas_len;
0050     uvcb_attest->meas_addr = (u64)meas;
0051     uvcb_attest->add_data_len = uvio_attest->add_data_len;
0052     uvcb_attest->add_data_addr = (u64)add_data;
0053 
0054     return 0;
0055 }
0056 
0057 static int uvio_copy_attest_result_to_user(struct uv_cb_attest *uvcb_attest,
0058                        struct uvio_ioctl_cb *uv_ioctl,
0059                        u8 *measurement, u8 *add_data,
0060                        struct uvio_attest *uvio_attest)
0061 {
0062     struct uvio_attest __user *user_uvio_attest = (void __user *)uv_ioctl->argument_addr;
0063     void __user *user_buf_add = (void __user *)uvio_attest->add_data_addr;
0064     void __user *user_buf_meas = (void __user *)uvio_attest->meas_addr;
0065     void __user *user_buf_uid = &user_uvio_attest->config_uid;
0066 
0067     if (copy_to_user(user_buf_meas, measurement, uvio_attest->meas_len))
0068         return -EFAULT;
0069     if (add_data && copy_to_user(user_buf_add, add_data, uvio_attest->add_data_len))
0070         return -EFAULT;
0071     if (copy_to_user(user_buf_uid, uvcb_attest->config_uid, sizeof(uvcb_attest->config_uid)))
0072         return -EFAULT;
0073     return 0;
0074 }
0075 
0076 static int get_uvio_attest(struct uvio_ioctl_cb *uv_ioctl, struct uvio_attest *uvio_attest)
0077 {
0078     u8 __user *user_arg_buf = (u8 __user *)uv_ioctl->argument_addr;
0079 
0080     if (copy_from_user(uvio_attest, user_arg_buf, sizeof(*uvio_attest)))
0081         return -EFAULT;
0082 
0083     if (uvio_attest->arcb_len > UVIO_ATT_ARCB_MAX_LEN)
0084         return -EINVAL;
0085     if (uvio_attest->arcb_len == 0)
0086         return -EINVAL;
0087     if (uvio_attest->meas_len > UVIO_ATT_MEASUREMENT_MAX_LEN)
0088         return -EINVAL;
0089     if (uvio_attest->meas_len == 0)
0090         return -EINVAL;
0091     if (uvio_attest->add_data_len > UVIO_ATT_ADDITIONAL_MAX_LEN)
0092         return -EINVAL;
0093     if (uvio_attest->reserved136)
0094         return -EINVAL;
0095     return 0;
0096 }
0097 
0098 /**
0099  * uvio_attestation() - Perform a Retrieve Attestation Measurement UVC.
0100  *
0101  * @uv_ioctl: ioctl control block
0102  *
0103  * uvio_attestation() does a Retrieve Attestation Measurement Ultravisor Call.
0104  * It verifies that the given userspace addresses are valid and request sizes
0105  * are sane. Every other check is made by the Ultravisor (UV) and won't result
0106  * in a negative return value. It copies the input to kernelspace, builds the
0107  * request, sends the UV-call, and copies the result to userspace.
0108  *
0109  * The Attestation Request has two input and two outputs.
0110  * ARCB and User Data are inputs for the UV generated by userspace.
0111  * Measurement and Additional Data are outputs for userspace generated by UV.
0112  *
0113  * The Attestation Request Control Block (ARCB) is a cryptographically verified
0114  * and secured request to UV and User Data is some plaintext data which is
0115  * going to be included in the Attestation Measurement calculation.
0116  *
0117  * Measurement is a cryptographic measurement of the callers properties,
0118  * optional data configured by the ARCB and the user data. If specified by the
0119  * ARCB, UV will add some Additional Data to the measurement calculation.
0120  * This Additional Data is then returned as well.
0121  *
0122  * If the Retrieve Attestation Measurement UV facility is not present,
0123  * UV will return invalid command rc. This won't be fenced in the driver
0124  * and does not result in a negative return value.
0125  *
0126  * Context: might sleep
0127  *
0128  * Return: 0 on success or a negative error code on error.
0129  */
0130 static int uvio_attestation(struct uvio_ioctl_cb *uv_ioctl)
0131 {
0132     struct uv_cb_attest *uvcb_attest = NULL;
0133     struct uvio_attest *uvio_attest = NULL;
0134     u8 *measurement = NULL;
0135     u8 *add_data = NULL;
0136     u8 *arcb = NULL;
0137     int ret;
0138 
0139     ret = -EINVAL;
0140     if (uv_ioctl->argument_len != sizeof(*uvio_attest))
0141         goto out;
0142 
0143     ret = -ENOMEM;
0144     uvio_attest = kzalloc(sizeof(*uvio_attest), GFP_KERNEL);
0145     if (!uvio_attest)
0146         goto out;
0147 
0148     ret = get_uvio_attest(uv_ioctl, uvio_attest);
0149     if (ret)
0150         goto out;
0151 
0152     ret = -ENOMEM;
0153     arcb = kvzalloc(uvio_attest->arcb_len, GFP_KERNEL);
0154     measurement = kvzalloc(uvio_attest->meas_len, GFP_KERNEL);
0155     if (!arcb || !measurement)
0156         goto out;
0157 
0158     if (uvio_attest->add_data_len) {
0159         add_data = kvzalloc(uvio_attest->add_data_len, GFP_KERNEL);
0160         if (!add_data)
0161             goto out;
0162     }
0163 
0164     uvcb_attest = kzalloc(sizeof(*uvcb_attest), GFP_KERNEL);
0165     if (!uvcb_attest)
0166         goto out;
0167 
0168     ret = uvio_build_uvcb_attest(uvcb_attest, arcb,  measurement, add_data, uvio_attest);
0169     if (ret)
0170         goto out;
0171 
0172     uv_call_sched(0, (u64)uvcb_attest);
0173 
0174     uv_ioctl->uv_rc = uvcb_attest->header.rc;
0175     uv_ioctl->uv_rrc = uvcb_attest->header.rrc;
0176 
0177     ret = uvio_copy_attest_result_to_user(uvcb_attest, uv_ioctl, measurement, add_data,
0178                           uvio_attest);
0179 out:
0180     kvfree(arcb);
0181     kvfree(measurement);
0182     kvfree(add_data);
0183     kfree(uvio_attest);
0184     kfree(uvcb_attest);
0185     return ret;
0186 }
0187 
0188 static int uvio_copy_and_check_ioctl(struct uvio_ioctl_cb *ioctl, void __user *argp)
0189 {
0190     if (copy_from_user(ioctl, argp, sizeof(*ioctl)))
0191         return -EFAULT;
0192     if (ioctl->flags != 0)
0193         return -EINVAL;
0194     if (memchr_inv(ioctl->reserved14, 0, sizeof(ioctl->reserved14)))
0195         return -EINVAL;
0196 
0197     return 0;
0198 }
0199 
0200 /*
0201  * IOCTL entry point for the Ultravisor device.
0202  */
0203 static long uvio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
0204 {
0205     void __user *argp = (void __user *)arg;
0206     struct uvio_ioctl_cb uv_ioctl = { };
0207     long ret;
0208 
0209     switch (cmd) {
0210     case UVIO_IOCTL_ATT:
0211         ret = uvio_copy_and_check_ioctl(&uv_ioctl, argp);
0212         if (ret)
0213             return ret;
0214         ret = uvio_attestation(&uv_ioctl);
0215         break;
0216     default:
0217         ret = -ENOIOCTLCMD;
0218         break;
0219     }
0220     if (ret)
0221         return ret;
0222 
0223     if (copy_to_user(argp, &uv_ioctl, sizeof(uv_ioctl)))
0224         ret = -EFAULT;
0225 
0226     return ret;
0227 }
0228 
0229 static const struct file_operations uvio_dev_fops = {
0230     .owner = THIS_MODULE,
0231     .unlocked_ioctl = uvio_ioctl,
0232     .llseek = no_llseek,
0233 };
0234 
0235 static struct miscdevice uvio_dev_miscdev = {
0236     .minor = MISC_DYNAMIC_MINOR,
0237     .name = UVIO_DEVICE_NAME,
0238     .fops = &uvio_dev_fops,
0239 };
0240 
0241 static void __exit uvio_dev_exit(void)
0242 {
0243     misc_deregister(&uvio_dev_miscdev);
0244 }
0245 
0246 static int __init uvio_dev_init(void)
0247 {
0248     return misc_register(&uvio_dev_miscdev);
0249 }
0250 
0251 module_cpu_feature_match(S390_CPU_FEATURE_UV, uvio_dev_init);
0252 module_exit(uvio_dev_exit);
0253 
0254 MODULE_AUTHOR("IBM Corporation");
0255 MODULE_LICENSE("GPL");
0256 MODULE_DESCRIPTION("Ultravisor UAPI driver");