public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Miles Chen <miles.chen@mediatek.com>
To: Christoph Hellwig <hch@lst.de>, "David S . Miller" <davem@davemloft.net>
Cc: <linux-kernel@vger.kernel.org>,
	<linux-mediatek@lists.infradead.org>, <wsd_upstream@mediatek.com>,
	Miles Chen <miles.chen@mediatek.com>
Subject: [PATCH] net: untag pointer in sockptr_is_kernel
Date: Tue, 11 Aug 2020 18:27:04 +0800	[thread overview]
Message-ID: <20200811102704.17875-1-miles.chen@mediatek.com> (raw)

From: Miles Chen <miles.chen@mediatek.com>

sockptr_is_kernel() uses (sockptr.kernel >= TASK_SIZE) to tell
if the pointer is kernel space or user space. When user space uses
the "top byte ignored" feature such as HWAsan, we must untag
the pointer before checking against TASK_SIZE.

sockptr_is_kernel() will view a tagged user pointer as a kernel pointer
and use memcpy directly and causes a kernel crash.

static inline int copy_from_sockptr_offset(void *dst, sockptr_t src,
		size_t offset, size_t size)
{
	if (!sockptr_is_kernel(src))
		return copy_from_user(dst, src.user + offset, size);
	memcpy(dst, src.kernel + offset, size);
	return 0;
}

Crash log:
[   26.066275] Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000007b410f6990
[   26.067640] Mem abort info:
[   26.068004]   ESR = 0x9600000f
[   26.068400]   EC = 0x25: DABT (current EL), IL = 32 bits
[   26.084406]   SET = 0, FnV = 0
[   26.084805]   EA = 0, S1PTW = 0
[   26.085310] Data abort info:
[   26.085686]   ISV = 0, ISS = 0x0000000f
[   26.086179]   CM = 0, WnR = 0
[   26.086565] user pgtable: 4k pages, 39-bit VAs, pgdp=00000001feb7c000
[   26.087386] [0000007b410f6990] pgd=0000000201ac2003, p4d=0000000201ac2003, pud=0000000201ac2003, pmd=00000001fd58a003, pte=00e80001fca7bf53
[   26.089111] Internal error: Oops: 9600000f [#1] PREEMPT SMP
[   30.435941] pstate: 80400005 (Nzcv daif +PAN -UAO BTYPE=--)
[   30.435950] pc : __memcpy+0xbc/0x180
[   30.435956] lr : copy_from_sockptr_offset+0x120/0x298
[   30.435960] sp : ffffffc0179438d0
[   30.441225] x29: ffffffc0179438d0 x28: ffffff81bf579940
[   30.441898] x27: ffffffd24a752bc0 x26: ffffffc0179439b0
[   30.442572] x25: ffffffd24a75dd60 x24: 0000000000000002
[   30.443247] x23: ffffff81bf579940 x22: 0000000000000000
[   30.443919] x21: b400007a2e8749f0 x20: ffffffc0179439b0
[   30.444592] x19: 0000000000000060 x18: 0000000000000000
[   30.445264] x17: 0000000000000000 x16: 0000000000000000
[   30.445937] x15: 0000000000000552 x14: 00000000ba02a83b
[   30.446609] x13: 0000000045fb4ba9 x12: 00000000e5d1c812
[   30.447281] x11: 0000000000019cde x10: 0000000000000001
[   30.447952] x9 : 00000000fffff000 x8 : 0000008000000000
[   30.448625] x7 : ffffffd24932449c x6 : ffffffc0179439b0
[   30.449295] x5 : 0000000000000000 x4 : 0000000000000000
[   30.449967] x3 : 0000000000000060 x2 : ffffffffffffffe0
[   30.450639] x1 : b400007a2e8749f0 x0 : ffffffc0179439b0
[   30.451310] Call trace:
[   30.451628]  __memcpy+0xbc/0x180
[   30.452039]  do_ipt_set_ctl+0x88/0xa48
[   30.452520]  nf_setsockopt+0xc4/0x104
[   30.452988]  ip_setsockopt+0x128/0xfa8
[   30.453466]  raw_setsockopt+0x48/0x2c0
[   30.453944]  sock_common_setsockopt+0x18/0x20
[   30.454497]  __sys_setsockopt+0x144/0x1ec
[   30.455005]  __arm64_sys_setsockopt+0x24/0x30
[   30.455560]  el0_svc_common+0xa0/0x18c
[   30.456039]  do_el0_svc+0x78/0x80
[   30.456462]  el0_sync_handler+0xec/0x2b8
[   30.456960]  el0_sync+0x144/0x180
[   30.457386] Code: 380014c3 14000028 f1020042 5400024a (a8c12027)
[   30.458156] ---[ end trace a53f2349dbbd41cd ]---
[   30.465290] Kernel panic - not syncing: Fatal exception

Signed-off-by: Miles Chen <miles.chen@mediatek.com>
Fixes: 6d04fe15f78a ("net: optimize the sockptr_t for unified kernel/user address spaces")
---
 include/linux/sockptr.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/sockptr.h b/include/linux/sockptr.h
index 96840def9d69..3febc4da1056 100644
--- a/include/linux/sockptr.h
+++ b/include/linux/sockptr.h
@@ -20,7 +20,7 @@ typedef union {
 
 static inline bool sockptr_is_kernel(sockptr_t sockptr)
 {
-	return (unsigned long)sockptr.kernel >= TASK_SIZE;
+	return (unsigned long)untagged_addr(sockptr.kernel) >= TASK_SIZE;
 }
 
 static inline sockptr_t KERNEL_SOCKPTR(void *p)
-- 
2.18.0


             reply	other threads:[~2020-08-11 10:27 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-11 10:27 Miles Chen [this message]
2020-08-11 11:15 ` [PATCH] net: untag pointer in sockptr_is_kernel Christoph Hellwig
2020-08-11 11:44   ` David Laight
2020-08-12  9:15     ` Miles Chen
2020-08-12  9:48       ` David Laight
2020-08-11 12:24 ` kernel test robot
2020-08-11 12:28 ` kernel test robot
2020-08-12  9:17   ` Miles Chen

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=20200811102704.17875-1-miles.chen@mediatek.com \
    --to=miles.chen@mediatek.com \
    --cc=davem@davemloft.net \
    --cc=hch@lst.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=wsd_upstream@mediatek.com \
    /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