Browse code

linux-secure: Fix kernel panic during boot

The linux-secure kernel panics during boot as shown below:

[ 0.734037] BUG: unable to handle kernel NULL pointer dereference at 0000000000000070
[ 0.734077] PGD 0 P4D 0
[ 0.734092] Oops: 0000 [#1] SMP PTI
[ 0.734108] CPU: 0 PID: 162 Comm: modprobe Tainted: G W T 4.18.9-2.ph3-secure #1-photon
[ 0.734144] Hardware name: VMware, Inc. VMware7,1/440BX Desktop Reference Platform, BIOS VMW71.00V.0.B64.1704110547 04/11/2017
[ 0.734203] RIP: 0010:__x64_sys_brk+0x25/0x1f0
[ 0.734222] Code: 18 00 00 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 4c 8d 6d c0 53 65 4c 8b 3c 25 40 4d 01 00 48 83 ec 20 4d 8b a7 7
[ 0.734319] RSP: 0018:ffff9fbf414b3e20 EFLAGS: 00010282
[ 0.734341] RAX: 0000000080000000 RBX: ffff9fbf414b3f58 RCX: 0000000000000000
[ 0.734369] RDX: 000000000000004d RSI: 00007bc7977d41a3 RDI: 0000000000000000
[ 0.734397] RBP: ffff9fbf414b3e68 R08: 0000000000000019 R09: 00007bc7977d43f9
[ 0.734425] R10: 0000000000000000 R11: 0000000000000000 R12: ffff927b0ec31000
[ 0.734454] R13: ffff9fbf414b3e28 R14: 0000000000000000 R15: ffff927b0ec2cb80
[ 0.734483] FS: 0000000000000000(0000) GS:ffff927b7fc00000(0000) knlGS:0000000000000000
[ 0.734515] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 0.734538] CR2: 0000000000000070 CR3: 000000000ec34004 CR4: 00000000001606f0
[ 0.734614] Call Trace:
[ 0.734630] do_syscall_64+0x6d/0x330
[ 0.734648] ? invalid_op+0x14/0x20
[ 0.734665] entry_SYSCALL_64_after_hwframe+0x4f/0xb5
[ 0.734687] ? pax_randomize_kstack+0x85/0xa0
[ 0.734707] ? entry_SYSCALL_64_after_hwframe+0x42/0xb5
[ 0.734729] Modules linked in:
[ 0.734744] CR2: 0000000000000070
[ 0.734759] ---[ end trace b8d9c1f99ecab103 ]---

The root-cause of this issue is two-fold:

- The PAX randkstack patch uses task_pt_regs(current) to calculate the
new randomized stack pointer. However, that's incorrect in the
current code, because the pt_regs pointer passed to do_syscall_64() is
actually different from the one computed using task_pt_regs(current).
So, we'll need to use the same pt_regs pointer to calculate the new
randomized stack pointer as well.

- The RAP plugin patch passes 6 arguments to the syscall handler in
do_syscall_64(). The latter used to accept 6 arguments before, but was
recently changed to accept only 1 argument, namely the pt_regs
pointer. This argument mismatch (which goes undetected by the compiler
because it is coded up in in-line assembly) causes sys_brk() to try
and access regs->di as if it was regs itself, causing the NULL pointer
dereference down the road.

Fix both these issues to avoid the kernel panic. While at it, also
refactor the PAX randkstack patch to make sure that the stack
randomization logic is actually enclosed under CONFIG_PAX_RANDKSTACK.

Change-Id: Ia93a07c1c62ed0fe33db058996fb87c085f8e2e5
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/6078
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>

Srivatsa S. Bhat (VMware) authored on 2018/10/31 05:25:01
Showing 3 changed files
... ...
@@ -83,87 +83,97 @@ Subject: [PATCH 2/3] Added PAX_RANDKSTACK
83 83
 Signed-off-by: Him Kalyan Bordoloi<bordoloih@vmware.com>
84 84
 
85 85
 ---
86
- arch/x86/entry/entry_64.S    | 17 +++++++++++++++--
87
- arch/x86/kernel/process_64.c | 17 +++++++++++++++++
86
+ arch/x86/entry/entry_64.S    | 37 +++++++++++++++++++++++++++++++++++++
87
+ arch/x86/kernel/process_64.c | 15 +++++++++++++++
88 88
  security/Kconfig             | 16 ++++++++++++++++
89
- 3 files changed, 48 insertions(+), 2 deletions(-)
89
+ 3 files changed, 68 insertions(+)
90 90
 
91 91
 diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
92
-index 8ae7ffd..9c1daeb 100644
92
+index 8ae7ffd..f7c721d 100644
93 93
 --- a/arch/x86/entry/entry_64.S
94 94
 +++ b/arch/x86/entry/entry_64.S
95
-@@ -53,6 +53,14 @@ ENTRY(native_usergs_sysret64)
95
+@@ -53,6 +53,15 @@ ENTRY(native_usergs_sysret64)
96 96
  END(native_usergs_sysret64)
97 97
  #endif /* CONFIG_PARAVIRT */
98 98
  
99
-+.macro pax_rand_kstack
100 99
 +#ifdef CONFIG_PAX_RANDKSTACK
100
++.macro PAX_RAND_KSTACK
101
++	movq	%rsp, %rdi
101 102
 +	call	pax_randomize_kstack
102 103
 +	movq    %rsp, %rdi
103 104
 +	movq    %rax, %rsp
104
-+#endif
105 105
 +.endm
106
++#endif
106 107
 +
107 108
  .macro TRACE_IRQS_FLAGS flags:req
108 109
  #ifdef CONFIG_TRACE_IRQFLAGS
109 110
  	btl	$9, \flags		/* interrupts off? */
110
-@@ -233,9 +241,20 @@ GLOBAL(entry_SYSCALL_64_after_hwframe)
111
+@@ -233,9 +242,28 @@ GLOBAL(entry_SYSCALL_64_after_hwframe)
111 112
  	TRACE_IRQS_OFF
112 113
  
113 114
  	/* IRQs are off. */
114
--	movq	%rax, %rdi
115
--	movq	%rsp, %rsi
116 115
 +
117 116
 +	/*
118 117
 +	 * do_syscall_64 expects syscall-nr (pt_regs->orig_ax) as the first
119 118
 +	 * argument (%rdi) and pointer to pt_regs as the second argument (%rsi).
120 119
 +	 */
120
++#ifdef CONFIG_PAX_RANDKSTACK
121 121
 +	pushq	%rax
122
++	movq	%rsp, %rdi
122 123
 +	call	pax_randomize_kstack
123 124
 +	popq	%rdi
124 125
 +	movq    %rsp, %rsi
125 126
 +	movq    %rax, %rsp
126 127
 +
127 128
 +	pushq	%rsi
129
++#else
130
+ 	movq	%rax, %rdi
131
+ 	movq	%rsp, %rsi
132
++#endif
128 133
  	call	do_syscall_64		/* returns with IRQs disabled */
134
++#ifdef CONFIG_PAX_RANDKSTACK
129 135
 +	popq	%rsp
136
++#endif
130 137
  
131 138
  	TRACE_IRQS_IRETQ		/* we're about to change IF */
132 139
  
133
-@@ -401,8 +420,11 @@ ENTRY(ret_from_fork)
140
+@@ -401,8 +429,17 @@ ENTRY(ret_from_fork)
134 141
  
135 142
  2:
136 143
  	UNWIND_HINT_REGS
137
--	movq	%rsp, %rdi
138
-+	pax_rand_kstack
144
++#ifdef CONFIG_PAX_RANDKSTACK
145
++	PAX_RAND_KSTACK
139 146
 +	pushq	%rdi
147
++#else
148
+ 	movq	%rsp, %rdi
149
++#endif
140 150
  	call	syscall_return_slowpath	/* returns with IRQs disabled */
151
++#ifdef CONFIG_PAX_RANDKSTACK
141 152
 +	popq	%rsp
153
++#endif
142 154
 +
143 155
  	TRACE_IRQS_ON			/* user mode is traced as IRQS on */
144 156
  	jmp	swapgs_restore_regs_and_return_to_usermode
145 157
  
146 158
 diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
147
-index 0091a73..a73aab3 100644
159
+index 0091a73..31b697c 100644
148 160
 --- a/arch/x86/kernel/process_64.c
149 161
 +++ b/arch/x86/kernel/process_64.c
150
-@@ -61,6 +61,23 @@
162
+@@ -61,6 +61,21 @@
151 163
  
152 164
  __visible DEFINE_PER_CPU(unsigned long, rsp_scratch);
153 165
  
154 166
 +#ifdef CONFIG_PAX_RANDKSTACK
155
-+unsigned long pax_randomize_kstack(void)
167
++unsigned long pax_randomize_kstack(struct pt_regs *regs)
156 168
 +{
157
-+        struct task_struct *task = current;
158
-+        unsigned long time;
159
-+        unsigned long sp1;
160
-+
169
++	unsigned long time;
170
++	unsigned long sp1;
161 171
 +
162
-+        if (!randomize_va_space)
163
-+                return (unsigned long)task_pt_regs(task);
172
++	if (!randomize_va_space)
173
++		return (unsigned long)regs;
164 174
 +
165
-+        time = rdtsc() & 0xFUL;
166
-+        sp1 = (unsigned long)task_pt_regs(task) - (time << 4);
175
++	time = rdtsc() & 0xFUL;
176
++	sp1 = (unsigned long)regs - (time << 4);
167 177
 +	return sp1;
168 178
 +}
169 179
 +#endif
... ...
@@ -198,3 +208,5 @@ index 564e975..7ef4ec8 100644
198 198
  endif
199 199
  
200 200
  source security/keys/Kconfig
201
+-- 
202
+2.7.4
... ...
@@ -34,7 +34,7 @@ Subject: [PATCH 3/3] Added rap_plugin
34 34
  arch/x86/crypto/twofish-x86_64-asm_64-3way.S       |   2 +-
35 35
  arch/x86/crypto/twofish-x86_64-asm_64.S            |   4 +-
36 36
  arch/x86/entry/Makefile                            |   2 +
37
- arch/x86/entry/common.c                            |  61 +++
37
+ arch/x86/entry/common.c                            |  51 ++
38 38
  arch/x86/events/amd/iommu.h                        |   2 +-
39 39
  arch/x86/include/asm/e820/api.h                    |   2 +-
40 40
  arch/x86/include/asm/fixmap.h                      |   2 +-
... ...
@@ -104,7 +104,7 @@ Subject: [PATCH 3/3] Added rap_plugin
104 104
  kernel/sched/core.c                                |   4 +-
105 105
  kernel/sched/deadline.c                            |   4 +-
106 106
  kernel/sched/rt.c                                  |   4 +-
107
- kernel/sched/sched.h                               |   8 +-
107
+ kernel/sched/sched.h                               |   9 +-
108 108
  mm/filemap.c                                       |   6 +-
109 109
  mm/readahead.c                                     |   2 +-
110 110
  net/bridge/br_private.h                            |   3 +-
... ...
@@ -117,7 +117,7 @@ Subject: [PATCH 3/3] Added rap_plugin
117 117
  scripts/gcc-plugins/rap_plugin/rap_plugin.c        | 534 ++++++++++++++++++++
118 118
  scripts/gcc-plugins/rap_plugin/sip.c               |  96 ++++
119 119
  security/Kconfig                                   |  18 +
120
- 113 files changed, 2506 insertions(+), 750 deletions(-)
120
+ 113 files changed, 2496 insertions(+), 751 deletions(-)
121 121
  create mode 100644 scripts/gcc-plugins/rap_plugin/Makefile
122 122
  create mode 100644 scripts/gcc-plugins/rap_plugin/rap.h
123 123
  create mode 100644 scripts/gcc-plugins/rap_plugin/rap_fptr_pass.c
... ...
@@ -125,7 +125,6 @@ Subject: [PATCH 3/3] Added rap_plugin
125 125
  create mode 100644 scripts/gcc-plugins/rap_plugin/rap_plugin.c
126 126
  create mode 100644 scripts/gcc-plugins/rap_plugin/sip.c
127 127
 
128
-
129 128
 diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
130 129
 index d27a506..25fbe8f 100644
131 130
 --- a/arch/x86/crypto/aesni-intel_asm.S
... ...
@@ -1094,39 +1093,28 @@ index 06fc70c..03f4755 100644
1094 1094
 +CFLAGS_REMOVE_syscall_32.o = $(RAP_PLUGIN_ABS_CFLAGS)
1095 1095
 +CFLAGS_REMOVE_syscall_64.o = $(RAP_PLUGIN_ABS_CFLAGS)
1096 1096
 diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
1097
-index 3b2490b..589aae7 100644
1097
+index 3b2490b..0806da8 100644
1098 1098
 --- a/arch/x86/entry/common.c
1099 1099
 +++ b/arch/x86/entry/common.c
1100
-@@ -286,8 +286,28 @@ __visible void do_syscall_64(unsigned long nr, struct pt_regs *regs)
1101
- 	 */
1100
+@@ -287,7 +287,17 @@ __visible void do_syscall_64(unsigned long nr, struct pt_regs *regs)
1102 1101
  	nr &= __SYSCALL_MASK;
1103 1102
  	if (likely(nr < NR_syscalls)) {
1103
+ 		nr = array_index_nospec(nr, NR_syscalls);
1104 1104
 +#ifdef CONFIG_PAX_RAP
1105
-+		asm volatile("movq %[param1],%%rdi\n\t"
1106
-+			"movq %[param2],%%rsi\n\t"
1107
-+			"movq %[param3],%%rdx\n\t"
1108
-+			"movq %[param4],%%rcx\n\t"
1109
-+			"movq %[param5],%%r8\n\t"
1110
-+			"movq %[param6],%%r9\n\t"
1105
++		asm volatile("movq %[param],%%rdi\n\t"
1111 1106
 +			"call *%P[syscall]\n\t"
1112 1107
 +			"mov %%rax,%[result]\n\t"
1113 1108
 +			: [result] "=m" (regs->ax)
1114 1109
 +			: [syscall] "m" (sys_call_table[nr]),
1115
-+			[param1] "m" (regs->di),
1116
-+			[param2] "m" (regs->si),
1117
-+			[param3] "m" (regs->dx),
1118
-+			[param4] "m" (regs->r10),
1119
-+			[param5] "m" (regs->r8),
1120
-+			[param6] "m" (regs->r9)
1121
-+			: "ax", "di", "si", "dx", "cx", "r8", "r9", "r10", "r11", "memory");
1110
++			[param] "m" (regs)
1111
++			: "ax", "di", "memory");
1122 1112
 +#else
1123
- 		nr = array_index_nospec(nr, NR_syscalls);
1124 1113
  		regs->ax = sys_call_table[nr](regs);
1125 1114
 +#endif
1126 1115
  	}
1127 1116
  
1128 1117
  	syscall_return_slowpath(regs);
1129
-@@ -331,10 +351,51 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs)
1118
+@@ -331,10 +341,51 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs)
1130 1119
  		 * the high bits are zero.  Make sure we zero-extend all
1131 1120
  		 * of the args.
1132 1121
  		 */
... ...
@@ -5527,7 +5515,7 @@ index c7742dc..39668dc 100644
5527 5527
  
5528 5528
  	unsigned char		idle_balance;
5529 5529
  
5530
-@@ -1088,7 +1092,7 @@ init_numa_balancing(unsigned long clone_flags, struct task_struct *p)
5530
+@@ -1088,7 +1091,7 @@ init_numa_balancing(unsigned long clone_flags, struct task_struct *p)
5531 5531
  
5532 5532
  static inline void
5533 5533
  queue_balance_callback(struct rq *rq,
... ...
@@ -5536,7 +5524,7 @@ index c7742dc..39668dc 100644
5536 5536
  		       void (*func)(struct rq *rq))
5537 5537
  {
5538 5538
  	lockdep_assert_held(&rq->lock);
5539
-@@ -1096,7 +1100,7 @@ queue_balance_callback(struct rq *rq,
5539
+@@ -1096,7 +1099,7 @@ queue_balance_callback(struct rq *rq,
5540 5540
  	if (unlikely(head->next))
5541 5541
  		return;
5542 5542
  
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:        Kernel
3 3
 Name:           linux-secure
4 4
 Version:        4.18.9
5
-Release:        2%{?kat_build:.%kat_build}%{?dist}
5
+Release:        3%{?kat_build:.%kat_build}%{?dist}
6 6
 License:        GPLv2
7 7
 URL:            http://www.kernel.org/
8 8
 Group:          System Environment/Kernel
... ...
@@ -233,6 +233,8 @@ ln -sf linux-%{uname_r}.cfg /boot/photon.cfg
233 233
 /usr/src/linux-headers-%{uname_r}
234 234
 
235 235
 %changelog
236
+*   Tue Oct 30 2018 Srivatsa S. Bhat (VMware) <srivatsa@csail.mit.edu> 4.18.9-3
237
+-   Fix PAX randkstack and RAP plugin patches to avoid boot panic.
236 238
 *   Mon Oct 22 2018 Srivatsa S. Bhat (VMware) <srivatsa@csail.mit.edu> 4.18.9-2
237 239
 -   Use updated steal time accounting patch.
238 240
 *   Tue Sep 25 2018 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 4.18.9-1
... ...
@@ -262,7 +264,7 @@ ln -sf linux-%{uname_r}.cfg /boot/photon.cfg
262 262
 -   Version update
263 263
 *   Wed Oct 11 2017 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 4.9.53-3
264 264
 -   Add patch "KVM: Don't accept obviously wrong gsi values via
265
-    KVM_IRQFD" to fix CVE-2017-1000252.
265
+-   KVM_IRQFD" to fix CVE-2017-1000252.
266 266
 *   Tue Oct 10 2017 Alexey Makhalov <amakhalov@vmware.com> 4.9.53-2
267 267
 -   Build hang (at make oldconfig) fix.
268 268
 *   Thu Oct 05 2017 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 4.9.53-1
... ...
@@ -285,7 +287,7 @@ ln -sf linux-%{uname_r}.cfg /boot/photon.cfg
285 285
 *   Wed Aug 09 2017 Alexey Makhalov <amakhalov@vmware.com> 4.9.41-2
286 286
 -   Fix CVE-2017-7542
287 287
 -   [bugfix] Added ccm,gcm,ghash,lzo crypto modules to avoid
288
-    panic on modprobe tcrypt
288
+-   panic on modprobe tcrypt
289 289
 *   Mon Aug 07 2017 Alexey Makhalov <amakhalov@vmware.com> 4.9.41-1
290 290
 -   Version update
291 291
 *   Fri Aug 04 2017 Bo Gan <ganb@vmware.com> 4.9.38-6
... ...
@@ -313,7 +315,7 @@ ln -sf linux-%{uname_r}.cfg /boot/photon.cfg
313 313
 -   Fix CVE-2017-1000364 ("stack clash") and CVE-2017-9605
314 314
 *   Thu Jun 8 2017 Alexey Makhalov <amakhalov@vmware.com> 4.9.31-1
315 315
 -   Fix CVE-2017-8890, CVE-2017-9074, CVE-2017-9075, CVE-2017-9076
316
-    CVE-2017-9077 and CVE-2017-9242
316
+-   CVE-2017-9077 and CVE-2017-9242
317 317
 -   [feature] IPV6 netfilter NAT table support
318 318
 *   Fri May 26 2017 Alexey Makhalov <amakhalov@vmware.com> 4.9.30-1
319 319
 -   Fix CVE-2017-7487 and CVE-2017-9059
... ...
@@ -340,11 +342,11 @@ ln -sf linux-%{uname_r}.cfg /boot/photon.cfg
340 340
 -   .config: disable XEN guest (needs rap_plugin verification)
341 341
 *   Wed Feb 22 2017 Alexey Makhalov <amakhalov@vmware.com> 4.9.9-2
342 342
 -   rap_plugin improvement: throw error on function type casting
343
-    function signatures were cleaned up using this feature.
343
+-   function signatures were cleaned up using this feature.
344 344
 -   Added RAP_ENTRY for asm functions.
345 345
 *   Thu Feb 09 2017 Alexey Makhalov <amakhalov@vmware.com> 4.9.9-1
346 346
 -   Update to linux-4.9.9 to fix CVE-2016-10153, CVE-2017-5546,
347
-    CVE-2017-5547, CVE-2017-5548 and CVE-2017-5576.
347
+-   CVE-2017-5547, CVE-2017-5548 and CVE-2017-5576.
348 348
 -   Added aufs support.
349 349
 -   Added PAX_RANDKSTACK feature.
350 350
 -   Extra func signatures cleanup to fix 1809717 and 1809722.
... ...
@@ -358,7 +360,7 @@ ln -sf linux-%{uname_r}.cfg /boot/photon.cfg
358 358
 *   Mon Dec 12 2016 Alexey Makhalov <amakhalov@vmware.com> 4.9.0-1
359 359
 -   Update to linux-4.9.0
360 360
 -   Add paravirt stolen time accounting feature (from linux-esx),
361
-    but disable it by default (no-vmw-sta cmdline parameter)
361
+-   but disable it by default (no-vmw-sta cmdline parameter)
362 362
 -   Use vmware_io_delay() to keep "void fn(void)" signature
363 363
 *   Wed Nov 30 2016 Alexey Makhalov <amakhalov@vmware.com> 4.8.0-2
364 364
 -   Expand `uname -r` with release number
... ...
@@ -369,4 +371,4 @@ ln -sf linux-%{uname_r}.cfg /boot/photon.cfg
369 369
 -   .config: add netfilter_xt_match_{cgroup,ipvs} support
370 370
 -   .config: disable /dev/mem
371 371
 *   Mon Oct 17 2016 Alexey Makhalov <amakhalov@vmware.com> 4.8.0-1
372
-    Initial commit.
372
+-   Initial commit.