From: Sasha Levin Date: Tue, 3 Sep 2019 05:27:12 +0000 (-0400) Subject: drop uprobes-x86-fix-detection-of-32-bit-user-mode.patch for now X-Git-Tag: v4.4.191~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=551398a39c1177e1d2fa108624351beeb9b4afcf;p=thirdparty%2Fkernel%2Fstable-queue.git drop uprobes-x86-fix-detection-of-32-bit-user-mode.patch for now Signed-off-by: Sasha Levin --- diff --git a/queue-4.14/series b/queue-4.14/series index 0b8ddcce021..3d008b1276f 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -25,4 +25,3 @@ kvm-x86-skip-populating-logical-dest-map-if-apic-is-not-sw-enabled.patch kvm-x86-don-t-update-rip-or-do-single-step-on-faulting-emulation.patch x86-apic-do-not-initialize-ldr-and-dfr-for-bigsmp.patch x86-apic-include-the-ldr-when-clearing-out-apic-registers.patch -uprobes-x86-fix-detection-of-32-bit-user-mode.patch diff --git a/queue-4.14/uprobes-x86-fix-detection-of-32-bit-user-mode.patch b/queue-4.14/uprobes-x86-fix-detection-of-32-bit-user-mode.patch deleted file mode 100644 index dadeabf81a8..00000000000 --- a/queue-4.14/uprobes-x86-fix-detection-of-32-bit-user-mode.patch +++ /dev/null @@ -1,130 +0,0 @@ -From c63e9c2a9ecd90df7a073322a5d90ed9fad19196 Mon Sep 17 00:00:00 2001 -From: Sebastian Mayr -Date: Sun, 28 Jul 2019 17:26:17 +0200 -Subject: uprobes/x86: Fix detection of 32-bit user mode - -[ Upstream commit 9212ec7d8357ea630031e89d0d399c761421c83b ] - -32-bit processes running on a 64-bit kernel are not always detected -correctly, causing the process to crash when uretprobes are installed. - -The reason for the crash is that in_ia32_syscall() is used to determine the -process's mode, which only works correctly when called from a syscall. - -In the case of uretprobes, however, the function is called from a exception -and always returns 'false' on a 64-bit kernel. In consequence this leads to -corruption of the process's return address. - -Fix this by using user_64bit_mode() instead of in_ia32_syscall(), which -is correct in any situation. - -[ tglx: Add a comment and the following historical info ] - -This should have been detected by the rename which happened in commit - - abfb9498ee13 ("x86/entry: Rename is_{ia32,x32}_task() to in_{ia32,x32}_syscall()") - -which states in the changelog: - - The is_ia32_task()/is_x32_task() function names are a big misnomer: they - suggests that the compat-ness of a system call is a task property, which - is not true, the compatness of a system call purely depends on how it - was invoked through the system call layer. - ..... - -and then it went and blindly renamed every call site. - -Sadly enough this was already mentioned here: - - 8faaed1b9f50 ("uprobes/x86: Introduce sizeof_long(), cleanup adjust_ret_addr() and -arch_uretprobe_hijack_return_addr()") - -where the changelog says: - - TODO: is_ia32_task() is not what we actually want, TS_COMPAT does - not necessarily mean 32bit. Fortunately syscall-like insns can't be - probed so it actually works, but it would be better to rename and - use is_ia32_frame(). - -and goes all the way back to: - - 0326f5a94dde ("uprobes/core: Handle breakpoint and singlestep exceptions") - -Oh well. 7+ years until someone actually tried a uretprobe on a 32bit -process on a 64bit kernel.... - -Fixes: 0326f5a94dde ("uprobes/core: Handle breakpoint and singlestep exceptions") -Signed-off-by: Sebastian Mayr -Signed-off-by: Thomas Gleixner -Cc: Masami Hiramatsu -Cc: Dmitry Safonov -Cc: Oleg Nesterov -Cc: Srikar Dronamraju -Cc: stable@vger.kernel.org -Link: https://lkml.kernel.org/r/20190728152617.7308-1-me@sam.st -Signed-off-by: Sasha Levin ---- - arch/x86/kernel/uprobes.c | 17 ++++++++++------- - 1 file changed, 10 insertions(+), 7 deletions(-) - -diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c -index b9a8f34b5e5ab..7a87ef1f5b5e6 100644 ---- a/arch/x86/kernel/uprobes.c -+++ b/arch/x86/kernel/uprobes.c -@@ -518,9 +518,12 @@ struct uprobe_xol_ops { - void (*abort)(struct arch_uprobe *, struct pt_regs *); - }; - --static inline int sizeof_long(void) -+static inline int sizeof_long(struct pt_regs *regs) - { -- return in_ia32_syscall() ? 4 : 8; -+ /* -+ * Check registers for mode as in_xxx_syscall() does not apply here. -+ */ -+ return user_64bit_mode(regs) ? 8 : 4; - } - - static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) -@@ -531,9 +534,9 @@ static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) - - static int push_ret_address(struct pt_regs *regs, unsigned long ip) - { -- unsigned long new_sp = regs->sp - sizeof_long(); -+ unsigned long new_sp = regs->sp - sizeof_long(regs); - -- if (copy_to_user((void __user *)new_sp, &ip, sizeof_long())) -+ if (copy_to_user((void __user *)new_sp, &ip, sizeof_long(regs))) - return -EFAULT; - - regs->sp = new_sp; -@@ -566,7 +569,7 @@ static int default_post_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs - long correction = utask->vaddr - utask->xol_vaddr; - regs->ip += correction; - } else if (auprobe->defparam.fixups & UPROBE_FIX_CALL) { -- regs->sp += sizeof_long(); /* Pop incorrect return address */ -+ regs->sp += sizeof_long(regs); /* Pop incorrect return address */ - if (push_ret_address(regs, utask->vaddr + auprobe->defparam.ilen)) - return -ERESTART; - } -@@ -675,7 +678,7 @@ static int branch_post_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) - * "call" insn was executed out-of-line. Just restore ->sp and restart. - * We could also restore ->ip and try to call branch_emulate_op() again. - */ -- regs->sp += sizeof_long(); -+ regs->sp += sizeof_long(regs); - return -ERESTART; - } - -@@ -966,7 +969,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) - unsigned long - arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs) - { -- int rasize = sizeof_long(), nleft; -+ int rasize = sizeof_long(regs), nleft; - unsigned long orig_ret_vaddr = 0; /* clear high bits for 32-bit apps */ - - if (copy_from_user(&orig_ret_vaddr, (void __user *)regs->sp, rasize)) --- -2.20.1 - diff --git a/queue-4.4/series b/queue-4.4/series index d44a915c55c..7aa01522c0d 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -61,4 +61,3 @@ alsa-seq-fix-potential-concurrent-access-to-the-deleted-pool.patch kvm-x86-don-t-update-rip-or-do-single-step-on-faulting-emulation.patch x86-apic-do-not-initialize-ldr-and-dfr-for-bigsmp.patch x86-apic-include-the-ldr-when-clearing-out-apic-registers.patch -uprobes-x86-fix-detection-of-32-bit-user-mode.patch diff --git a/queue-4.4/uprobes-x86-fix-detection-of-32-bit-user-mode.patch b/queue-4.4/uprobes-x86-fix-detection-of-32-bit-user-mode.patch deleted file mode 100644 index cd358872591..00000000000 --- a/queue-4.4/uprobes-x86-fix-detection-of-32-bit-user-mode.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 763926ed4a403e97c969a8fae136f31d7ffc662e Mon Sep 17 00:00:00 2001 -From: Sebastian Mayr -Date: Sun, 28 Jul 2019 17:26:17 +0200 -Subject: uprobes/x86: Fix detection of 32-bit user mode - -[ Upstream commit 9212ec7d8357ea630031e89d0d399c761421c83b ] - -32-bit processes running on a 64-bit kernel are not always detected -correctly, causing the process to crash when uretprobes are installed. - -The reason for the crash is that in_ia32_syscall() is used to determine the -process's mode, which only works correctly when called from a syscall. - -In the case of uretprobes, however, the function is called from a exception -and always returns 'false' on a 64-bit kernel. In consequence this leads to -corruption of the process's return address. - -Fix this by using user_64bit_mode() instead of in_ia32_syscall(), which -is correct in any situation. - -[ tglx: Add a comment and the following historical info ] - -This should have been detected by the rename which happened in commit - - abfb9498ee13 ("x86/entry: Rename is_{ia32,x32}_task() to in_{ia32,x32}_syscall()") - -which states in the changelog: - - The is_ia32_task()/is_x32_task() function names are a big misnomer: they - suggests that the compat-ness of a system call is a task property, which - is not true, the compatness of a system call purely depends on how it - was invoked through the system call layer. - ..... - -and then it went and blindly renamed every call site. - -Sadly enough this was already mentioned here: - - 8faaed1b9f50 ("uprobes/x86: Introduce sizeof_long(), cleanup adjust_ret_addr() and -arch_uretprobe_hijack_return_addr()") - -where the changelog says: - - TODO: is_ia32_task() is not what we actually want, TS_COMPAT does - not necessarily mean 32bit. Fortunately syscall-like insns can't be - probed so it actually works, but it would be better to rename and - use is_ia32_frame(). - -and goes all the way back to: - - 0326f5a94dde ("uprobes/core: Handle breakpoint and singlestep exceptions") - -Oh well. 7+ years until someone actually tried a uretprobe on a 32bit -process on a 64bit kernel.... - -Fixes: 0326f5a94dde ("uprobes/core: Handle breakpoint and singlestep exceptions") -Signed-off-by: Sebastian Mayr -Signed-off-by: Thomas Gleixner -Cc: Masami Hiramatsu -Cc: Dmitry Safonov -Cc: Oleg Nesterov -Cc: Srikar Dronamraju -Cc: stable@vger.kernel.org -Link: https://lkml.kernel.org/r/20190728152617.7308-1-me@sam.st -Signed-off-by: Sasha Levin ---- - arch/x86/kernel/uprobes.c | 17 ++++++++++------- - 1 file changed, 10 insertions(+), 7 deletions(-) - -diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c -index b8105289c60b6..178d63cac321b 100644 ---- a/arch/x86/kernel/uprobes.c -+++ b/arch/x86/kernel/uprobes.c -@@ -514,9 +514,12 @@ struct uprobe_xol_ops { - void (*abort)(struct arch_uprobe *, struct pt_regs *); - }; - --static inline int sizeof_long(void) -+static inline int sizeof_long(struct pt_regs *regs) - { -- return is_ia32_task() ? 4 : 8; -+ /* -+ * Check registers for mode as in_xxx_syscall() does not apply here. -+ */ -+ return user_64bit_mode(regs) ? 8 : 4; - } - - static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) -@@ -527,9 +530,9 @@ static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) - - static int push_ret_address(struct pt_regs *regs, unsigned long ip) - { -- unsigned long new_sp = regs->sp - sizeof_long(); -+ unsigned long new_sp = regs->sp - sizeof_long(regs); - -- if (copy_to_user((void __user *)new_sp, &ip, sizeof_long())) -+ if (copy_to_user((void __user *)new_sp, &ip, sizeof_long(regs))) - return -EFAULT; - - regs->sp = new_sp; -@@ -562,7 +565,7 @@ static int default_post_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs - long correction = utask->vaddr - utask->xol_vaddr; - regs->ip += correction; - } else if (auprobe->defparam.fixups & UPROBE_FIX_CALL) { -- regs->sp += sizeof_long(); /* Pop incorrect return address */ -+ regs->sp += sizeof_long(regs); /* Pop incorrect return address */ - if (push_ret_address(regs, utask->vaddr + auprobe->defparam.ilen)) - return -ERESTART; - } -@@ -671,7 +674,7 @@ static int branch_post_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) - * "call" insn was executed out-of-line. Just restore ->sp and restart. - * We could also restore ->ip and try to call branch_emulate_op() again. - */ -- regs->sp += sizeof_long(); -+ regs->sp += sizeof_long(regs); - return -ERESTART; - } - -@@ -962,7 +965,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) - unsigned long - arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs) - { -- int rasize = sizeof_long(), nleft; -+ int rasize = sizeof_long(regs), nleft; - unsigned long orig_ret_vaddr = 0; /* clear high bits for 32-bit apps */ - - if (copy_from_user(&orig_ret_vaddr, (void __user *)regs->sp, rasize)) --- -2.20.1 - diff --git a/queue-4.9/series b/queue-4.9/series index 4a8e52073ae..5084716cc89 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -61,5 +61,4 @@ alsa-seq-fix-potential-concurrent-access-to-the-deleted-pool.patch kvm-x86-don-t-update-rip-or-do-single-step-on-faulting-emulation.patch x86-apic-do-not-initialize-ldr-and-dfr-for-bigsmp.patch x86-apic-include-the-ldr-when-clearing-out-apic-registers.patch -uprobes-x86-fix-detection-of-32-bit-user-mode.patch mm-zsmalloc.c-fix-race-condition-in-zs_destroy_pool.patch diff --git a/queue-4.9/uprobes-x86-fix-detection-of-32-bit-user-mode.patch b/queue-4.9/uprobes-x86-fix-detection-of-32-bit-user-mode.patch deleted file mode 100644 index f0308ab8259..00000000000 --- a/queue-4.9/uprobes-x86-fix-detection-of-32-bit-user-mode.patch +++ /dev/null @@ -1,130 +0,0 @@ -From c932a2cd326caac68cd394e7203c616214b93a67 Mon Sep 17 00:00:00 2001 -From: Sebastian Mayr -Date: Sun, 28 Jul 2019 17:26:17 +0200 -Subject: uprobes/x86: Fix detection of 32-bit user mode - -[ Upstream commit 9212ec7d8357ea630031e89d0d399c761421c83b ] - -32-bit processes running on a 64-bit kernel are not always detected -correctly, causing the process to crash when uretprobes are installed. - -The reason for the crash is that in_ia32_syscall() is used to determine the -process's mode, which only works correctly when called from a syscall. - -In the case of uretprobes, however, the function is called from a exception -and always returns 'false' on a 64-bit kernel. In consequence this leads to -corruption of the process's return address. - -Fix this by using user_64bit_mode() instead of in_ia32_syscall(), which -is correct in any situation. - -[ tglx: Add a comment and the following historical info ] - -This should have been detected by the rename which happened in commit - - abfb9498ee13 ("x86/entry: Rename is_{ia32,x32}_task() to in_{ia32,x32}_syscall()") - -which states in the changelog: - - The is_ia32_task()/is_x32_task() function names are a big misnomer: they - suggests that the compat-ness of a system call is a task property, which - is not true, the compatness of a system call purely depends on how it - was invoked through the system call layer. - ..... - -and then it went and blindly renamed every call site. - -Sadly enough this was already mentioned here: - - 8faaed1b9f50 ("uprobes/x86: Introduce sizeof_long(), cleanup adjust_ret_addr() and -arch_uretprobe_hijack_return_addr()") - -where the changelog says: - - TODO: is_ia32_task() is not what we actually want, TS_COMPAT does - not necessarily mean 32bit. Fortunately syscall-like insns can't be - probed so it actually works, but it would be better to rename and - use is_ia32_frame(). - -and goes all the way back to: - - 0326f5a94dde ("uprobes/core: Handle breakpoint and singlestep exceptions") - -Oh well. 7+ years until someone actually tried a uretprobe on a 32bit -process on a 64bit kernel.... - -Fixes: 0326f5a94dde ("uprobes/core: Handle breakpoint and singlestep exceptions") -Signed-off-by: Sebastian Mayr -Signed-off-by: Thomas Gleixner -Cc: Masami Hiramatsu -Cc: Dmitry Safonov -Cc: Oleg Nesterov -Cc: Srikar Dronamraju -Cc: stable@vger.kernel.org -Link: https://lkml.kernel.org/r/20190728152617.7308-1-me@sam.st -Signed-off-by: Sasha Levin ---- - arch/x86/kernel/uprobes.c | 17 ++++++++++------- - 1 file changed, 10 insertions(+), 7 deletions(-) - -diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c -index e78a6b1db74b0..e35466afe989d 100644 ---- a/arch/x86/kernel/uprobes.c -+++ b/arch/x86/kernel/uprobes.c -@@ -514,9 +514,12 @@ struct uprobe_xol_ops { - void (*abort)(struct arch_uprobe *, struct pt_regs *); - }; - --static inline int sizeof_long(void) -+static inline int sizeof_long(struct pt_regs *regs) - { -- return in_ia32_syscall() ? 4 : 8; -+ /* -+ * Check registers for mode as in_xxx_syscall() does not apply here. -+ */ -+ return user_64bit_mode(regs) ? 8 : 4; - } - - static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) -@@ -527,9 +530,9 @@ static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) - - static int push_ret_address(struct pt_regs *regs, unsigned long ip) - { -- unsigned long new_sp = regs->sp - sizeof_long(); -+ unsigned long new_sp = regs->sp - sizeof_long(regs); - -- if (copy_to_user((void __user *)new_sp, &ip, sizeof_long())) -+ if (copy_to_user((void __user *)new_sp, &ip, sizeof_long(regs))) - return -EFAULT; - - regs->sp = new_sp; -@@ -562,7 +565,7 @@ static int default_post_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs - long correction = utask->vaddr - utask->xol_vaddr; - regs->ip += correction; - } else if (auprobe->defparam.fixups & UPROBE_FIX_CALL) { -- regs->sp += sizeof_long(); /* Pop incorrect return address */ -+ regs->sp += sizeof_long(regs); /* Pop incorrect return address */ - if (push_ret_address(regs, utask->vaddr + auprobe->defparam.ilen)) - return -ERESTART; - } -@@ -671,7 +674,7 @@ static int branch_post_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) - * "call" insn was executed out-of-line. Just restore ->sp and restart. - * We could also restore ->ip and try to call branch_emulate_op() again. - */ -- regs->sp += sizeof_long(); -+ regs->sp += sizeof_long(regs); - return -ERESTART; - } - -@@ -962,7 +965,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) - unsigned long - arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs) - { -- int rasize = sizeof_long(), nleft; -+ int rasize = sizeof_long(regs), nleft; - unsigned long orig_ret_vaddr = 0; /* clear high bits for 32-bit apps */ - - if (copy_from_user(&orig_ret_vaddr, (void __user *)regs->sp, rasize)) --- -2.20.1 -