Subject: [RFC PATCH] uprobes: copy to user-space xol page with proper cache flushing

From: [email-masked] (Oleg Nesterov)
Date: Fri, 11 Apr 2014 19:38:53 +0200

On 04/11, Oleg Nesterov wrote:
>
> +static void arch_uprobe_copy_ixol(struct xol_area *area, unsigned long vaddr,
> +				 	struct arch_uprobe *auprobe)
> +{
> +#ifndef ARCH_UPROBE_XXX
> +	copy_to_page(area->page, vaddr, &auprobe->ixol, sizeof(&auprobe->ixol));
> +	/*
> +	 * We probably need flush_icache_user_range() but it needs vma.
> +	 * If this doesn't work define ARCH_UPROBE_XXX.
> +	 */
> +	flush_dcache_page(area->page);
> +#else
> +	struct mm_struct *mm = current->mm;
> +	struct vm_area_struct *vma;
> +
> +	down_read(&mm->mmap_sem);
> +	vma = find_exact_vma(mm, area->vaddr, area->vaddr + PAGE_SIZE);
> +	if (vma) {
> +		void *kaddr = kmap_atomic(area->page);
> +		copy_to_user_page(vma, area->page,
> +					vaddr, kaddr + (vaddr & ~PAGE_MASK),
> +					&auprobe->ixol, sizeof(&auprobe->ixol));
> +		kunmap_atomic(kaddr);
> +	}
> +	up_read(&mm->mmap_sem);
> +#endif

And perhaps the patch is not complete. "if (vma)" is not enough, a probed
task can mmap something else at this vaddr.

copy_to_user_page() should only change the contents of area->page, so memcpy
should be fine. But I am not sure that flush_icache_user_range() or
flush_ptrace_access() is always safe on every arch if "struct page *page"
doesn't match vma.

Oleg.