1 // SPDX-License-Identifier: GPL-2.0+
3 * EFI Test Driver for Runtime Services
5 * Copyright(C) 2012-2016 Canonical Ltd.
7 * This driver exports EFI runtime services interfaces into userspace, which
8 * allow to use and test UEFI runtime services provided by firmware.
12 #include <linux/miscdevice.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/proc_fs.h>
16 #include <linux/efi.h>
17 #include <linux/slab.h>
18 #include <linux/uaccess.h>
22 MODULE_AUTHOR("Ivan Hu <ivan.hu@canonical.com>");
23 MODULE_DESCRIPTION("EFI Test Driver");
24 MODULE_LICENSE("GPL");
27 * Count the bytes in 'str', including the terminating NULL.
29 * Note this function returns the number of *bytes*, not the number of
32 static inline size_t user_ucs2_strsize(efi_char16_t __user
*str
)
34 efi_char16_t
*s
= str
, c
;
40 /* Include terminating NULL */
41 len
= sizeof(efi_char16_t
);
43 if (get_user(c
, s
++)) {
44 /* Can't read userspace memory for size */
49 if (get_user(c
, s
++)) {
50 /* Can't read userspace memory for size */
53 len
+= sizeof(efi_char16_t
);
59 * Allocate a buffer and copy a ucs2 string from user space into it.
62 copy_ucs2_from_user_len(efi_char16_t
**dst
, efi_char16_t __user
*src
,
72 if (!access_ok(src
, 1))
75 buf
= memdup_user(src
, len
);
86 * Count the bytes in 'str', including the terminating NULL.
88 * Just a wrap for user_ucs2_strsize
91 get_ucs2_strsize_from_user(efi_char16_t __user
*src
, size_t *len
)
93 if (!access_ok(src
, 1))
96 *len
= user_ucs2_strsize(src
);
104 * Calculate the required buffer allocation size and copy a ucs2 string
105 * from user space into it.
107 * This function differs from copy_ucs2_from_user_len() because it
108 * calculates the size of the buffer to allocate by taking the length of
111 * If a non-zero value is returned, the caller MUST NOT access 'dst'.
113 * It is the caller's responsibility to free 'dst'.
116 copy_ucs2_from_user(efi_char16_t
**dst
, efi_char16_t __user
*src
)
120 if (!access_ok(src
, 1))
123 len
= user_ucs2_strsize(src
);
126 return copy_ucs2_from_user_len(dst
, src
, len
);
130 * Copy a ucs2 string to a user buffer.
132 * This function is a simple wrapper around copy_to_user() that does
133 * nothing if 'src' is NULL, which is useful for reducing the amount of
134 * NULL checking the caller has to do.
136 * 'len' specifies the number of bytes to copy.
139 copy_ucs2_to_user_len(efi_char16_t __user
*dst
, efi_char16_t
*src
, size_t len
)
144 if (!access_ok(dst
, 1))
147 return copy_to_user(dst
, src
, len
);
150 static long efi_runtime_get_variable(unsigned long arg
)
152 struct efi_getvariable __user
*getvariable_user
;
153 struct efi_getvariable getvariable
;
154 unsigned long datasize
= 0, prev_datasize
, *dz
;
155 efi_guid_t vendor_guid
, *vd
= NULL
;
157 efi_char16_t
*name
= NULL
;
162 getvariable_user
= (struct efi_getvariable __user
*)arg
;
164 if (copy_from_user(&getvariable
, getvariable_user
,
165 sizeof(getvariable
)))
167 if (getvariable
.data_size
&&
168 get_user(datasize
, getvariable
.data_size
))
170 if (getvariable
.vendor_guid
) {
171 if (copy_from_user(&vendor_guid
, getvariable
.vendor_guid
,
172 sizeof(vendor_guid
)))
177 if (getvariable
.variable_name
) {
178 rv
= copy_ucs2_from_user(&name
, getvariable
.variable_name
);
183 at
= getvariable
.attributes
? &attr
: NULL
;
184 dz
= getvariable
.data_size
? &datasize
: NULL
;
186 if (getvariable
.data_size
&& getvariable
.data
) {
187 data
= kmalloc(datasize
, GFP_KERNEL
);
194 prev_datasize
= datasize
;
195 status
= efi
.get_variable(name
, vd
, at
, dz
, data
);
198 if (put_user(status
, getvariable
.status
)) {
203 if (status
!= EFI_SUCCESS
) {
204 if (status
== EFI_BUFFER_TOO_SMALL
) {
205 if (dz
&& put_user(datasize
, getvariable
.data_size
)) {
214 if (prev_datasize
< datasize
) {
220 if (copy_to_user(getvariable
.data
, data
, datasize
)) {
226 if (at
&& put_user(attr
, getvariable
.attributes
)) {
231 if (dz
&& put_user(datasize
, getvariable
.data_size
))
240 static long efi_runtime_set_variable(unsigned long arg
)
242 struct efi_setvariable __user
*setvariable_user
;
243 struct efi_setvariable setvariable
;
244 efi_guid_t vendor_guid
;
246 efi_char16_t
*name
= NULL
;
250 setvariable_user
= (struct efi_setvariable __user
*)arg
;
252 if (copy_from_user(&setvariable
, setvariable_user
, sizeof(setvariable
)))
254 if (copy_from_user(&vendor_guid
, setvariable
.vendor_guid
,
255 sizeof(vendor_guid
)))
258 if (setvariable
.variable_name
) {
259 rv
= copy_ucs2_from_user(&name
, setvariable
.variable_name
);
264 data
= memdup_user(setvariable
.data
, setvariable
.data_size
);
267 return PTR_ERR(data
);
270 status
= efi
.set_variable(name
, &vendor_guid
,
271 setvariable
.attributes
,
272 setvariable
.data_size
, data
);
274 if (put_user(status
, setvariable
.status
)) {
279 rv
= status
== EFI_SUCCESS
? 0 : -EINVAL
;
288 static long efi_runtime_get_time(unsigned long arg
)
290 struct efi_gettime __user
*gettime_user
;
291 struct efi_gettime gettime
;
296 gettime_user
= (struct efi_gettime __user
*)arg
;
297 if (copy_from_user(&gettime
, gettime_user
, sizeof(gettime
)))
300 status
= efi
.get_time(gettime
.time
? &efi_time
: NULL
,
301 gettime
.capabilities
? &cap
: NULL
);
303 if (put_user(status
, gettime
.status
))
306 if (status
!= EFI_SUCCESS
)
309 if (gettime
.capabilities
) {
310 efi_time_cap_t __user
*cap_local
;
312 cap_local
= (efi_time_cap_t
*)gettime
.capabilities
;
313 if (put_user(cap
.resolution
, &(cap_local
->resolution
)) ||
314 put_user(cap
.accuracy
, &(cap_local
->accuracy
)) ||
315 put_user(cap
.sets_to_zero
, &(cap_local
->sets_to_zero
)))
319 if (copy_to_user(gettime
.time
, &efi_time
, sizeof(efi_time_t
)))
326 static long efi_runtime_set_time(unsigned long arg
)
328 struct efi_settime __user
*settime_user
;
329 struct efi_settime settime
;
333 settime_user
= (struct efi_settime __user
*)arg
;
334 if (copy_from_user(&settime
, settime_user
, sizeof(settime
)))
336 if (copy_from_user(&efi_time
, settime
.time
,
339 status
= efi
.set_time(&efi_time
);
341 if (put_user(status
, settime
.status
))
344 return status
== EFI_SUCCESS
? 0 : -EINVAL
;
347 static long efi_runtime_get_waketime(unsigned long arg
)
349 struct efi_getwakeuptime __user
*getwakeuptime_user
;
350 struct efi_getwakeuptime getwakeuptime
;
351 efi_bool_t enabled
, pending
;
355 getwakeuptime_user
= (struct efi_getwakeuptime __user
*)arg
;
356 if (copy_from_user(&getwakeuptime
, getwakeuptime_user
,
357 sizeof(getwakeuptime
)))
360 status
= efi
.get_wakeup_time(
361 getwakeuptime
.enabled
? (efi_bool_t
*)&enabled
: NULL
,
362 getwakeuptime
.pending
? (efi_bool_t
*)&pending
: NULL
,
363 getwakeuptime
.time
? &efi_time
: NULL
);
365 if (put_user(status
, getwakeuptime
.status
))
368 if (status
!= EFI_SUCCESS
)
371 if (getwakeuptime
.enabled
&& put_user(enabled
,
372 getwakeuptime
.enabled
))
375 if (getwakeuptime
.time
) {
376 if (copy_to_user(getwakeuptime
.time
, &efi_time
,
384 static long efi_runtime_set_waketime(unsigned long arg
)
386 struct efi_setwakeuptime __user
*setwakeuptime_user
;
387 struct efi_setwakeuptime setwakeuptime
;
392 setwakeuptime_user
= (struct efi_setwakeuptime __user
*)arg
;
394 if (copy_from_user(&setwakeuptime
, setwakeuptime_user
,
395 sizeof(setwakeuptime
)))
398 enabled
= setwakeuptime
.enabled
;
399 if (setwakeuptime
.time
) {
400 if (copy_from_user(&efi_time
, setwakeuptime
.time
,
404 status
= efi
.set_wakeup_time(enabled
, &efi_time
);
406 status
= efi
.set_wakeup_time(enabled
, NULL
);
408 if (put_user(status
, setwakeuptime
.status
))
411 return status
== EFI_SUCCESS
? 0 : -EINVAL
;
414 static long efi_runtime_get_nextvariablename(unsigned long arg
)
416 struct efi_getnextvariablename __user
*getnextvariablename_user
;
417 struct efi_getnextvariablename getnextvariablename
;
418 unsigned long name_size
, prev_name_size
= 0, *ns
= NULL
;
420 efi_guid_t
*vd
= NULL
;
421 efi_guid_t vendor_guid
;
422 efi_char16_t
*name
= NULL
;
425 getnextvariablename_user
= (struct efi_getnextvariablename __user
*)arg
;
427 if (copy_from_user(&getnextvariablename
, getnextvariablename_user
,
428 sizeof(getnextvariablename
)))
431 if (getnextvariablename
.variable_name_size
) {
432 if (get_user(name_size
, getnextvariablename
.variable_name_size
))
435 prev_name_size
= name_size
;
438 if (getnextvariablename
.vendor_guid
) {
439 if (copy_from_user(&vendor_guid
,
440 getnextvariablename
.vendor_guid
,
441 sizeof(vendor_guid
)))
446 if (getnextvariablename
.variable_name
) {
447 size_t name_string_size
= 0;
449 rv
= get_ucs2_strsize_from_user(
450 getnextvariablename
.variable_name
,
455 * The name_size may be smaller than the real buffer size where
456 * variable name located in some use cases. The most typical
457 * case is passing a 0 to get the required buffer size for the
458 * 1st time call. So we need to copy the content from user
459 * space for at least the string size of variable name, or else
460 * the name passed to UEFI may not be terminated as we expected.
462 rv
= copy_ucs2_from_user_len(&name
,
463 getnextvariablename
.variable_name
,
464 prev_name_size
> name_string_size
?
465 prev_name_size
: name_string_size
);
470 status
= efi
.get_next_variable(ns
, name
, vd
);
472 if (put_user(status
, getnextvariablename
.status
)) {
477 if (status
!= EFI_SUCCESS
) {
478 if (status
== EFI_BUFFER_TOO_SMALL
) {
479 if (ns
&& put_user(*ns
,
480 getnextvariablename
.variable_name_size
)) {
490 if (copy_ucs2_to_user_len(getnextvariablename
.variable_name
,
491 name
, prev_name_size
)) {
498 if (put_user(*ns
, getnextvariablename
.variable_name_size
)) {
505 if (copy_to_user(getnextvariablename
.vendor_guid
, vd
,
515 static long efi_runtime_get_nexthighmonocount(unsigned long arg
)
517 struct efi_getnexthighmonotoniccount __user
*getnexthighmonocount_user
;
518 struct efi_getnexthighmonotoniccount getnexthighmonocount
;
522 getnexthighmonocount_user
= (struct
523 efi_getnexthighmonotoniccount __user
*)arg
;
525 if (copy_from_user(&getnexthighmonocount
,
526 getnexthighmonocount_user
,
527 sizeof(getnexthighmonocount
)))
530 status
= efi
.get_next_high_mono_count(
531 getnexthighmonocount
.high_count
? &count
: NULL
);
533 if (put_user(status
, getnexthighmonocount
.status
))
536 if (status
!= EFI_SUCCESS
)
539 if (getnexthighmonocount
.high_count
&&
540 put_user(count
, getnexthighmonocount
.high_count
))
546 static long efi_runtime_reset_system(unsigned long arg
)
548 struct efi_resetsystem __user
*resetsystem_user
;
549 struct efi_resetsystem resetsystem
;
552 resetsystem_user
= (struct efi_resetsystem __user
*)arg
;
553 if (copy_from_user(&resetsystem
, resetsystem_user
,
554 sizeof(resetsystem
)))
556 if (resetsystem
.data_size
!= 0) {
557 data
= memdup_user((void *)resetsystem
.data
,
558 resetsystem
.data_size
);
560 return PTR_ERR(data
);
563 efi
.reset_system(resetsystem
.reset_type
, resetsystem
.status
,
564 resetsystem
.data_size
, (efi_char16_t
*)data
);
570 static long efi_runtime_query_variableinfo(unsigned long arg
)
572 struct efi_queryvariableinfo __user
*queryvariableinfo_user
;
573 struct efi_queryvariableinfo queryvariableinfo
;
575 u64 max_storage
, remaining
, max_size
;
577 queryvariableinfo_user
= (struct efi_queryvariableinfo __user
*)arg
;
579 if (copy_from_user(&queryvariableinfo
, queryvariableinfo_user
,
580 sizeof(queryvariableinfo
)))
583 status
= efi
.query_variable_info(queryvariableinfo
.attributes
,
584 &max_storage
, &remaining
, &max_size
);
586 if (put_user(status
, queryvariableinfo
.status
))
589 if (status
!= EFI_SUCCESS
)
592 if (put_user(max_storage
,
593 queryvariableinfo
.maximum_variable_storage_size
))
596 if (put_user(remaining
,
597 queryvariableinfo
.remaining_variable_storage_size
))
600 if (put_user(max_size
, queryvariableinfo
.maximum_variable_size
))
606 static long efi_runtime_query_capsulecaps(unsigned long arg
)
608 struct efi_querycapsulecapabilities __user
*qcaps_user
;
609 struct efi_querycapsulecapabilities qcaps
;
610 efi_capsule_header_t
*capsules
;
616 qcaps_user
= (struct efi_querycapsulecapabilities __user
*)arg
;
618 if (copy_from_user(&qcaps
, qcaps_user
, sizeof(qcaps
)))
621 if (qcaps
.capsule_count
== ULONG_MAX
)
624 capsules
= kcalloc(qcaps
.capsule_count
+ 1,
625 sizeof(efi_capsule_header_t
), GFP_KERNEL
);
629 for (i
= 0; i
< qcaps
.capsule_count
; i
++) {
630 efi_capsule_header_t
*c
;
632 * We cannot dereference qcaps.capsule_header_array directly to
633 * obtain the address of the capsule as it resides in the
636 if (get_user(c
, qcaps
.capsule_header_array
+ i
)) {
640 if (copy_from_user(&capsules
[i
], c
,
641 sizeof(efi_capsule_header_t
))) {
647 qcaps
.capsule_header_array
= &capsules
;
649 status
= efi
.query_capsule_caps((efi_capsule_header_t
**)
650 qcaps
.capsule_header_array
,
652 &max_size
, &reset_type
);
654 if (put_user(status
, qcaps
.status
)) {
659 if (status
!= EFI_SUCCESS
) {
664 if (put_user(max_size
, qcaps
.maximum_capsule_size
)) {
669 if (put_user(reset_type
, qcaps
.reset_type
))
677 static long efi_test_ioctl(struct file
*file
, unsigned int cmd
,
681 case EFI_RUNTIME_GET_VARIABLE
:
682 return efi_runtime_get_variable(arg
);
684 case EFI_RUNTIME_SET_VARIABLE
:
685 return efi_runtime_set_variable(arg
);
687 case EFI_RUNTIME_GET_TIME
:
688 return efi_runtime_get_time(arg
);
690 case EFI_RUNTIME_SET_TIME
:
691 return efi_runtime_set_time(arg
);
693 case EFI_RUNTIME_GET_WAKETIME
:
694 return efi_runtime_get_waketime(arg
);
696 case EFI_RUNTIME_SET_WAKETIME
:
697 return efi_runtime_set_waketime(arg
);
699 case EFI_RUNTIME_GET_NEXTVARIABLENAME
:
700 return efi_runtime_get_nextvariablename(arg
);
702 case EFI_RUNTIME_GET_NEXTHIGHMONOTONICCOUNT
:
703 return efi_runtime_get_nexthighmonocount(arg
);
705 case EFI_RUNTIME_QUERY_VARIABLEINFO
:
706 return efi_runtime_query_variableinfo(arg
);
708 case EFI_RUNTIME_QUERY_CAPSULECAPABILITIES
:
709 return efi_runtime_query_capsulecaps(arg
);
711 case EFI_RUNTIME_RESET_SYSTEM
:
712 return efi_runtime_reset_system(arg
);
718 static int efi_test_open(struct inode
*inode
, struct file
*file
)
721 * nothing special to do here
722 * We do accept multiple open files at the same time as we
723 * synchronize on the per call operation.
728 static int efi_test_close(struct inode
*inode
, struct file
*file
)
734 * The various file operations we support.
736 static const struct file_operations efi_test_fops
= {
737 .owner
= THIS_MODULE
,
738 .unlocked_ioctl
= efi_test_ioctl
,
739 .open
= efi_test_open
,
740 .release
= efi_test_close
,
744 static struct miscdevice efi_test_dev
= {
750 static int __init
efi_test_init(void)
754 ret
= misc_register(&efi_test_dev
);
756 pr_err("efi_test: can't misc_register on minor=%d\n",
764 static void __exit
efi_test_exit(void)
766 misc_deregister(&efi_test_dev
);
769 module_init(efi_test_init
);
770 module_exit(efi_test_exit
);