Thread (7 messages) flat view 7 messages, 6 authors, 2018-10-29

[PATCH] arm64: kprobe: make page to RO mode when allocate it

From: Will Deacon <hidden>
Date: 2018-10-29 17:02:22
Also in: lkml

On Mon, Oct 29, 2018 at 01:11:24PM +0100, Arnd Bergmann wrote:
On 10/29/18, Will Deacon [off-list ref] wrote:
quoted
On Mon, Oct 15, 2018 at 01:16:00PM +0200, Anders Roxell wrote:
quoted
quoted
-static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)
+void *alloc_insn_page(void)
 {
-	void *addrs[1];
-	u32 insns[1];
+	void *page;

-	addrs[0] = (void *)addr;
-	insns[0] = (u32)opcode;
+	page = vmalloc_exec(PAGE_SIZE);
+	if (page)
+		set_memory_ro((unsigned long)page & PAGE_MASK, 1);
This looks a bit strange to me -- you're allocating PAGE_SIZE bytes so
that we can adjust the permissions, yet we can't guarantee that page is
actually page-aligned and therefore end up explicitly masking down.

In which case allocating an entire page isn't actually helping us, and
we could end up racing with somebody else changing permission on the
same page afaict.

I think we need to ensure we really have an entire page, perhaps using
vmap() instead? Or have I missed some subtle detail here?
I'm fairly sure that vmalloc() and vmalloc_exec() is guaranteed to be page
aligned everywhere. The documentation is a bit vague here, but I'm
still confident enough that we can make that assumption based on

/**
 *      vmalloc_exec  -  allocate virtually contiguous, executable memory
 *      @size:          allocation size
 *
 *      Kernel-internal function to allocate enough pages to cover @size
 *      the page level allocator and map them into contiguous and
 *      executable kernel virtual space.
 *
 *      For tight control over page level allocator and protection flags
 *      use __vmalloc() instead.
 */
void *vmalloc_exec(unsigned long size)
FWIW, I did a bit of digging and I agree with your conclusion. vmalloc()
allocations end up getting installed in map_vm_area() via
__vmalloc_area_node(), which allocates things a page at a time.

So we can simplify this patch to drop the masking when calling
set_memory_ro().

Will
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help