1
2
3
4
5
6
7
8
9#include <linux/kernel.h>
10#include <linux/slab.h>
11#include <linux/mm_types.h>
12#include <linux/syscalls.h>
13#include <linux/sched/sysctl.h>
14
15#include <asm/insn.h>
16#include <asm/insn-eval.h>
17#include <asm/mman.h>
18#include <asm/mmu_context.h>
19#include <asm/mpx.h>
20#include <asm/processor.h>
21#include <asm/fpu/internal.h>
22
23#define CREATE_TRACE_POINTS
24#include <asm/trace/mpx.h>
25
26static inline unsigned long mpx_bd_size_bytes(struct mm_struct *mm)
27{
28 if (is_64bit_mm(mm))
29 return MPX_BD_SIZE_BYTES_64;
30 else
31 return MPX_BD_SIZE_BYTES_32;
32}
33
34static inline unsigned long mpx_bt_size_bytes(struct mm_struct *mm)
35{
36 if (is_64bit_mm(mm))
37 return MPX_BT_SIZE_BYTES_64;
38 else
39 return MPX_BT_SIZE_BYTES_32;
40}
41
42
43
44
45
46static unsigned long mpx_mmap(unsigned long len)
47{
48 struct mm_struct *mm = current->mm;
49 unsigned long addr, populate;
50
51
52 if (len != mpx_bt_size_bytes(mm))
53 return -EINVAL;
54
55 down_write(&mm->mmap_sem);
56 addr = do_mmap(NULL, 0, len, PROT_READ | PROT_WRITE,
57 MAP_ANONYMOUS | MAP_PRIVATE, VM_MPX, 0, &populate, NULL);
58 up_write(&mm->mmap_sem);
59 if (populate)
60 mm_populate(addr, populate);
61
62 return addr;
63}
64
65static int mpx_insn_decode(struct insn *insn,
66 struct pt_regs *regs)
67{
68 unsigned char buf[MAX_INSN_SIZE];
69 int x86_64 = !test_thread_flag(TIF_IA32);
70 int not_copied;
71 int nr_copied;
72
73 not_copied = copy_from_user(buf, (void __user *)regs->ip, sizeof(buf));
74 nr_copied = sizeof(buf) - not_copied;
75
76
77
78
79
80 if (!nr_copied)
81 return -EFAULT;
82 insn_init(insn, buf, nr_copied, x86_64);
83 insn_get_length(insn);
84
85
86
87
88
89
90
91
92 if (nr_copied < insn->length)
93 return -EFAULT;
94
95 insn_get_opcode(insn);
96
97
98
99
100 if (insn->opcode.bytes[0] != 0x0f)
101 goto bad_opcode;
102 if ((insn->opcode.bytes[1] != 0x1a) &&
103 (insn->opcode.bytes[1] != 0x1b))
104 goto bad_opcode;
105
106 return 0;
107bad_opcode:
108 return -EINVAL;
109}
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124siginfo_t *mpx_generate_siginfo(struct pt_regs *regs)
125{
126 const struct mpx_bndreg_state *bndregs;
127 const struct mpx_bndreg *bndreg;
128 siginfo_t *info = NULL;
129 struct insn insn;
130 uint8_t bndregno;
131 int err;
132
133 err = mpx_insn_decode(&insn, regs);
134 if (err)
135 goto err_out;
136
137
138
139
140
141 insn_get_modrm(&insn);
142 bndregno = X86_MODRM_REG(insn.modrm.value);
143 if (bndregno > 3) {
144 err = -EINVAL;
145 goto err_out;
146 }
147
148 bndregs = get_xsave_field_ptr(XFEATURE_MASK_BNDREGS);
149 if (!bndregs) {
150 err = -EINVAL;
151 goto err_out;
152 }
153
154 bndreg = &bndregs->bndreg[bndregno];
155
156 info = kzalloc(sizeof(*info), GFP_KERNEL);
157 if (!info) {
158 err = -ENOMEM;
159 goto err_out;
160 }
161
162
163
164
165
166
167
168
169
170
171 info->si_lower = (void __user *)(unsigned long)bndreg->lower_bound;
172 info->si_upper = (void __user *)(unsigned long)~bndreg->upper_bound;
173 info->si_addr_lsb = 0;
174 info->si_signo = SIGSEGV;
175 info->si_errno = 0;
176 info->si_code = SEGV_BNDERR;
177 info->si_addr = insn_get_addr_ref(&insn, regs);
178
179
180
181
182 if (info->si_addr == (void __user *)-1) {
183 err = -EINVAL;
184 goto err_out;
185 }
186 trace_mpx_bounds_register_exception(info->si_addr, bndreg);
187 return info;
188err_out:
189
190 kfree(info);
191 return ERR_PTR(err);
192}
193
194static __user void *mpx_get_bounds_dir(void)
195{
196 const struct mpx_bndcsr *bndcsr;
197
198 if (!cpu_feature_enabled(X86_FEATURE_MPX))
199 return MPX_INVALID_BOUNDS_DIR;
200
201
202
203
204
205 bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
206 if (!bndcsr)
207 return MPX_INVALID_BOUNDS_DIR;
208
209
210
211
212
213 if (!(bndcsr->bndcfgu & MPX_BNDCFG_ENABLE_FLAG))
214 return MPX_INVALID_BOUNDS_DIR;
215
216
217
218
219
220 return (void __user *)(unsigned long)
221 (bndcsr->bndcfgu & MPX_BNDCFG_ADDR_MASK);
222}
223
224int mpx_enable_management(void)
225{
226 void __user *bd_base = MPX_INVALID_BOUNDS_DIR;
227 struct mm_struct *mm = current->mm;
228 int ret = 0;
229
230
231
232
233
234
235
236
237
238
239
240
241 bd_base = mpx_get_bounds_dir();
242 down_write(&mm->mmap_sem);
243
244
245 if (find_vma(mm, DEFAULT_MAP_WINDOW)) {
246 pr_warn_once("%s (%d): MPX cannot handle addresses "
247 "above 47-bits. Disabling.",
248 current->comm, current->pid);
249 ret = -ENXIO;
250 goto out;
251 }
252 mm->context.bd_addr = bd_base;
253 if (mm->context.bd_addr == MPX_INVALID_BOUNDS_DIR)
254 ret = -ENXIO;
255out:
256 up_write(&mm->mmap_sem);
257 return ret;
258}
259
260int mpx_disable_management(void)
261{
262 struct mm_struct *mm = current->mm;
263
264 if (!cpu_feature_enabled(X86_FEATURE_MPX))
265 return -ENXIO;
266
267 down_write(&mm->mmap_sem);
268 mm->context.bd_addr = MPX_INVALID_BOUNDS_DIR;
269 up_write(&mm->mmap_sem);
270 return 0;
271}
272
273static int mpx_cmpxchg_bd_entry(struct mm_struct *mm,
274 unsigned long *curval,
275 unsigned long __user *addr,
276 unsigned long old_val, unsigned long new_val)
277{
278 int ret;
279
280
281
282
283
284
285
286 if (is_64bit_mm(mm)) {
287 ret = user_atomic_cmpxchg_inatomic(curval,
288 addr, old_val, new_val);
289 } else {
290 u32 uninitialized_var(curval_32);
291 u32 old_val_32 = old_val;
292 u32 new_val_32 = new_val;
293 u32 __user *addr_32 = (u32 __user *)addr;
294
295 ret = user_atomic_cmpxchg_inatomic(&curval_32,
296 addr_32, old_val_32, new_val_32);
297 *curval = curval_32;
298 }
299 return ret;
300}
301
302
303
304
305
306
307static int allocate_bt(struct mm_struct *mm, long __user *bd_entry)
308{
309 unsigned long expected_old_val = 0;
310 unsigned long actual_old_val = 0;
311 unsigned long bt_addr;
312 unsigned long bd_new_entry;
313 int ret = 0;
314
315
316
317
318
319 bt_addr = mpx_mmap(mpx_bt_size_bytes(mm));
320 if (IS_ERR((void *)bt_addr))
321 return PTR_ERR((void *)bt_addr);
322
323
324
325 bd_new_entry = bt_addr | MPX_BD_ENTRY_VALID_FLAG;
326
327
328
329
330
331
332
333
334
335
336
337
338 ret = mpx_cmpxchg_bd_entry(mm, &actual_old_val, bd_entry,
339 expected_old_val, bd_new_entry);
340 if (ret)
341 goto out_unmap;
342
343
344
345
346
347
348
349
350
351
352
353 if (actual_old_val & MPX_BD_ENTRY_VALID_FLAG) {
354 ret = 0;
355 goto out_unmap;
356 }
357
358
359
360
361
362
363 if (expected_old_val != actual_old_val) {
364 ret = -EINVAL;
365 goto out_unmap;
366 }
367 trace_mpx_new_bounds_table(bt_addr);
368 return 0;
369out_unmap:
370 vm_munmap(bt_addr, mpx_bt_size_bytes(mm));
371 return ret;
372}
373
374
375
376
377
378
379
380
381
382
383
384
385static int do_mpx_bt_fault(void)
386{
387 unsigned long bd_entry, bd_base;
388 const struct mpx_bndcsr *bndcsr;
389 struct mm_struct *mm = current->mm;
390
391 bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
392 if (!bndcsr)
393 return -EINVAL;
394
395
396
397 bd_base = bndcsr->bndcfgu & MPX_BNDCFG_ADDR_MASK;
398
399
400
401
402 bd_entry = bndcsr->bndstatus & MPX_BNDSTA_ADDR_MASK;
403
404
405
406
407 if ((bd_entry < bd_base) ||
408 (bd_entry >= bd_base + mpx_bd_size_bytes(mm)))
409 return -EINVAL;
410
411 return allocate_bt(mm, (long __user *)bd_entry);
412}
413
414int mpx_handle_bd_fault(void)
415{
416
417
418
419
420 if (!kernel_managing_mpx_tables(current->mm))
421 return -EINVAL;
422
423 return do_mpx_bt_fault();
424}
425
426
427
428
429
430static int mpx_resolve_fault(long __user *addr, int write)
431{
432 long gup_ret;
433 int nr_pages = 1;
434
435 gup_ret = get_user_pages((unsigned long)addr, nr_pages,
436 write ? FOLL_WRITE : 0, NULL, NULL);
437
438
439
440
441
442 if (!gup_ret)
443 return -EFAULT;
444
445 if (gup_ret < 0)
446 return gup_ret;
447
448 return 0;
449}
450
451static unsigned long mpx_bd_entry_to_bt_addr(struct mm_struct *mm,
452 unsigned long bd_entry)
453{
454 unsigned long bt_addr = bd_entry;
455 int align_to_bytes;
456
457
458
459 bt_addr &= ~MPX_BD_ENTRY_VALID_FLAG;
460
461
462
463
464
465
466 if (is_64bit_mm(mm))
467 align_to_bytes = 8;
468 else
469 align_to_bytes = 4;
470 bt_addr &= ~(align_to_bytes-1);
471 return bt_addr;
472}
473
474
475
476
477
478
479static int get_user_bd_entry(struct mm_struct *mm, unsigned long *bd_entry_ret,
480 long __user *bd_entry_ptr)
481{
482 u32 bd_entry_32;
483 int ret;
484
485 if (is_64bit_mm(mm))
486 return get_user(*bd_entry_ret, bd_entry_ptr);
487
488
489
490
491
492 ret = get_user(bd_entry_32, (u32 __user *)bd_entry_ptr);
493 *bd_entry_ret = bd_entry_32;
494 return ret;
495}
496
497
498
499
500
501static int get_bt_addr(struct mm_struct *mm,
502 long __user *bd_entry_ptr,
503 unsigned long *bt_addr_result)
504{
505 int ret;
506 int valid_bit;
507 unsigned long bd_entry;
508 unsigned long bt_addr;
509
510 if (!access_ok(VERIFY_READ, (bd_entry_ptr), sizeof(*bd_entry_ptr)))
511 return -EFAULT;
512
513 while (1) {
514 int need_write = 0;
515
516 pagefault_disable();
517 ret = get_user_bd_entry(mm, &bd_entry, bd_entry_ptr);
518 pagefault_enable();
519 if (!ret)
520 break;
521 if (ret == -EFAULT)
522 ret = mpx_resolve_fault(bd_entry_ptr, need_write);
523
524
525
526
527 if (ret)
528 return ret;
529 }
530
531 valid_bit = bd_entry & MPX_BD_ENTRY_VALID_FLAG;
532 bt_addr = mpx_bd_entry_to_bt_addr(mm, bd_entry);
533
534
535
536
537
538
539
540
541 if (!valid_bit && bt_addr)
542 return -EINVAL;
543
544
545
546
547
548
549 if (!valid_bit)
550 return -ENOENT;
551
552 *bt_addr_result = bt_addr;
553 return 0;
554}
555
556static inline int bt_entry_size_bytes(struct mm_struct *mm)
557{
558 if (is_64bit_mm(mm))
559 return MPX_BT_ENTRY_BYTES_64;
560 else
561 return MPX_BT_ENTRY_BYTES_32;
562}
563
564
565
566
567
568
569static unsigned long mpx_get_bt_entry_offset_bytes(struct mm_struct *mm,
570 unsigned long addr)
571{
572 unsigned long bt_table_nr_entries;
573 unsigned long offset = addr;
574
575 if (is_64bit_mm(mm)) {
576
577 offset >>= 3;
578 bt_table_nr_entries = MPX_BT_NR_ENTRIES_64;
579 } else {
580
581 offset >>= 2;
582 bt_table_nr_entries = MPX_BT_NR_ENTRIES_32;
583 }
584
585
586
587
588
589
590
591
592
593
594 offset &= (bt_table_nr_entries-1);
595
596
597
598
599 offset *= bt_entry_size_bytes(mm);
600 return offset;
601}
602
603
604
605
606
607
608
609
610static inline unsigned long bd_entry_virt_space(struct mm_struct *mm)
611{
612 unsigned long long virt_space;
613 unsigned long long GB = (1ULL << 30);
614
615
616
617
618
619 if (!is_64bit_mm(mm))
620 return (4ULL * GB) / MPX_BD_NR_ENTRIES_32;
621
622
623
624
625
626
627 virt_space = (1ULL << boot_cpu_data.x86_virt_bits);
628 return virt_space / MPX_BD_NR_ENTRIES_64;
629}
630
631
632
633
634
635static noinline int zap_bt_entries_mapping(struct mm_struct *mm,
636 unsigned long bt_addr,
637 unsigned long start_mapping, unsigned long end_mapping)
638{
639 struct vm_area_struct *vma;
640 unsigned long addr, len;
641 unsigned long start;
642 unsigned long end;
643
644
645
646
647
648
649
650 start = bt_addr + mpx_get_bt_entry_offset_bytes(mm, start_mapping);
651 end = bt_addr + mpx_get_bt_entry_offset_bytes(mm, end_mapping - 1);
652
653
654
655
656
657 end += bt_entry_size_bytes(mm);
658
659
660
661
662
663
664 vma = find_vma(mm, start);
665 if (!vma || vma->vm_start > start)
666 return -EINVAL;
667
668
669
670
671
672
673
674 addr = start;
675 while (vma && vma->vm_start < end) {
676
677
678
679
680
681
682 if (!(vma->vm_flags & VM_MPX))
683 return -EINVAL;
684
685 len = min(vma->vm_end, end) - addr;
686 zap_page_range(vma, addr, len);
687 trace_mpx_unmap_zap(addr, addr+len);
688
689 vma = vma->vm_next;
690 addr = vma->vm_start;
691 }
692 return 0;
693}
694
695static unsigned long mpx_get_bd_entry_offset(struct mm_struct *mm,
696 unsigned long addr)
697{
698
699
700
701
702
703
704
705
706
707
708
709 if (is_64bit_mm(mm)) {
710 int bd_entry_size = 8;
711
712
713
714 addr &= ((1UL << boot_cpu_data.x86_virt_bits) - 1);
715 return (addr / bd_entry_virt_space(mm)) * bd_entry_size;
716 } else {
717 int bd_entry_size = 4;
718
719
720
721 return (addr / bd_entry_virt_space(mm)) * bd_entry_size;
722 }
723
724
725
726
727
728
729
730}
731
732static int unmap_entire_bt(struct mm_struct *mm,
733 long __user *bd_entry, unsigned long bt_addr)
734{
735 unsigned long expected_old_val = bt_addr | MPX_BD_ENTRY_VALID_FLAG;
736 unsigned long uninitialized_var(actual_old_val);
737 int ret;
738
739 while (1) {
740 int need_write = 1;
741 unsigned long cleared_bd_entry = 0;
742
743 pagefault_disable();
744 ret = mpx_cmpxchg_bd_entry(mm, &actual_old_val,
745 bd_entry, expected_old_val, cleared_bd_entry);
746 pagefault_enable();
747 if (!ret)
748 break;
749 if (ret == -EFAULT)
750 ret = mpx_resolve_fault(bd_entry, need_write);
751
752
753
754
755 if (ret)
756 return ret;
757 }
758
759
760
761 if (actual_old_val != expected_old_val) {
762
763
764
765
766
767 if (!actual_old_val)
768 return 0;
769
770
771
772
773
774
775
776 return -EINVAL;
777 }
778
779
780
781
782
783 return do_munmap(mm, bt_addr, mpx_bt_size_bytes(mm), NULL);
784}
785
786static int try_unmap_single_bt(struct mm_struct *mm,
787 unsigned long start, unsigned long end)
788{
789 struct vm_area_struct *next;
790 struct vm_area_struct *prev;
791
792
793
794
795 unsigned long bta_start_vaddr = start & ~(bd_entry_virt_space(mm)-1);
796 unsigned long bta_end_vaddr = bta_start_vaddr + bd_entry_virt_space(mm);
797 unsigned long uninitialized_var(bt_addr);
798 void __user *bde_vaddr;
799 int ret;
800
801
802
803
804
805
806 next = find_vma_prev(mm, start, &prev);
807
808
809
810
811
812
813
814
815 while (next && (next->vm_flags & VM_MPX))
816 next = next->vm_next;
817 while (prev && (prev->vm_flags & VM_MPX))
818 prev = prev->vm_prev;
819
820
821
822
823
824
825
826 next = find_vma_prev(mm, start, &prev);
827 if ((!prev || prev->vm_end <= bta_start_vaddr) &&
828 (!next || next->vm_start >= bta_end_vaddr)) {
829
830
831
832
833 start = bta_start_vaddr;
834 end = bta_end_vaddr;
835 }
836
837 bde_vaddr = mm->context.bd_addr + mpx_get_bd_entry_offset(mm, start);
838 ret = get_bt_addr(mm, bde_vaddr, &bt_addr);
839
840
841
842 if (ret == -ENOENT) {
843 ret = 0;
844 return 0;
845 }
846 if (ret)
847 return ret;
848
849
850
851
852
853
854 if ((start == bta_start_vaddr) &&
855 (end == bta_end_vaddr))
856 return unmap_entire_bt(mm, bde_vaddr, bt_addr);
857 return zap_bt_entries_mapping(mm, bt_addr, start, end);
858}
859
860static int mpx_unmap_tables(struct mm_struct *mm,
861 unsigned long start, unsigned long end)
862{
863 unsigned long one_unmap_start;
864 trace_mpx_unmap_search(start, end);
865
866 one_unmap_start = start;
867 while (one_unmap_start < end) {
868 int ret;
869 unsigned long next_unmap_start = ALIGN(one_unmap_start+1,
870 bd_entry_virt_space(mm));
871 unsigned long one_unmap_end = end;
872
873
874
875
876
877 if (one_unmap_end > next_unmap_start)
878 one_unmap_end = next_unmap_start;
879 ret = try_unmap_single_bt(mm, one_unmap_start, one_unmap_end);
880 if (ret)
881 return ret;
882
883 one_unmap_start = next_unmap_start;
884 }
885 return 0;
886}
887
888
889
890
891
892
893
894
895
896void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma,
897 unsigned long start, unsigned long end)
898{
899 int ret;
900
901
902
903
904
905 if (!kernel_managing_mpx_tables(current->mm))
906 return;
907
908
909
910
911
912
913
914
915
916
917 do {
918 if (vma->vm_flags & VM_MPX)
919 return;
920 vma = vma->vm_next;
921 } while (vma && vma->vm_start < end);
922
923 ret = mpx_unmap_tables(mm, start, end);
924 if (ret)
925 force_sig(SIGSEGV, current);
926}
927
928
929unsigned long mpx_unmapped_area_check(unsigned long addr, unsigned long len,
930 unsigned long flags)
931{
932 if (!kernel_managing_mpx_tables(current->mm))
933 return addr;
934 if (addr + len <= DEFAULT_MAP_WINDOW)
935 return addr;
936 if (flags & MAP_FIXED)
937 return -ENOMEM;
938
939
940
941
942
943 if (len > DEFAULT_MAP_WINDOW)
944 return -ENOMEM;
945
946
947 return 0;
948}
949