mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: akpm@linux-foundation.org, "Sasha Levin" <sasha.levin@oracle.com>,
	"Andi Kleen" <ak@linux.intel.com>,
	"Kostya Serebryany" <kcc@google.com>,
	"Thomas Gleixner" <tglx@linutronix.de>,
	"Andy Lutomirski" <luto@amacapital.net>,
	"Andrey Konovalov" <andreyknvl@google.com>,
	"kasan-dev" <kasan-dev@googlegroups.com>,
	"Denys Vlasenko" <dvlasenk@redhat.com>,
	"Borislav Petkov" <bp@alien8.de>,
	"Wolfram Gloger" <wmglo@dent.med.uni-muenchen.de>,
	"Andrey Ryabinin" <ryabinin.a.a@gmail.com>,
	"Alexander Potapenko" <glider@google.com>,
	"Dmitry Vyukov" <dvyukov@google.com>
Subject: [PATCH 3.2 11/60] x86/process: Add proper bound checks in 64bit get_wchan()
Date: Sun, 15 Nov 2015 01:45:45 +0000	[thread overview]
Message-ID: <lsq.1447551945.331070837@decadent.org.uk> (raw)
In-Reply-To: <lsq.1447551944.536641563@decadent.org.uk>

3.2.73-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Thomas Gleixner <tglx@linutronix.de>

commit eddd3826a1a0190e5235703d1e666affa4d13b96 upstream.

Dmitry Vyukov reported the following using trinity and the memory
error detector AddressSanitizer
(https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel).

[ 124.575597] ERROR: AddressSanitizer: heap-buffer-overflow on
address ffff88002e280000
[ 124.576801] ffff88002e280000 is located 131938492886538 bytes to
the left of 28857600-byte region [ffffffff81282e0a, ffffffff82e0830a)
[ 124.578633] Accessed by thread T10915:
[ 124.579295] inlined in describe_heap_address
./arch/x86/mm/asan/report.c:164
[ 124.579295] #0 ffffffff810dd277 in asan_report_error
./arch/x86/mm/asan/report.c:278
[ 124.580137] #1 ffffffff810dc6a0 in asan_check_region
./arch/x86/mm/asan/asan.c:37
[ 124.581050] #2 ffffffff810dd423 in __tsan_read8 ??:0
[ 124.581893] #3 ffffffff8107c093 in get_wchan
./arch/x86/kernel/process_64.c:444

The address checks in the 64bit implementation of get_wchan() are
wrong in several ways:

 - The lower bound of the stack is not the start of the stack
   page. It's the start of the stack page plus sizeof (struct
   thread_info)

 - The upper bound must be:

       top_of_stack - TOP_OF_KERNEL_STACK_PADDING - 2 * sizeof(unsigned long).

   The 2 * sizeof(unsigned long) is required because the stack pointer
   points at the frame pointer. The layout on the stack is: ... IP FP
   ... IP FP. So we need to make sure that both IP and FP are in the
   bounds.

Fix the bound checks and get rid of the mix of numeric constants, u64
and unsigned long. Making all unsigned long allows us to use the same
function for 32bit as well.

Use READ_ONCE() when accessing the stack. This does not prevent a
concurrent wakeup of the task and the stack changing, but at least it
avoids TOCTOU.

Also check task state at the end of the loop. Again that does not
prevent concurrent changes, but it avoids walking for nothing.

Add proper comments while at it.

Reported-by: Dmitry Vyukov <dvyukov@google.com>
Reported-by: Sasha Levin <sasha.levin@oracle.com>
Based-on-patch-from: Wolfram Gloger <wmglo@dent.med.uni-muenchen.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Borislav Petkov <bp@alien8.de>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Andrey Konovalov <andreyknvl@google.com>
Cc: Kostya Serebryany <kcc@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: kasan-dev <kasan-dev@googlegroups.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Wolfram Gloger <wmglo@dent.med.uni-muenchen.de>
Link: http://lkml.kernel.org/r/20150930083302.694788319@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[bwh: Backported to 3.2:
 - s/READ_ONCE/ACCESS_ONCE/
 - Remove use of TOP_OF_KERNEL_STACK_PADDING, not defined here and would
   be defined as 0]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 arch/x86/kernel/process_64.c | 52 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 42 insertions(+), 10 deletions(-)

--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -555,27 +555,59 @@ void set_personality_ia32(void)
 	current_thread_info()->status |= TS_COMPAT;
 }
 
+/*
+ * Called from fs/proc with a reference on @p to find the function
+ * which called into schedule(). This needs to be done carefully
+ * because the task might wake up and we might look at a stack
+ * changing under us.
+ */
 unsigned long get_wchan(struct task_struct *p)
 {
-	unsigned long stack;
-	u64 fp, ip;
+	unsigned long start, bottom, top, sp, fp, ip;
 	int count = 0;
 
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
-	stack = (unsigned long)task_stack_page(p);
-	if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
+
+	start = (unsigned long)task_stack_page(p);
+	if (!start)
 		return 0;
-	fp = *(u64 *)(p->thread.sp);
+
+	/*
+	 * Layout of the stack page:
+	 *
+	 * ----------- topmax = start + THREAD_SIZE - sizeof(unsigned long)
+	 * PADDING
+	 * ----------- top = topmax - TOP_OF_KERNEL_STACK_PADDING
+	 * stack
+	 * ----------- bottom = start + sizeof(thread_info)
+	 * thread_info
+	 * ----------- start
+	 *
+	 * The tasks stack pointer points at the location where the
+	 * framepointer is stored. The data on the stack is:
+	 * ... IP FP ... IP FP
+	 *
+	 * We need to read FP and IP, so we need to adjust the upper
+	 * bound by another unsigned long.
+	 */
+	top = start + THREAD_SIZE;
+	top -= 2 * sizeof(unsigned long);
+	bottom = start + sizeof(struct thread_info);
+
+	sp = ACCESS_ONCE(p->thread.sp);
+	if (sp < bottom || sp > top)
+		return 0;
+
+	fp = ACCESS_ONCE(*(unsigned long *)sp);
 	do {
-		if (fp < (unsigned long)stack ||
-		    fp >= (unsigned long)stack+THREAD_SIZE)
+		if (fp < bottom || fp > top)
 			return 0;
-		ip = *(u64 *)(fp+8);
+		ip = ACCESS_ONCE(*(unsigned long *)(fp + sizeof(unsigned long)));
 		if (!in_sched_functions(ip))
 			return ip;
-		fp = *(u64 *)fp;
-	} while (count++ < 16);
+		fp = ACCESS_ONCE(*(unsigned long *)fp);
+	} while (count++ < 16 && p->state != TASK_RUNNING);
 	return 0;
 }
 


  parent reply	other threads:[~2015-11-15  2:08 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-15  1:45 [PATCH 3.2 00/60] 3.2.73-rc1 review Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 07/60] x86/xen: Do not clip xen_e820_map to xen_e820_map_entries when sanitizing map Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 30/60] crypto: ahash - ensure statesize is non-zero Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 31/60] iommu/vt-d: fix range computation when making room for large pages Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 22/60] drivers/tty: require read access for controlling terminal Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 37/60] ASoC: wm8904: Correct number of EQ registers Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 27/60] 3w-9xxx: don't unmap bounce buffered commands Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 49/60] mvsas: Fix NULL pointer dereference in mvs_slot_task_free Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 39/60] drm/nouveau/gem: return only valid domain when there's only one Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 10/60] MIPS: dma-default: Fix 32-bit fall back to GFP_DMA Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 45/60] md/raid1: ensure device failure recorded before write request returns Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 25/60] ALSA: synth: Fix conflicting OSS device registration on AWE32 Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 50/60] sched: declare pid_alive as inline Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 53/60] skbuff: Fix skb checksum partial check Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 19/60] USB: Add reset-resume quirk for two Plantronics usb headphones Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 12/60] genirq: Fix race in register_irq_proc() Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 06/60] m68k: Define asmlinkage_protect Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 54/60] ethtool: Use kcalloc instead of kmalloc for ethtool_get_strings Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 55/60] asix: Don't reset PHY on if_up for ASIX 88772 Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 28/60] xen-blkfront: check for null drvdata in blkback_changed (XenbusStateClosing) Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 57/60] Failing to send a CLOSE if file is opened WRONLY and server reboots on a 4.x mount Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 23/60] ppp: don't override sk->sk_state in pppoe_flush_dev() Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 59/60] KEYS: Fix race between key destruction and finding a keyring by name Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 02/60] module: Fix locking in symbol_put_addr() Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 08/60] UBI: Validate data_size Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 03/60] regmap: debugfs: Ensure we don't underflow when printing access masks Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 40/60] powerpc/rtas: Validate rtas.entry before calling enter_rtas() Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 33/60] xhci: handle no ping response error properly Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 47/60] md/raid10: ensure device failure recorded before write request returns Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 05/60] ath9k: declare required extra tx headroom Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 29/60] ALSA: hda - Fix inverted internal mic on Lenovo G50-80 Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 38/60] IB/cm: Fix rb-tree duplicate free and use-after-free Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 34/60] xhci: Switch Intel Lynx Point LP ports to EHCI on shutdown Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 35/60] xhci: Add spurious wakeup quirk for LynxPoint-LP controllers Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 56/60] asix: Do full reset during ax88772_bind Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 32/60] xhci: don't finish a TD if we get a short transfer event mid TD Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 17/60] clocksource: Fix abs() usage w/ 64bit values Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 43/60] dm btree remove: fix a bug when rebalancing nodes after removal Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 60/60] KEYS: Fix crash when attempt to garbage collect an uninstantiated keyring Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 51/60] net: add length argument to skb_copy_and_csum_datagram_iovec Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 46/60] md/raid1: don't clear bitmap bit when bad-block-list write fails Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 01/60] Revert "KVM: MMU: fix validation of mmio page fault" Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 18/60] iio: accel: sca3000: memory corruption in sca3000_read_first_n_hw_rb() Ben Hutchings
2015-11-15  1:45 ` Ben Hutchings [this message]
2015-11-15  1:45 ` [PATCH 3.2 48/60] md/raid10: don't clear bitmap bit when bad-block-list write fails Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 26/60] sched/core: Fix TASK_DEAD race in finish_task_switch() Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 20/60] usb: Add device quirk for Logitech PTZ cameras Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 14/60] [SMB3] Do not fall back to SMBWriteX in set_file_size error cases Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 09/60] UBI: return ENOSPC if no enough space available Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 44/60] dm btree: fix leak of bufio-backed block in btree_split_beneath error path Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 04/60] regmap: debugfs: Don't bother actually printing when calculating max length Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 15/60] md/raid0: update queue parameter in a safer location Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 24/60] iwlwifi: dvm: fix D3 firmware PN programming Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 42/60] ppp: fix pppoe_dev deletion condition in pppoe_release() Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 13/60] mm: hugetlbfs: skip shared VMAs when unmapping private pages to satisfy a fault Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 36/60] crypto: api - Only abort operations on fatal signal Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 58/60] KVM: x86: work around infinite loop in microcode when #AC is delivered Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 21/60] tty: fix stall caused by missing memory barrier in drivers/tty/n_tty.c Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 41/60] mm: make sendfile(2) killable Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 52/60] skbuff: Fix skb checksum flag on skb pull Ben Hutchings
2015-11-15  1:45 ` [PATCH 3.2 16/60] md/raid0: apply base queue limits *before* disk_stack_limits Ben Hutchings
2015-11-15  2:29 ` [PATCH 3.2 00/60] 3.2.73-rc1 review Ben Hutchings
2015-11-15 13:42 ` Guenter Roeck
2015-11-16 11:11   ` Ben Hutchings

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=lsq.1447551945.331070837@decadent.org.uk \
    --to=ben@decadent.org.uk \
    --cc=ak@linux.intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=andreyknvl@google.com \
    --cc=bp@alien8.de \
    --cc=dvlasenk@redhat.com \
    --cc=dvyukov@google.com \
    --cc=glider@google.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=kcc@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=ryabinin.a.a@gmail.com \
    --cc=sasha.levin@oracle.com \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=wmglo@dent.med.uni-muenchen.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®