From patchwork Thu Apr 2 08:40:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Russell Currey X-Patchwork-Id: 11470641 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 29AD781 for ; Thu, 2 Apr 2020 12:32:34 +0000 (UTC) Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.kernel.org (Postfix) with SMTP id 871FA20757 for ; Thu, 2 Apr 2020 12:32:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=russell.cc header.i=@russell.cc header.b="tHKWzO/Y"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="zggeFAj9" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 871FA20757 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=russell.cc Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=kernel-hardening-return-18372-patchwork-kernel-hardening=patchwork.kernel.org@lists.openwall.com Received: (qmail 9721 invoked by uid 550); 2 Apr 2020 12:31:55 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 9487 invoked from network); 2 Apr 2020 12:31:49 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=russell.cc; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm1; bh=GOZVk5Fsc5eI2 5Khq7lhjYKWFmMeiiNzwmpYuMZHgMk=; b=tHKWzO/YKIoeg/m4Ct5GMas6HWb+D vSlMm5IFk1yy4M/idFQxdK/RNpRsYtc5CxLucH653PuHO4p26HwU6xHFF6SAuQsF mOYHXroqe+D7zQyIkhyb9U639u4heZOdbGNnwLXB2ctIRhfKwIDIqq2kauCD7QSb R10rXQdtFueXC5vO7VDCQ9m+VsSkSl/aEkwZDTale86hIBAcCKFyqIHwotzUy54Z 6D/6RQud1uX6wQBrZugQy+uRFv3DDTCrF43sZuFpAAUlTZdQFlRSmB9byeHz9tf9 xJQB4gkYoqd8tfSOpH2Kdg1245hcygl7VagRi7yjwAgs+iJYNnVR2uScQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding: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= fm2; bh=GOZVk5Fsc5eI25Khq7lhjYKWFmMeiiNzwmpYuMZHgMk=; b=zggeFAj9 MQCctEYeTljjKugBIcF4pEYMp+NLt6pvoiOpZGt9KIHbxMghg22wNSITvAWFdGUQ gySd3KNWuJoM/jcQgiYRRtyjYEKfJDZgQLEfX2YlxP8QmUfVysRO1uRjcH9khEzY OPTmbp7/VK8qjQqpdZwhc0Q2BQZj36y5Babt2+69F2CTSakdyt5+7a+EWadcEZq8 BZpA7vv33Q37aZbCMgMaZFYyj5uEjPp0eDN53Ywni1qwzsej1mvnerwm9B/wqgSS rT17SqBPnKPQhjnm9mMqDK6nU/P/Pkhfyovv2oRWg9zqCIM1lInmz5V/JOr1WSWI sHOTVGOdTCcVOw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduhedrtdeggddtgecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecufghrlhcuvffnffculddutddmnecujfgurhephffvuf ffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpeftuhhsshgvlhhlucevuhhrrhgv hicuoehruhhstghurhesrhhushhsvghllhdrtggtqeenucfkphepuddvuddrgeehrddvud dvrddvfeelnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhho mheprhhushgtuhhrsehruhhsshgvlhhlrdgttg X-ME-Proxy: From: Russell Currey To: linuxppc-dev@lists.ozlabs.org Cc: Russell Currey , christophe.leroy@c-s.fr, mpe@ellerman.id.au, ajd@linux.ibm.com, dja@axtens.net, npiggin@gmail.com, kernel-hardening@lists.openwall.com Subject: [PATCH v8 2/7] powerpc/kprobes: Mark newly allocated probes as RO Date: Thu, 2 Apr 2020 19:40:47 +1100 Message-Id: <20200402084053.188537-2-ruscur@russell.cc> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200402084053.188537-1-ruscur@russell.cc> References: <20200402084053.188537-1-ruscur@russell.cc> MIME-Version: 1.0 With CONFIG_STRICT_KERNEL_RWX=y and CONFIG_KPROBES=y, there will be one W+X page at boot by default. This can be tested with CONFIG_PPC_PTDUMP=y and CONFIG_PPC_DEBUG_WX=y set, and checking the kernel log during boot. powerpc doesn't implement its own alloc() for kprobes like other architectures do, but we couldn't immediately mark RO anyway since we do a memcpy to the page we allocate later. After that, nothing should be allowed to modify the page, and write permissions are removed well before the kprobe is armed. The memcpy() would fail if >1 probes were allocated, so use patch_instruction() instead which is safe for RO. Reviewed-by: Daniel Axtens Signed-off-by: Russell Currey Signed-off-by: Christophe Leroy --- arch/powerpc/kernel/kprobes.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 81efb605113e..fa4502b4de35 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); @@ -102,6 +104,16 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset) return addr; } +void *alloc_insn_page(void) +{ + void *page = vmalloc_exec(PAGE_SIZE); + + if (page) + set_memory_ro((unsigned long)page, 1); + + return page; +} + int arch_prepare_kprobe(struct kprobe *p) { int ret = 0; @@ -124,11 +136,8 @@ int arch_prepare_kprobe(struct kprobe *p) } if (!ret) { - memcpy(p->ainsn.insn, p->addr, - MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); + patch_instruction(p->ainsn.insn, *p->addr); p->opcode = *p->addr; - flush_icache_range((unsigned long)p->ainsn.insn, - (unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t)); } p->ainsn.boostable = 0;