Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp313643ybl; Thu, 30 Jan 2020 22:56:12 -0800 (PST) X-Google-Smtp-Source: APXvYqzqww15xFDWn4IGlO9pmBY/lJGdV4gSaKDv+wSnS+nmpNgb8DOTVCfggHNNRmtejmfE+GkL X-Received: by 2002:a9d:268:: with SMTP id 95mr6625830otb.183.1580453772362; Thu, 30 Jan 2020 22:56:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1580453772; cv=none; d=google.com; s=arc-20160816; b=M5JJpNmBDFCCSY/DQhEC5qN6tkHFH0/FEzjRb8fbhHmdjJR77JtOC5+z0iaov219hj /pq1qordlDhbTut73h6WBeZ/Gci0EpGkTjEC3TerNTtZYQeJK/aobmaswncdkbHk4cZT WnNH99I862yp0lEzNoUvGQbX+VoiLnsqBNcVLoCGRsVyCN2zG8Q/A53vBUiENNQAO/8u 8a2lw8y2huzPCHvWMNNof0CAbMEIFDoRdNe0o1zRfTWx63j58+qDcUdl7+QdxOX965ZG fbKhzALa5NWSYA9xNx/3gPo2zXIHfCw7oXf2490nj5xJ+rxbrRrkYa+09rxXQRFhxDt8 TfdA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:date:cc:to:from:subject :message-id:dkim-signature:dkim-signature; bh=PK1pmpuptvT5/MkvhBVcvSK+hqg9sA+88hLtr2Io7nw=; b=uVqNkArs/NqGzeBSASiBMCTUKtEZ26kpdQGhDqK3GSC7ptWf7YbWtTvEZue7YqrV9f Kfmsxt0s6QxHhhuMp4r8f9HbJaCc3ljRxkoUPIT0/mVZQUhZI18PQ9XQJMW80sJDaa+T f4XG6OXYXruo7pMPFpmEjtfABwxlwz+SKi5bOGKJTbSz5bT+ZsEr2vF9yB+dNwkLXtey o9CrsKhruQkCPSx1hq8tSUvGxUlyPsliMewe9DVMmNzSamNWuDhibcgh2oE81Z8RIRTs KVA2PBTdYgPIwbMQ1clMmprO6iNeu9fsJkEntRY9OZ0dpGJmO8tVjw53JOH0lA6Aw3VZ Gq0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@russell.cc header.s=fm1 header.b=o5YxGTLi; dkim=pass header.i=@messagingengine.com header.s=fm1 header.b=o8YI7DDa; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l20si4085207otd.292.2020.01.30.22.55.59; Thu, 30 Jan 2020 22:56:12 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@russell.cc header.s=fm1 header.b=o5YxGTLi; dkim=pass header.i=@messagingengine.com header.s=fm1 header.b=o8YI7DDa; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728079AbgAaGxW (ORCPT + 99 others); Fri, 31 Jan 2020 01:53:22 -0500 Received: from wout1-smtp.messagingengine.com ([64.147.123.24]:51507 "EHLO wout1-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726127AbgAaGxW (ORCPT ); Fri, 31 Jan 2020 01:53:22 -0500 Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.west.internal (Postfix) with ESMTP id 17DE77C6; Fri, 31 Jan 2020 01:53:21 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute1.internal (MEProxy); Fri, 31 Jan 2020 01:53:21 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=russell.cc; h= message-id:subject:from:to:cc:date:in-reply-to:references :content-type:mime-version:content-transfer-encoding; s=fm1; bh= PK1pmpuptvT5/MkvhBVcvSK+hqg9sA+88hLtr2Io7nw=; b=o5YxGTLi4sIrJXoo ugd2krrWcg64RFmiqJ6tdkiGc+adzeQ5z4ig6QeuAXfutLZu11Bc36G1UXTaOgsw McqAYwaYsI3d31F5bgjRfskD3QNOmNqWiQG1R3ZwWRmBJs9HQ6nxHd+Jr7w9rDwT TsrXMVIwp5ZowfFbIZuI/ZIAMwSyUTu6Ty3Hk+YQsjFZMyjyykhWXH2QHNFuNwxh ESpv/hHIuNWv8FfgrY5OY+iDHNtvScWNLCG1GgKPmNALsiXfqqMf7GaZt8UrwwL/ 0tXc0BlHl7E8Xao68bTmHg61lA9Do2j7OFxy5OnuBif1zPDj10vQrYeui+CfdelB DdXdbw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm1; bh=PK1pmpuptvT5/MkvhBVcvSK+hqg9sA+88hLtr2Io7 nw=; b=o8YI7DDaHYTjKgapJwAjfU8XvzA5klTJrByUtPe78PgrHGM7HTS1QawvQ 16SAxyiDIIyl0S8pefOn24dXAcLIQmfHVr/0CBXKmeSzkZ6lwCUlm63CIFNLEYcT l+OVW2JwxEmXrl04JtL10DqHdt4lHyho8/ADXrmUjmLPYpdIQJoycdswXMM/zV7Z C7soOieAJSFDjaobkbgTqmsgn2WPiVeTIzxwl9Tr0ot62gTb8XiOJjN3fH3faalM bf9EbN4gx7PPYjL/C6eRJp72AGezAybDKYhpuX07yLRNA7vAGRhoUeXxOtcPrRcR gYd7tEpSqRET554+IRCWJLcZiAm3g== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedugedrfeelgdeliecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenfg hrlhcuvffnffculdduhedmnecujfgurhepkffuhffvffgjfhgtfggggfesthekredttder jeenucfhrhhomheptfhushhsvghllhcuvehurhhrvgihuceorhhushgtuhhrsehruhhssh gvlhhlrdgttgeqnecuffhomhgrihhnpehoiihlrggsshdrohhrghenucfkphepuddvvddr leelrdekvddruddtnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilh hfrhhomheprhhushgtuhhrsehruhhsshgvlhhlrdgttg X-ME-Proxy: Received: from crackle.ozlabs.ibm.com (unknown [122.99.82.10]) by mail.messagingengine.com (Postfix) with ESMTPA id 54FA230607B0; Fri, 31 Jan 2020 01:53:17 -0500 (EST) Message-ID: <0b016861756cbe27e66651b5c21229a06558cb57.camel@russell.cc> Subject: Re: [PATCH] lkdtm: Test KUAP directional user access unlocks on powerpc From: Russell Currey To: Christophe Leroy , keescook@chromium.org, mpe@ellerman.id.au Cc: linux-kernel@vger.kernel.org, dja@axtens.net, kernel-hardening@lists.openwall.com, linuxppc-dev@lists.ozlabs.org Date: Fri, 31 Jan 2020 17:53:14 +1100 In-Reply-To: <1b40cea6-0675-731a-58b1-bdc65f1e495e@c-s.fr> References: <20200131053157.22463-1-ruscur@russell.cc> <1b40cea6-0675-731a-58b1-bdc65f1e495e@c-s.fr> Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.34.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, 2020-01-31 at 07:44 +0100, Christophe Leroy wrote: > > Le 31/01/2020 à 06:31, Russell Currey a écrit : > > Kernel Userspace Access Prevention (KUAP) on powerpc supports > > allowing only one access direction (Read or Write) when allowing > > access > > to or from user memory. > > > > A bug was recently found that showed that these one-way unlocks > > never > > worked, and allowing Read *or* Write would actually unlock Read > > *and* > > Write. We should have a test case for this so we can make sure > > this > > doesn't happen again. > > > > Like ACCESS_USERSPACE, the correct result is for the test to fault. > > > > At the time of writing this, the upstream kernel still has this bug > > present, so the test will allow both accesses whereas > > ACCESS_USERSPACE > > will correctly fault. > > > > Signed-off-by: Russell Currey > > --- > > drivers/misc/lkdtm/core.c | 3 +++ > > drivers/misc/lkdtm/lkdtm.h | 3 +++ > > drivers/misc/lkdtm/perms.c | 43 > > ++++++++++++++++++++++++++++++++++++++ > > 3 files changed, 49 insertions(+) > > > > diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c > > index ee0d6e721441..baef3c6f48d6 100644 > > --- a/drivers/misc/lkdtm/core.c > > +++ b/drivers/misc/lkdtm/core.c > > @@ -137,6 +137,9 @@ static const struct crashtype crashtypes[] = { > > CRASHTYPE(EXEC_USERSPACE), > > CRASHTYPE(EXEC_NULL), > > CRASHTYPE(ACCESS_USERSPACE), > > +#ifdef CONFIG_PPC_KUAP > > + CRASHTYPE(ACCESS_USERSPACE_KUAP), > > +#endif > > I'm not sure it is a good idea to build this test as a specific test > for > powerpc, more comments below. > > > CRASHTYPE(ACCESS_NULL), > > CRASHTYPE(WRITE_RO), > > CRASHTYPE(WRITE_RO_AFTER_INIT), > > diff --git a/drivers/misc/lkdtm/lkdtm.h > > b/drivers/misc/lkdtm/lkdtm.h > > index c56d23e37643..406a3fb32e6f 100644 > > --- a/drivers/misc/lkdtm/lkdtm.h > > +++ b/drivers/misc/lkdtm/lkdtm.h > > @@ -57,6 +57,9 @@ void lkdtm_EXEC_RODATA(void); > > void lkdtm_EXEC_USERSPACE(void); > > void lkdtm_EXEC_NULL(void); > > void lkdtm_ACCESS_USERSPACE(void); > > +#ifdef CONFIG_PPC_KUAP > > +void lkdtm_ACCESS_USERSPACE_KUAP(void); > > +#endif > > void lkdtm_ACCESS_NULL(void); > > > > /* lkdtm_refcount.c */ > > diff --git a/drivers/misc/lkdtm/perms.c > > b/drivers/misc/lkdtm/perms.c > > index 62f76d506f04..2c9aa0114333 100644 > > --- a/drivers/misc/lkdtm/perms.c > > +++ b/drivers/misc/lkdtm/perms.c > > @@ -10,6 +10,9 @@ > > #include > > #include > > #include > > +#ifdef CONFIG_PPC_KUAP > > +#include > > +#endif > > asm/uaccess.h is already included by linux/uaccess.h I should have actually read the other includes rather than assuming I needed this, pretty silly > > > > > /* Whether or not to fill the target memory area with > > do_nothing(). */ > > #define CODE_WRITE true > > @@ -200,6 +203,46 @@ void lkdtm_ACCESS_USERSPACE(void) > > vm_munmap(user_addr, PAGE_SIZE); > > } > > > > +/* Test that KUAP's directional user access unlocks work as > > intended */ > > +#ifdef CONFIG_PPC_KUAP > > +void lkdtm_ACCESS_USERSPACE_KUAP(void) > > +{ > > + unsigned long user_addr, tmp = 0; > > + unsigned long *ptr; > > Should be a __user ptr because allow_write_to_user() and friends > takes > __user pointers. > > > + > > + user_addr = vm_mmap(NULL, 0, PAGE_SIZE, > > + PROT_READ | PROT_WRITE | PROT_EXEC, > > + MAP_ANONYMOUS | MAP_PRIVATE, 0); > > + if (user_addr >= TASK_SIZE) { > > Should use IS_ERR_VALUE() here. > > > + pr_warn("Failed to allocate user memory\n"); > > + return; > > + } > > + > > + if (copy_to_user((void __user *)user_addr, &tmp, sizeof(tmp))) > > { > > Should use ptr instead of casted user_addr. > > Why using copy_to_user() for writing an unsigned long ? put_user() > should be enough. > > > + pr_warn("copy_to_user failed\n"); > > + vm_munmap(user_addr, PAGE_SIZE); > > + return; > > + } > > + > > + ptr = (unsigned long *)user_addr; > > move before copy_to_user() and use there. All of the above is from the original ACCESS_USERSPACE test, not to imply that it's perfect, but I'm not sure it's worth changing in one place only > > > + > > + /* Allowing "write to" should not allow "read from" */ > > + allow_write_to_user(ptr, sizeof(unsigned long)); > > This is powerpc specific. I think we should build this around the > user_access_begin()/user_access_end() generic fonctions. > > I'm about to propose an enhancement to this in order to allow > unlocking > only read or write. See discussion at > https://patchwork.ozlabs.org/patch/1227926/. > > My plan is to propose my enhancement once powerpc implementation of > user_access_begin stuff is merged. I don't know if Michael is still > planning to merge the series for 5.6 > (https://patchwork.ozlabs.org/patch/1228801/ - patch 1 of the series > has > already been merged by Linus in 5.5) You're correct, making generic user_access_begin() calls aware of direction solves the arch-specific problem, so unless your series somehow ends up being unviable (or taking a very long time to get merged) we can drop this idea and have a generic implementation instead. > > > > + pr_info("attempting bad read at %px with write allowed\n", > > ptr); > > + tmp = *ptr; > > + tmp += 0xc0dec0de; > > + prevent_write_to_user(ptr, sizeof(unsigned long)); > > Does it work ? I would have thought that if the read fails the > process > will die and the following test won't be performed. Correct, the ACCESS_USERSPACE test does the same thing. Splitting this into separate R and W tests makes sense, even if it is unlikely that one would be broken without the other. - Russell > > > + > > + /* Allowing "read from" should not allow "write to" */ > > + allow_read_from_user(ptr, sizeof(unsigned long)); > > + pr_info("attempting bad write at %px with read allowed\n", > > ptr); > > + *ptr = tmp; > > + prevent_read_from_user(ptr, sizeof(unsigned long)); > > + > > + vm_munmap(user_addr, PAGE_SIZE); > > +} > > +#endif > > + > > void lkdtm_ACCESS_NULL(void) > > { > > unsigned long tmp; > > > > Christophe