diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-04-14 20:00:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-04-14 20:00:01 -0400 |
commit | 91174391bf5a368c9837b63b84d7f5a813efd719 (patch) | |
tree | 1dcabefff9cc72492238533e61fafc91a2017ed5 | |
parent | 07c7016de7896493e95bef64fe913ac849509d6e (diff) | |
parent | 7f00f388712b29005782bad7e4b25942620f3b9c (diff) |
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thomas Gleixner:
"A set of small fixes for x86:
- fix locking in RDT to prevent memory leaks and freeing in use
memory
- prevent setting invalid values for vdso32_enabled which cause
inconsistencies for user space resulting in application crashes.
- plug a race in the vdso32 code between fork and sysctl which causes
inconsistencies for user space resulting in application crashes.
- make MPX signal delivery work in compat mode
- make the dmesg output of traps and faults readable again"
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/intel_rdt: Fix locking in rdtgroup_schemata_write()
x86/debug: Fix the printk() debug output of signal_fault(), do_trap() and do_general_protection()
x86/vdso: Plug race between mapping and ELF header setup
x86/vdso: Ensure vdso32_enabled gets set to valid values only
x86/signals: Fix lower/upper bound reporting in compat siginfo
-rw-r--r-- | arch/x86/entry/vdso/vdso32-setup.c | 11 | ||||
-rw-r--r-- | arch/x86/include/asm/elf.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel_rdt_schemata.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/signal.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/signal_compat.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/traps.c | 4 |
6 files changed, 16 insertions, 9 deletions
diff --git a/arch/x86/entry/vdso/vdso32-setup.c b/arch/x86/entry/vdso/vdso32-setup.c index 7853b53959cd..3f9d1a83891a 100644 --- a/arch/x86/entry/vdso/vdso32-setup.c +++ b/arch/x86/entry/vdso/vdso32-setup.c | |||
@@ -30,8 +30,10 @@ static int __init vdso32_setup(char *s) | |||
30 | { | 30 | { |
31 | vdso32_enabled = simple_strtoul(s, NULL, 0); | 31 | vdso32_enabled = simple_strtoul(s, NULL, 0); |
32 | 32 | ||
33 | if (vdso32_enabled > 1) | 33 | if (vdso32_enabled > 1) { |
34 | pr_warn("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n"); | 34 | pr_warn("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n"); |
35 | vdso32_enabled = 0; | ||
36 | } | ||
35 | 37 | ||
36 | return 1; | 38 | return 1; |
37 | } | 39 | } |
@@ -62,13 +64,18 @@ subsys_initcall(sysenter_setup); | |||
62 | /* Register vsyscall32 into the ABI table */ | 64 | /* Register vsyscall32 into the ABI table */ |
63 | #include <linux/sysctl.h> | 65 | #include <linux/sysctl.h> |
64 | 66 | ||
67 | static const int zero; | ||
68 | static const int one = 1; | ||
69 | |||
65 | static struct ctl_table abi_table2[] = { | 70 | static struct ctl_table abi_table2[] = { |
66 | { | 71 | { |
67 | .procname = "vsyscall32", | 72 | .procname = "vsyscall32", |
68 | .data = &vdso32_enabled, | 73 | .data = &vdso32_enabled, |
69 | .maxlen = sizeof(int), | 74 | .maxlen = sizeof(int), |
70 | .mode = 0644, | 75 | .mode = 0644, |
71 | .proc_handler = proc_dointvec | 76 | .proc_handler = proc_dointvec_minmax, |
77 | .extra1 = (int *)&zero, | ||
78 | .extra2 = (int *)&one, | ||
72 | }, | 79 | }, |
73 | {} | 80 | {} |
74 | }; | 81 | }; |
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h index 9d49c18b5ea9..3762536619f8 100644 --- a/arch/x86/include/asm/elf.h +++ b/arch/x86/include/asm/elf.h | |||
@@ -287,7 +287,7 @@ struct task_struct; | |||
287 | 287 | ||
288 | #define ARCH_DLINFO_IA32 \ | 288 | #define ARCH_DLINFO_IA32 \ |
289 | do { \ | 289 | do { \ |
290 | if (vdso32_enabled) { \ | 290 | if (VDSO_CURRENT_BASE) { \ |
291 | NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ | 291 | NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ |
292 | NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ | 292 | NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ |
293 | } \ | 293 | } \ |
diff --git a/arch/x86/kernel/cpu/intel_rdt_schemata.c b/arch/x86/kernel/cpu/intel_rdt_schemata.c index f369cb8db0d5..badd2b31a560 100644 --- a/arch/x86/kernel/cpu/intel_rdt_schemata.c +++ b/arch/x86/kernel/cpu/intel_rdt_schemata.c | |||
@@ -200,11 +200,11 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, | |||
200 | } | 200 | } |
201 | 201 | ||
202 | out: | 202 | out: |
203 | rdtgroup_kn_unlock(of->kn); | ||
204 | for_each_enabled_rdt_resource(r) { | 203 | for_each_enabled_rdt_resource(r) { |
205 | kfree(r->tmp_cbms); | 204 | kfree(r->tmp_cbms); |
206 | r->tmp_cbms = NULL; | 205 | r->tmp_cbms = NULL; |
207 | } | 206 | } |
207 | rdtgroup_kn_unlock(of->kn); | ||
208 | return ret ?: nbytes; | 208 | return ret ?: nbytes; |
209 | } | 209 | } |
210 | 210 | ||
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 396c042e9d0e..cc30a74e4adb 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -846,7 +846,7 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where) | |||
846 | task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG, | 846 | task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG, |
847 | me->comm, me->pid, where, frame, | 847 | me->comm, me->pid, where, frame, |
848 | regs->ip, regs->sp, regs->orig_ax); | 848 | regs->ip, regs->sp, regs->orig_ax); |
849 | print_vma_addr(" in ", regs->ip); | 849 | print_vma_addr(KERN_CONT " in ", regs->ip); |
850 | pr_cont("\n"); | 850 | pr_cont("\n"); |
851 | } | 851 | } |
852 | 852 | ||
diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c index ec1f756f9dc9..71beb28600d4 100644 --- a/arch/x86/kernel/signal_compat.c +++ b/arch/x86/kernel/signal_compat.c | |||
@@ -151,8 +151,8 @@ int __copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from, | |||
151 | 151 | ||
152 | if (from->si_signo == SIGSEGV) { | 152 | if (from->si_signo == SIGSEGV) { |
153 | if (from->si_code == SEGV_BNDERR) { | 153 | if (from->si_code == SEGV_BNDERR) { |
154 | compat_uptr_t lower = (unsigned long)&to->si_lower; | 154 | compat_uptr_t lower = (unsigned long)from->si_lower; |
155 | compat_uptr_t upper = (unsigned long)&to->si_upper; | 155 | compat_uptr_t upper = (unsigned long)from->si_upper; |
156 | put_user_ex(lower, &to->si_lower); | 156 | put_user_ex(lower, &to->si_lower); |
157 | put_user_ex(upper, &to->si_upper); | 157 | put_user_ex(upper, &to->si_upper); |
158 | } | 158 | } |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 948443e115c1..4e496379a871 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -255,7 +255,7 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, | |||
255 | pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx", | 255 | pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx", |
256 | tsk->comm, tsk->pid, str, | 256 | tsk->comm, tsk->pid, str, |
257 | regs->ip, regs->sp, error_code); | 257 | regs->ip, regs->sp, error_code); |
258 | print_vma_addr(" in ", regs->ip); | 258 | print_vma_addr(KERN_CONT " in ", regs->ip); |
259 | pr_cont("\n"); | 259 | pr_cont("\n"); |
260 | } | 260 | } |
261 | 261 | ||
@@ -519,7 +519,7 @@ do_general_protection(struct pt_regs *regs, long error_code) | |||
519 | pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx", | 519 | pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx", |
520 | tsk->comm, task_pid_nr(tsk), | 520 | tsk->comm, task_pid_nr(tsk), |
521 | regs->ip, regs->sp, error_code); | 521 | regs->ip, regs->sp, error_code); |
522 | print_vma_addr(" in ", regs->ip); | 522 | print_vma_addr(KERN_CONT " in ", regs->ip); |
523 | pr_cont("\n"); | 523 | pr_cont("\n"); |
524 | } | 524 | } |
525 | 525 | ||