efi_test.c (17791B)
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * EFI Test Driver for Runtime Services 4 * 5 * Copyright(C) 2012-2016 Canonical Ltd. 6 * 7 * This driver exports EFI runtime services interfaces into userspace, which 8 * allow to use and test UEFI runtime services provided by firmware. 9 * 10 */ 11 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/security.h> 18#include <linux/slab.h> 19#include <linux/uaccess.h> 20 21#include "efi_test.h" 22 23MODULE_AUTHOR("Ivan Hu <ivan.hu@canonical.com>"); 24MODULE_DESCRIPTION("EFI Test Driver"); 25MODULE_LICENSE("GPL"); 26 27/* 28 * Count the bytes in 'str', including the terminating NULL. 29 * 30 * Note this function returns the number of *bytes*, not the number of 31 * ucs2 characters. 32 */ 33static inline size_t user_ucs2_strsize(efi_char16_t __user *str) 34{ 35 efi_char16_t *s = str, c; 36 size_t len; 37 38 if (!str) 39 return 0; 40 41 /* Include terminating NULL */ 42 len = sizeof(efi_char16_t); 43 44 if (get_user(c, s++)) { 45 /* Can't read userspace memory for size */ 46 return 0; 47 } 48 49 while (c != 0) { 50 if (get_user(c, s++)) { 51 /* Can't read userspace memory for size */ 52 return 0; 53 } 54 len += sizeof(efi_char16_t); 55 } 56 return len; 57} 58 59/* 60 * Allocate a buffer and copy a ucs2 string from user space into it. 61 */ 62static inline int 63copy_ucs2_from_user_len(efi_char16_t **dst, efi_char16_t __user *src, 64 size_t len) 65{ 66 efi_char16_t *buf; 67 68 if (!src) { 69 *dst = NULL; 70 return 0; 71 } 72 73 buf = memdup_user(src, len); 74 if (IS_ERR(buf)) { 75 *dst = NULL; 76 return PTR_ERR(buf); 77 } 78 *dst = buf; 79 80 return 0; 81} 82 83/* 84 * Count the bytes in 'str', including the terminating NULL. 85 * 86 * Just a wrap for user_ucs2_strsize 87 */ 88static inline int 89get_ucs2_strsize_from_user(efi_char16_t __user *src, size_t *len) 90{ 91 *len = user_ucs2_strsize(src); 92 if (*len == 0) 93 return -EFAULT; 94 95 return 0; 96} 97 98/* 99 * Calculate the required buffer allocation size and copy a ucs2 string 100 * from user space into it. 101 * 102 * This function differs from copy_ucs2_from_user_len() because it 103 * calculates the size of the buffer to allocate by taking the length of 104 * the string 'src'. 105 * 106 * If a non-zero value is returned, the caller MUST NOT access 'dst'. 107 * 108 * It is the caller's responsibility to free 'dst'. 109 */ 110static inline int 111copy_ucs2_from_user(efi_char16_t **dst, efi_char16_t __user *src) 112{ 113 size_t len; 114 115 len = user_ucs2_strsize(src); 116 if (len == 0) 117 return -EFAULT; 118 return copy_ucs2_from_user_len(dst, src, len); 119} 120 121/* 122 * Copy a ucs2 string to a user buffer. 123 * 124 * This function is a simple wrapper around copy_to_user() that does 125 * nothing if 'src' is NULL, which is useful for reducing the amount of 126 * NULL checking the caller has to do. 127 * 128 * 'len' specifies the number of bytes to copy. 129 */ 130static inline int 131copy_ucs2_to_user_len(efi_char16_t __user *dst, efi_char16_t *src, size_t len) 132{ 133 if (!src) 134 return 0; 135 136 return copy_to_user(dst, src, len); 137} 138 139static long efi_runtime_get_variable(unsigned long arg) 140{ 141 struct efi_getvariable __user *getvariable_user; 142 struct efi_getvariable getvariable; 143 unsigned long datasize = 0, prev_datasize, *dz; 144 efi_guid_t vendor_guid, *vd = NULL; 145 efi_status_t status; 146 efi_char16_t *name = NULL; 147 u32 attr, *at; 148 void *data = NULL; 149 int rv = 0; 150 151 getvariable_user = (struct efi_getvariable __user *)arg; 152 153 if (copy_from_user(&getvariable, getvariable_user, 154 sizeof(getvariable))) 155 return -EFAULT; 156 if (getvariable.data_size && 157 get_user(datasize, getvariable.data_size)) 158 return -EFAULT; 159 if (getvariable.vendor_guid) { 160 if (copy_from_user(&vendor_guid, getvariable.vendor_guid, 161 sizeof(vendor_guid))) 162 return -EFAULT; 163 vd = &vendor_guid; 164 } 165 166 if (getvariable.variable_name) { 167 rv = copy_ucs2_from_user(&name, getvariable.variable_name); 168 if (rv) 169 return rv; 170 } 171 172 at = getvariable.attributes ? &attr : NULL; 173 dz = getvariable.data_size ? &datasize : NULL; 174 175 if (getvariable.data_size && getvariable.data) { 176 data = kmalloc(datasize, GFP_KERNEL); 177 if (!data) { 178 kfree(name); 179 return -ENOMEM; 180 } 181 } 182 183 prev_datasize = datasize; 184 status = efi.get_variable(name, vd, at, dz, data); 185 kfree(name); 186 187 if (put_user(status, getvariable.status)) { 188 rv = -EFAULT; 189 goto out; 190 } 191 192 if (status != EFI_SUCCESS) { 193 if (status == EFI_BUFFER_TOO_SMALL) { 194 if (dz && put_user(datasize, getvariable.data_size)) { 195 rv = -EFAULT; 196 goto out; 197 } 198 } 199 rv = -EINVAL; 200 goto out; 201 } 202 203 if (prev_datasize < datasize) { 204 rv = -EINVAL; 205 goto out; 206 } 207 208 if (data) { 209 if (copy_to_user(getvariable.data, data, datasize)) { 210 rv = -EFAULT; 211 goto out; 212 } 213 } 214 215 if (at && put_user(attr, getvariable.attributes)) { 216 rv = -EFAULT; 217 goto out; 218 } 219 220 if (dz && put_user(datasize, getvariable.data_size)) 221 rv = -EFAULT; 222 223out: 224 kfree(data); 225 return rv; 226 227} 228 229static long efi_runtime_set_variable(unsigned long arg) 230{ 231 struct efi_setvariable __user *setvariable_user; 232 struct efi_setvariable setvariable; 233 efi_guid_t vendor_guid; 234 efi_status_t status; 235 efi_char16_t *name = NULL; 236 void *data; 237 int rv = 0; 238 239 setvariable_user = (struct efi_setvariable __user *)arg; 240 241 if (copy_from_user(&setvariable, setvariable_user, sizeof(setvariable))) 242 return -EFAULT; 243 if (copy_from_user(&vendor_guid, setvariable.vendor_guid, 244 sizeof(vendor_guid))) 245 return -EFAULT; 246 247 if (setvariable.variable_name) { 248 rv = copy_ucs2_from_user(&name, setvariable.variable_name); 249 if (rv) 250 return rv; 251 } 252 253 data = memdup_user(setvariable.data, setvariable.data_size); 254 if (IS_ERR(data)) { 255 kfree(name); 256 return PTR_ERR(data); 257 } 258 259 status = efi.set_variable(name, &vendor_guid, 260 setvariable.attributes, 261 setvariable.data_size, data); 262 263 if (put_user(status, setvariable.status)) { 264 rv = -EFAULT; 265 goto out; 266 } 267 268 rv = status == EFI_SUCCESS ? 0 : -EINVAL; 269 270out: 271 kfree(data); 272 kfree(name); 273 274 return rv; 275} 276 277static long efi_runtime_get_time(unsigned long arg) 278{ 279 struct efi_gettime __user *gettime_user; 280 struct efi_gettime gettime; 281 efi_status_t status; 282 efi_time_cap_t cap; 283 efi_time_t efi_time; 284 285 gettime_user = (struct efi_gettime __user *)arg; 286 if (copy_from_user(&gettime, gettime_user, sizeof(gettime))) 287 return -EFAULT; 288 289 status = efi.get_time(gettime.time ? &efi_time : NULL, 290 gettime.capabilities ? &cap : NULL); 291 292 if (put_user(status, gettime.status)) 293 return -EFAULT; 294 295 if (status != EFI_SUCCESS) 296 return -EINVAL; 297 298 if (gettime.capabilities) { 299 efi_time_cap_t __user *cap_local; 300 301 cap_local = (efi_time_cap_t *)gettime.capabilities; 302 if (put_user(cap.resolution, &(cap_local->resolution)) || 303 put_user(cap.accuracy, &(cap_local->accuracy)) || 304 put_user(cap.sets_to_zero, &(cap_local->sets_to_zero))) 305 return -EFAULT; 306 } 307 if (gettime.time) { 308 if (copy_to_user(gettime.time, &efi_time, sizeof(efi_time_t))) 309 return -EFAULT; 310 } 311 312 return 0; 313} 314 315static long efi_runtime_set_time(unsigned long arg) 316{ 317 struct efi_settime __user *settime_user; 318 struct efi_settime settime; 319 efi_status_t status; 320 efi_time_t efi_time; 321 322 settime_user = (struct efi_settime __user *)arg; 323 if (copy_from_user(&settime, settime_user, sizeof(settime))) 324 return -EFAULT; 325 if (copy_from_user(&efi_time, settime.time, 326 sizeof(efi_time_t))) 327 return -EFAULT; 328 status = efi.set_time(&efi_time); 329 330 if (put_user(status, settime.status)) 331 return -EFAULT; 332 333 return status == EFI_SUCCESS ? 0 : -EINVAL; 334} 335 336static long efi_runtime_get_waketime(unsigned long arg) 337{ 338 struct efi_getwakeuptime __user *getwakeuptime_user; 339 struct efi_getwakeuptime getwakeuptime; 340 efi_bool_t enabled, pending; 341 efi_status_t status; 342 efi_time_t efi_time; 343 344 getwakeuptime_user = (struct efi_getwakeuptime __user *)arg; 345 if (copy_from_user(&getwakeuptime, getwakeuptime_user, 346 sizeof(getwakeuptime))) 347 return -EFAULT; 348 349 status = efi.get_wakeup_time( 350 getwakeuptime.enabled ? (efi_bool_t *)&enabled : NULL, 351 getwakeuptime.pending ? (efi_bool_t *)&pending : NULL, 352 getwakeuptime.time ? &efi_time : NULL); 353 354 if (put_user(status, getwakeuptime.status)) 355 return -EFAULT; 356 357 if (status != EFI_SUCCESS) 358 return -EINVAL; 359 360 if (getwakeuptime.enabled && put_user(enabled, 361 getwakeuptime.enabled)) 362 return -EFAULT; 363 364 if (getwakeuptime.time) { 365 if (copy_to_user(getwakeuptime.time, &efi_time, 366 sizeof(efi_time_t))) 367 return -EFAULT; 368 } 369 370 return 0; 371} 372 373static long efi_runtime_set_waketime(unsigned long arg) 374{ 375 struct efi_setwakeuptime __user *setwakeuptime_user; 376 struct efi_setwakeuptime setwakeuptime; 377 efi_bool_t enabled; 378 efi_status_t status; 379 efi_time_t efi_time; 380 381 setwakeuptime_user = (struct efi_setwakeuptime __user *)arg; 382 383 if (copy_from_user(&setwakeuptime, setwakeuptime_user, 384 sizeof(setwakeuptime))) 385 return -EFAULT; 386 387 enabled = setwakeuptime.enabled; 388 if (setwakeuptime.time) { 389 if (copy_from_user(&efi_time, setwakeuptime.time, 390 sizeof(efi_time_t))) 391 return -EFAULT; 392 393 status = efi.set_wakeup_time(enabled, &efi_time); 394 } else 395 status = efi.set_wakeup_time(enabled, NULL); 396 397 if (put_user(status, setwakeuptime.status)) 398 return -EFAULT; 399 400 return status == EFI_SUCCESS ? 0 : -EINVAL; 401} 402 403static long efi_runtime_get_nextvariablename(unsigned long arg) 404{ 405 struct efi_getnextvariablename __user *getnextvariablename_user; 406 struct efi_getnextvariablename getnextvariablename; 407 unsigned long name_size, prev_name_size = 0, *ns = NULL; 408 efi_status_t status; 409 efi_guid_t *vd = NULL; 410 efi_guid_t vendor_guid; 411 efi_char16_t *name = NULL; 412 int rv = 0; 413 414 getnextvariablename_user = (struct efi_getnextvariablename __user *)arg; 415 416 if (copy_from_user(&getnextvariablename, getnextvariablename_user, 417 sizeof(getnextvariablename))) 418 return -EFAULT; 419 420 if (getnextvariablename.variable_name_size) { 421 if (get_user(name_size, getnextvariablename.variable_name_size)) 422 return -EFAULT; 423 ns = &name_size; 424 prev_name_size = name_size; 425 } 426 427 if (getnextvariablename.vendor_guid) { 428 if (copy_from_user(&vendor_guid, 429 getnextvariablename.vendor_guid, 430 sizeof(vendor_guid))) 431 return -EFAULT; 432 vd = &vendor_guid; 433 } 434 435 if (getnextvariablename.variable_name) { 436 size_t name_string_size = 0; 437 438 rv = get_ucs2_strsize_from_user( 439 getnextvariablename.variable_name, 440 &name_string_size); 441 if (rv) 442 return rv; 443 /* 444 * The name_size may be smaller than the real buffer size where 445 * variable name located in some use cases. The most typical 446 * case is passing a 0 to get the required buffer size for the 447 * 1st time call. So we need to copy the content from user 448 * space for at least the string size of variable name, or else 449 * the name passed to UEFI may not be terminated as we expected. 450 */ 451 rv = copy_ucs2_from_user_len(&name, 452 getnextvariablename.variable_name, 453 prev_name_size > name_string_size ? 454 prev_name_size : name_string_size); 455 if (rv) 456 return rv; 457 } 458 459 status = efi.get_next_variable(ns, name, vd); 460 461 if (put_user(status, getnextvariablename.status)) { 462 rv = -EFAULT; 463 goto out; 464 } 465 466 if (status != EFI_SUCCESS) { 467 if (status == EFI_BUFFER_TOO_SMALL) { 468 if (ns && put_user(*ns, 469 getnextvariablename.variable_name_size)) { 470 rv = -EFAULT; 471 goto out; 472 } 473 } 474 rv = -EINVAL; 475 goto out; 476 } 477 478 if (name) { 479 if (copy_ucs2_to_user_len(getnextvariablename.variable_name, 480 name, prev_name_size)) { 481 rv = -EFAULT; 482 goto out; 483 } 484 } 485 486 if (ns) { 487 if (put_user(*ns, getnextvariablename.variable_name_size)) { 488 rv = -EFAULT; 489 goto out; 490 } 491 } 492 493 if (vd) { 494 if (copy_to_user(getnextvariablename.vendor_guid, vd, 495 sizeof(efi_guid_t))) 496 rv = -EFAULT; 497 } 498 499out: 500 kfree(name); 501 return rv; 502} 503 504static long efi_runtime_get_nexthighmonocount(unsigned long arg) 505{ 506 struct efi_getnexthighmonotoniccount __user *getnexthighmonocount_user; 507 struct efi_getnexthighmonotoniccount getnexthighmonocount; 508 efi_status_t status; 509 u32 count; 510 511 getnexthighmonocount_user = (struct 512 efi_getnexthighmonotoniccount __user *)arg; 513 514 if (copy_from_user(&getnexthighmonocount, 515 getnexthighmonocount_user, 516 sizeof(getnexthighmonocount))) 517 return -EFAULT; 518 519 status = efi.get_next_high_mono_count( 520 getnexthighmonocount.high_count ? &count : NULL); 521 522 if (put_user(status, getnexthighmonocount.status)) 523 return -EFAULT; 524 525 if (status != EFI_SUCCESS) 526 return -EINVAL; 527 528 if (getnexthighmonocount.high_count && 529 put_user(count, getnexthighmonocount.high_count)) 530 return -EFAULT; 531 532 return 0; 533} 534 535static long efi_runtime_reset_system(unsigned long arg) 536{ 537 struct efi_resetsystem __user *resetsystem_user; 538 struct efi_resetsystem resetsystem; 539 void *data = NULL; 540 541 resetsystem_user = (struct efi_resetsystem __user *)arg; 542 if (copy_from_user(&resetsystem, resetsystem_user, 543 sizeof(resetsystem))) 544 return -EFAULT; 545 if (resetsystem.data_size != 0) { 546 data = memdup_user((void *)resetsystem.data, 547 resetsystem.data_size); 548 if (IS_ERR(data)) 549 return PTR_ERR(data); 550 } 551 552 efi.reset_system(resetsystem.reset_type, resetsystem.status, 553 resetsystem.data_size, (efi_char16_t *)data); 554 555 kfree(data); 556 return 0; 557} 558 559static long efi_runtime_query_variableinfo(unsigned long arg) 560{ 561 struct efi_queryvariableinfo __user *queryvariableinfo_user; 562 struct efi_queryvariableinfo queryvariableinfo; 563 efi_status_t status; 564 u64 max_storage, remaining, max_size; 565 566 queryvariableinfo_user = (struct efi_queryvariableinfo __user *)arg; 567 568 if (copy_from_user(&queryvariableinfo, queryvariableinfo_user, 569 sizeof(queryvariableinfo))) 570 return -EFAULT; 571 572 status = efi.query_variable_info(queryvariableinfo.attributes, 573 &max_storage, &remaining, &max_size); 574 575 if (put_user(status, queryvariableinfo.status)) 576 return -EFAULT; 577 578 if (status != EFI_SUCCESS) 579 return -EINVAL; 580 581 if (put_user(max_storage, 582 queryvariableinfo.maximum_variable_storage_size)) 583 return -EFAULT; 584 585 if (put_user(remaining, 586 queryvariableinfo.remaining_variable_storage_size)) 587 return -EFAULT; 588 589 if (put_user(max_size, queryvariableinfo.maximum_variable_size)) 590 return -EFAULT; 591 592 return 0; 593} 594 595static long efi_runtime_query_capsulecaps(unsigned long arg) 596{ 597 struct efi_querycapsulecapabilities __user *qcaps_user; 598 struct efi_querycapsulecapabilities qcaps; 599 efi_capsule_header_t *capsules; 600 efi_status_t status; 601 u64 max_size; 602 int i, reset_type; 603 int rv = 0; 604 605 qcaps_user = (struct efi_querycapsulecapabilities __user *)arg; 606 607 if (copy_from_user(&qcaps, qcaps_user, sizeof(qcaps))) 608 return -EFAULT; 609 610 if (qcaps.capsule_count == ULONG_MAX) 611 return -EINVAL; 612 613 capsules = kcalloc(qcaps.capsule_count + 1, 614 sizeof(efi_capsule_header_t), GFP_KERNEL); 615 if (!capsules) 616 return -ENOMEM; 617 618 for (i = 0; i < qcaps.capsule_count; i++) { 619 efi_capsule_header_t *c; 620 /* 621 * We cannot dereference qcaps.capsule_header_array directly to 622 * obtain the address of the capsule as it resides in the 623 * user space 624 */ 625 if (get_user(c, qcaps.capsule_header_array + i)) { 626 rv = -EFAULT; 627 goto out; 628 } 629 if (copy_from_user(&capsules[i], c, 630 sizeof(efi_capsule_header_t))) { 631 rv = -EFAULT; 632 goto out; 633 } 634 } 635 636 qcaps.capsule_header_array = &capsules; 637 638 status = efi.query_capsule_caps((efi_capsule_header_t **) 639 qcaps.capsule_header_array, 640 qcaps.capsule_count, 641 &max_size, &reset_type); 642 643 if (put_user(status, qcaps.status)) { 644 rv = -EFAULT; 645 goto out; 646 } 647 648 if (status != EFI_SUCCESS) { 649 rv = -EINVAL; 650 goto out; 651 } 652 653 if (put_user(max_size, qcaps.maximum_capsule_size)) { 654 rv = -EFAULT; 655 goto out; 656 } 657 658 if (put_user(reset_type, qcaps.reset_type)) 659 rv = -EFAULT; 660 661out: 662 kfree(capsules); 663 return rv; 664} 665 666static long efi_runtime_get_supported_mask(unsigned long arg) 667{ 668 unsigned int __user *supported_mask; 669 int rv = 0; 670 671 supported_mask = (unsigned int *)arg; 672 673 if (put_user(efi.runtime_supported_mask, supported_mask)) 674 rv = -EFAULT; 675 676 return rv; 677} 678 679static long efi_test_ioctl(struct file *file, unsigned int cmd, 680 unsigned long arg) 681{ 682 switch (cmd) { 683 case EFI_RUNTIME_GET_VARIABLE: 684 return efi_runtime_get_variable(arg); 685 686 case EFI_RUNTIME_SET_VARIABLE: 687 return efi_runtime_set_variable(arg); 688 689 case EFI_RUNTIME_GET_TIME: 690 return efi_runtime_get_time(arg); 691 692 case EFI_RUNTIME_SET_TIME: 693 return efi_runtime_set_time(arg); 694 695 case EFI_RUNTIME_GET_WAKETIME: 696 return efi_runtime_get_waketime(arg); 697 698 case EFI_RUNTIME_SET_WAKETIME: 699 return efi_runtime_set_waketime(arg); 700 701 case EFI_RUNTIME_GET_NEXTVARIABLENAME: 702 return efi_runtime_get_nextvariablename(arg); 703 704 case EFI_RUNTIME_GET_NEXTHIGHMONOTONICCOUNT: 705 return efi_runtime_get_nexthighmonocount(arg); 706 707 case EFI_RUNTIME_QUERY_VARIABLEINFO: 708 return efi_runtime_query_variableinfo(arg); 709 710 case EFI_RUNTIME_QUERY_CAPSULECAPABILITIES: 711 return efi_runtime_query_capsulecaps(arg); 712 713 case EFI_RUNTIME_RESET_SYSTEM: 714 return efi_runtime_reset_system(arg); 715 716 case EFI_RUNTIME_GET_SUPPORTED_MASK: 717 return efi_runtime_get_supported_mask(arg); 718 } 719 720 return -ENOTTY; 721} 722 723static int efi_test_open(struct inode *inode, struct file *file) 724{ 725 int ret = security_locked_down(LOCKDOWN_EFI_TEST); 726 727 if (ret) 728 return ret; 729 730 if (!capable(CAP_SYS_ADMIN)) 731 return -EACCES; 732 /* 733 * nothing special to do here 734 * We do accept multiple open files at the same time as we 735 * synchronize on the per call operation. 736 */ 737 return 0; 738} 739 740static int efi_test_close(struct inode *inode, struct file *file) 741{ 742 return 0; 743} 744 745/* 746 * The various file operations we support. 747 */ 748static const struct file_operations efi_test_fops = { 749 .owner = THIS_MODULE, 750 .unlocked_ioctl = efi_test_ioctl, 751 .open = efi_test_open, 752 .release = efi_test_close, 753 .llseek = no_llseek, 754}; 755 756static struct miscdevice efi_test_dev = { 757 MISC_DYNAMIC_MINOR, 758 "efi_test", 759 &efi_test_fops 760}; 761 762static int __init efi_test_init(void) 763{ 764 int ret; 765 766 ret = misc_register(&efi_test_dev); 767 if (ret) { 768 pr_err("efi_test: can't misc_register on minor=%d\n", 769 MISC_DYNAMIC_MINOR); 770 return ret; 771 } 772 773 return 0; 774} 775 776static void __exit efi_test_exit(void) 777{ 778 misc_deregister(&efi_test_dev); 779} 780 781module_init(efi_test_init); 782module_exit(efi_test_exit);