diff options
Diffstat (limited to 'drivers/firmware/efi/test/efi_test.c')
| -rw-r--r-- | drivers/firmware/efi/test/efi_test.c | 72 |
1 files changed, 59 insertions, 13 deletions
diff --git a/drivers/firmware/efi/test/efi_test.c b/drivers/firmware/efi/test/efi_test.c index 08129b7b80ab..77b5f7ac3e20 100644 --- a/drivers/firmware/efi/test/efi_test.c +++ b/drivers/firmware/efi/test/efi_test.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * EFI Test Driver for Runtime Services * @@ -13,6 +14,7 @@ #include <linux/init.h> #include <linux/proc_fs.h> #include <linux/efi.h> +#include <linux/security.h> #include <linux/slab.h> #include <linux/uaccess.h> @@ -68,9 +70,6 @@ copy_ucs2_from_user_len(efi_char16_t **dst, efi_char16_t __user *src, return 0; } - if (!access_ok(VERIFY_READ, src, 1)) - return -EFAULT; - buf = memdup_user(src, len); if (IS_ERR(buf)) { *dst = NULL; @@ -89,9 +88,6 @@ copy_ucs2_from_user_len(efi_char16_t **dst, efi_char16_t __user *src, static inline int get_ucs2_strsize_from_user(efi_char16_t __user *src, size_t *len) { - if (!access_ok(VERIFY_READ, src, 1)) - return -EFAULT; - *len = user_ucs2_strsize(src); if (*len == 0) return -EFAULT; @@ -116,9 +112,6 @@ copy_ucs2_from_user(efi_char16_t **dst, efi_char16_t __user *src) { size_t len; - if (!access_ok(VERIFY_READ, src, 1)) - return -EFAULT; - len = user_ucs2_strsize(src); if (len == 0) return -EFAULT; @@ -140,9 +133,6 @@ copy_ucs2_to_user_len(efi_char16_t __user *dst, efi_char16_t *src, size_t len) if (!src) return 0; - if (!access_ok(VERIFY_WRITE, dst, 1)) - return -EFAULT; - return copy_to_user(dst, src, len); } @@ -371,6 +361,10 @@ static long efi_runtime_get_waketime(unsigned long arg) getwakeuptime.enabled)) return -EFAULT; + if (getwakeuptime.pending && put_user(pending, + getwakeuptime.pending)) + return -EFAULT; + if (getwakeuptime.time) { if (copy_to_user(getwakeuptime.time, &efi_time, sizeof(efi_time_t))) @@ -542,6 +536,30 @@ static long efi_runtime_get_nexthighmonocount(unsigned long arg) return 0; } +static long efi_runtime_reset_system(unsigned long arg) +{ + struct efi_resetsystem __user *resetsystem_user; + struct efi_resetsystem resetsystem; + void *data = NULL; + + resetsystem_user = (struct efi_resetsystem __user *)arg; + if (copy_from_user(&resetsystem, resetsystem_user, + sizeof(resetsystem))) + return -EFAULT; + if (resetsystem.data_size != 0) { + data = memdup_user((void *)resetsystem.data, + resetsystem.data_size); + if (IS_ERR(data)) + return PTR_ERR(data); + } + + efi.reset_system(resetsystem.reset_type, resetsystem.status, + resetsystem.data_size, (efi_char16_t *)data); + + kfree(data); + return 0; +} + static long efi_runtime_query_variableinfo(unsigned long arg) { struct efi_queryvariableinfo __user *queryvariableinfo_user; @@ -593,6 +611,9 @@ static long efi_runtime_query_capsulecaps(unsigned long arg) if (copy_from_user(&qcaps, qcaps_user, sizeof(qcaps))) return -EFAULT; + if (qcaps.capsule_count == ULONG_MAX) + return -EINVAL; + capsules = kcalloc(qcaps.capsule_count + 1, sizeof(efi_capsule_header_t), GFP_KERNEL); if (!capsules) @@ -646,6 +667,19 @@ out: return rv; } +static long efi_runtime_get_supported_mask(unsigned long arg) +{ + unsigned int __user *supported_mask; + int rv = 0; + + supported_mask = (unsigned int *)arg; + + if (put_user(efi.runtime_supported_mask, supported_mask)) + rv = -EFAULT; + + return rv; +} + static long efi_test_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -679,6 +713,12 @@ static long efi_test_ioctl(struct file *file, unsigned int cmd, case EFI_RUNTIME_QUERY_CAPSULECAPABILITIES: return efi_runtime_query_capsulecaps(arg); + + case EFI_RUNTIME_RESET_SYSTEM: + return efi_runtime_reset_system(arg); + + case EFI_RUNTIME_GET_SUPPORTED_MASK: + return efi_runtime_get_supported_mask(arg); } return -ENOTTY; @@ -686,6 +726,13 @@ static long efi_test_ioctl(struct file *file, unsigned int cmd, static int efi_test_open(struct inode *inode, struct file *file) { + int ret = security_locked_down(LOCKDOWN_EFI_TEST); + + if (ret) + return ret; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; /* * nothing special to do here * We do accept multiple open files at the same time as we @@ -707,7 +754,6 @@ static const struct file_operations efi_test_fops = { .unlocked_ioctl = efi_test_ioctl, .open = efi_test_open, .release = efi_test_close, - .llseek = no_llseek, }; static struct miscdevice efi_test_dev = { |
