From: Greg Kroah-Hartman Date: Tue, 9 Jun 2020 17:37:31 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v5.7.2~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=25c73ceb92fbc47a8be555604a53a5859bfae105;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: uprobes-ensure-that-uprobe-offset-and-ref_ctr_offset-are-properly-aligned.patch --- diff --git a/queue-4.4/series b/queue-4.4/series index ad035db4504..136f2a923e7 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -33,3 +33,4 @@ x86-speculation-add-special-register-buffer-data-sampling-srbds-mitigation.patch x86-speculation-add-srbds-vulnerability-and-mitigation-documentation.patch x86-speculation-add-ivy-bridge-to-affected-list.patch iio-vcnl4000-fix-i2c-swapped-word-reading.patch +uprobes-ensure-that-uprobe-offset-and-ref_ctr_offset-are-properly-aligned.patch diff --git a/queue-4.4/uprobes-ensure-that-uprobe-offset-and-ref_ctr_offset-are-properly-aligned.patch b/queue-4.4/uprobes-ensure-that-uprobe-offset-and-ref_ctr_offset-are-properly-aligned.patch new file mode 100644 index 00000000000..4581228a7cf --- /dev/null +++ b/queue-4.4/uprobes-ensure-that-uprobe-offset-and-ref_ctr_offset-are-properly-aligned.patch @@ -0,0 +1,76 @@ +From 013b2deba9a6b80ca02f4fafd7dedf875e9b4450 Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Mon, 4 May 2020 18:47:25 +0200 +Subject: uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned + +From: Oleg Nesterov + +commit 013b2deba9a6b80ca02f4fafd7dedf875e9b4450 upstream. + +uprobe_write_opcode() must not cross page boundary; prepare_uprobe() +relies on arch_uprobe_analyze_insn() which should validate "vaddr" but +some architectures (csky, s390, and sparc) don't do this. + +We can remove the BUG_ON() check in prepare_uprobe() and validate the +offset early in __uprobe_register(). The new IS_ALIGNED() check matches +the alignment check in arch_prepare_kprobe() on supported architectures, +so I think that all insns must be aligned to UPROBE_SWBP_INSN_SIZE. + +Another problem is __update_ref_ctr() which was wrong from the very +beginning, it can read/write outside of kmap'ed page unless "vaddr" is +aligned to sizeof(short), __uprobe_register() should check this too. + +Reported-by: Linus Torvalds +Suggested-by: Linus Torvalds +Signed-off-by: Oleg Nesterov +Reviewed-by: Srikar Dronamraju +Acked-by: Christian Borntraeger +Tested-by: Sven Schnelle +Cc: Steven Rostedt +Cc: stable@vger.kernel.org +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/events/uprobes.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/kernel/events/uprobes.c ++++ b/kernel/events/uprobes.c +@@ -602,10 +602,6 @@ static int prepare_uprobe(struct uprobe + if (ret) + goto out; + +- /* uprobe_write_opcode() assumes we don't cross page boundary */ +- BUG_ON((uprobe->offset & ~PAGE_MASK) + +- UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); +- + smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */ + set_bit(UPROBE_COPY_INSN, &uprobe->flags); + +@@ -884,6 +880,15 @@ int uprobe_register(struct inode *inode, + if (offset > i_size_read(inode)) + return -EINVAL; + ++ /* ++ * This ensures that copy_from_page(), copy_to_page() and ++ * __update_ref_ctr() can't cross page boundary. ++ */ ++ if (!IS_ALIGNED(offset, UPROBE_SWBP_INSN_SIZE)) ++ return -EINVAL; ++ if (!IS_ALIGNED(ref_ctr_offset, sizeof(short))) ++ return -EINVAL; ++ + retry: + uprobe = alloc_uprobe(inode, offset); + if (!uprobe) +@@ -1692,6 +1697,9 @@ static int is_trap_at_addr(struct mm_str + uprobe_opcode_t opcode; + int result; + ++ if (WARN_ON_ONCE(!IS_ALIGNED(vaddr, UPROBE_SWBP_INSN_SIZE))) ++ return -EINVAL; ++ + pagefault_disable(); + result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr, + sizeof(opcode));