]>
Commit | Line | Data |
---|---|---|
321d628a FG |
1 | From 5f1c500617cd1a6f629237471344ee200debaa60 Mon Sep 17 00:00:00 2001 |
2 | From: Andy Lutomirski <luto@kernel.org> | |
3 | Date: Sat, 4 Nov 2017 04:19:50 -0700 | |
b378f209 | 4 | Subject: [PATCH 114/233] selftests/x86/ldt_gdt: Add infrastructure to test |
321d628a FG |
5 | set_thread_area() |
6 | MIME-Version: 1.0 | |
7 | Content-Type: text/plain; charset=UTF-8 | |
8 | Content-Transfer-Encoding: 8bit | |
9 | ||
10 | CVE-2017-5754 | |
11 | ||
12 | Much of the test design could apply to set_thread_area() (i.e. GDT), | |
13 | not just modify_ldt(). Add set_thread_area() to the | |
14 | install_valid_mode() helper. | |
15 | ||
16 | Signed-off-by: Andy Lutomirski <luto@kernel.org> | |
17 | Cc: Borislav Petkov <bpetkov@suse.de> | |
18 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
19 | Cc: Peter Zijlstra <peterz@infradead.org> | |
20 | Cc: Thomas Gleixner <tglx@linutronix.de> | |
21 | Link: http://lkml.kernel.org/r/02c23f8fba5547007f741dc24c3926e5284ede02.1509794321.git.luto@kernel.org | |
22 | Signed-off-by: Ingo Molnar <mingo@kernel.org> | |
23 | (cherry picked from commit d744dcad39094c9187075e274d1cdef79c57c8b5) | |
24 | Signed-off-by: Andy Whitcroft <apw@canonical.com> | |
25 | Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> | |
26 | (cherry picked from commit d6ae7ac5849304e520538a6ce3111f372f809596) | |
27 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
28 | --- | |
29 | tools/testing/selftests/x86/ldt_gdt.c | 53 ++++++++++++++++++++++++----------- | |
30 | 1 file changed, 37 insertions(+), 16 deletions(-) | |
31 | ||
32 | diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c | |
33 | index b2c54f4673f2..337f217d0ae9 100644 | |
34 | --- a/tools/testing/selftests/x86/ldt_gdt.c | |
35 | +++ b/tools/testing/selftests/x86/ldt_gdt.c | |
36 | @@ -136,30 +136,51 @@ static void check_valid_segment(uint16_t index, int ldt, | |
37 | } | |
38 | } | |
39 | ||
40 | -static bool install_valid_mode(const struct user_desc *desc, uint32_t ar, | |
41 | - bool oldmode) | |
42 | +static bool install_valid_mode(const struct user_desc *d, uint32_t ar, | |
43 | + bool oldmode, bool ldt) | |
44 | { | |
45 | - int ret = syscall(SYS_modify_ldt, oldmode ? 1 : 0x11, | |
46 | - desc, sizeof(*desc)); | |
47 | - if (ret < -1) | |
48 | - errno = -ret; | |
49 | + struct user_desc desc = *d; | |
50 | + int ret; | |
51 | + | |
52 | + if (!ldt) { | |
53 | +#ifndef __i386__ | |
54 | + /* No point testing set_thread_area in a 64-bit build */ | |
55 | + return false; | |
56 | +#endif | |
57 | + if (!gdt_entry_num) | |
58 | + return false; | |
59 | + desc.entry_number = gdt_entry_num; | |
60 | + | |
61 | + ret = syscall(SYS_set_thread_area, &desc); | |
62 | + } else { | |
63 | + ret = syscall(SYS_modify_ldt, oldmode ? 1 : 0x11, | |
64 | + &desc, sizeof(desc)); | |
65 | + | |
66 | + if (ret < -1) | |
67 | + errno = -ret; | |
68 | + | |
69 | + if (ret != 0 && errno == ENOSYS) { | |
70 | + printf("[OK]\tmodify_ldt returned -ENOSYS\n"); | |
71 | + return false; | |
72 | + } | |
73 | + } | |
74 | + | |
75 | if (ret == 0) { | |
76 | - uint32_t limit = desc->limit; | |
77 | - if (desc->limit_in_pages) | |
78 | + uint32_t limit = desc.limit; | |
79 | + if (desc.limit_in_pages) | |
80 | limit = (limit << 12) + 4095; | |
81 | - check_valid_segment(desc->entry_number, 1, ar, limit, true); | |
82 | + check_valid_segment(desc.entry_number, ldt, ar, limit, true); | |
83 | return true; | |
84 | - } else if (errno == ENOSYS) { | |
85 | - printf("[OK]\tmodify_ldt returned -ENOSYS\n"); | |
86 | - return false; | |
87 | } else { | |
88 | - if (desc->seg_32bit) { | |
89 | - printf("[FAIL]\tUnexpected modify_ldt failure %d\n", | |
90 | + if (desc.seg_32bit) { | |
91 | + printf("[FAIL]\tUnexpected %s failure %d\n", | |
92 | + ldt ? "modify_ldt" : "set_thread_area", | |
93 | errno); | |
94 | nerrs++; | |
95 | return false; | |
96 | } else { | |
97 | - printf("[OK]\tmodify_ldt rejected 16 bit segment\n"); | |
98 | + printf("[OK]\t%s rejected 16 bit segment\n", | |
99 | + ldt ? "modify_ldt" : "set_thread_area"); | |
100 | return false; | |
101 | } | |
102 | } | |
103 | @@ -167,7 +188,7 @@ static bool install_valid_mode(const struct user_desc *desc, uint32_t ar, | |
104 | ||
105 | static bool install_valid(const struct user_desc *desc, uint32_t ar) | |
106 | { | |
107 | - return install_valid_mode(desc, ar, false); | |
108 | + return install_valid_mode(desc, ar, false, true); | |
109 | } | |
110 | ||
111 | static void install_invalid(const struct user_desc *desc, bool oldmode) | |
112 | -- | |
113 | 2.14.2 | |
114 |