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