All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>, Steven Rostedt <rostedt@goodmis.org>,
	Randy Dunlap <rdunlap@xenotime.net>,
	Arnaldo Carvalho de Melo <acme@infradead.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Christoph Hellwig <hch@infradead.org>,
	Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
	Ananth N Mavinakayanahalli <ananth@in.ibm.com>,
	Oleg Nesterov <oleg@redhat.com>, Mark Wielaard <mjw@redhat.com>,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	LKML <linux-kernel@vger.kernel.org>,
	Naren A Devaiah <naren.devaiah@in.ibm.com>,
	Jim Keniston <jkenisto@linux.vnet.ibm.com>,
	Frederic Weisbecker <fweisbec@gmail.com>,
	"Frank Ch. Eigler" <fche@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Subject: Re: [PATCHv11 2.6.36-rc2-tip 2/15]  2: uprobes: Breakpoint insertion/removal in user space applications.
Date: Wed, 01 Sep 2010 21:38:12 +0200	[thread overview]
Message-ID: <1283369892.2059.1493.camel@laptop> (raw)
In-Reply-To: <20100825134141.5447.88627.sendpatchset@localhost6.localdomain6>

On Wed, 2010-08-25 at 19:11 +0530, Srikar Dronamraju wrote:

> +struct user_bkpt_arch_info *arch = &user_bkpt_arch_info;

That really wants to be static, 'arch' is a way too generic a name to
inject in the global namespace.

> +unsigned long uprobes_read_vm(struct task_struct *tsk, void __user *vaddr,
> +					void *kbuf, unsigned long nbytes)
> +{
> +	if (tsk == current) {
> +		unsigned long nleft = copy_from_user(kbuf, vaddr, nbytes);
> +		return nbytes - nleft;
> +	} else
> +		return access_process_vm(tsk, (unsigned long) vaddr, kbuf,
> +							nbytes, 0);
> +}
> +

> +unsigned long uprobes_write_data(struct task_struct *tsk,
> +				void __user *vaddr, const void *kbuf,
> +				unsigned long nbytes)
> +{
> +	unsigned long nleft;
> +
> +	if (tsk == current) {
> +		nleft = copy_to_user(vaddr, kbuf, nbytes);
> +		return nbytes - nleft;
> +	} else
> +		return access_process_vm(tsk, (unsigned long) vaddr,
> +						(void *) kbuf, nbytes, 1);
> +}

either: s/uprobes_read_vm/uprobes_read_data/ or
s/uproves_write_data/uproves_write_vm/

> +static int write_opcode(struct task_struct *tsk, unsigned long vaddr,
> +						user_bkpt_opcode_t opcode)
> +{
> +	struct mm_struct *mm;
> +	struct vm_area_struct *vma;
> +	struct page *old_page, *new_page;
> +	void *vaddr_old, *vaddr_new;
> +	pte_t orig_pte;
> +	int ret = -EINVAL;
> +
> +	if (!tsk)
> +		return ret;
> +
> +	mm = get_task_mm(tsk);
> +	if (!mm)
> +		return ret;
> +
> +	down_read(&mm->mmap_sem);
> +
> +	/* Read the page with vaddr into memory */
> +	ret = get_user_pages(tsk, mm, vaddr, 1, 1, 1, &old_page, &vma);
> +	if (ret <= 0)
> +		goto mmput_out;
> +
> +	/*
> +	 * check if the page we are interested is read-only mapped
> +	 * Since we are interested in text pages, Our pages of interest
> +	 * should be mapped read-only.
> +	 */
> +	if ((vma->vm_flags && (VM_READ|VM_WRITE)) != VM_READ) {

 s/&&/&/

> +		ret = -EINVAL;
> +		goto put_out;
> +	}
> +
> +	/* If its VM_SHARED vma, lets not write to such vma's.  */
> +	if (vma->vm_flags & VM_SHARED) {
> +		ret = -EINVAL;
> +		goto put_out;
> +	}

Something like:

  /* private, read-only, executable maps only */
  if ((vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) != (VM_READ|VM_EXEC))

maybe?

> +	/* Allocate a page */
> +	new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr);
> +	if (!new_page) {
> +		ret = -ENOMEM;
> +		goto put_out;
> +	}

> +int __weak set_orig_insn(struct task_struct *tsk,
> +			struct user_bkpt *user_bkpt, bool verify)
> +{
> +	if (verify) {
> +		user_bkpt_opcode_t opcode;
> +		int result = read_opcode(tsk, user_bkpt->vaddr, &opcode);
> +		if (result)
> +			return result;
> +		if (opcode != arch->bkpt_insn)

This assumes user_bkpt_opcode_t is a scalar value, but there's no
assertion of that, if someone were to define it like char[5] or somesuch
the comparison would still compile but not do what you'd expect.

> +			return -EINVAL;
> +	}
> +	return write_opcode(tsk, user_bkpt->vaddr, user_bkpt->opcode);
> +}

> +/**
> + * check_vma - verify if the address is in a executable vma.
> + * @tsk: the probed task
> + * @vaddr: virtual address of the instruction to be verified.
> + *
> + * Return 0 if vaddr is in an executable VM area,
> + * or -EINVAL otherwise.
> + */
> +static int check_vma(struct task_struct *tsk, unsigned long vaddr)
> +{
> +	struct vm_area_struct *vma;
> +	struct mm_struct *mm;
> +	int ret = -EINVAL;
> +
> +	mm = get_task_mm(tsk);
> +	if (!mm)
> +		return -EINVAL;
> +	down_read(&mm->mmap_sem);
> +	vma = find_vma(mm, vaddr);
> +	if (vma && vaddr >= vma->vm_start && (vma->vm_flags & VM_EXEC))

you fail to check vma->vm_end

Also, do we want to do the full private,ro,exec check here again?

> +		ret = 0;
> +	up_read(&mm->mmap_sem);
> +	mmput(mm);
> +	return ret;
> +}

> +int __weak validate_address(struct task_struct *tsk, unsigned long vaddr)
> +{
> +	return check_vma(tsk, vaddr);
> +}

So here check_vma() is the default implementation of validate_address(),
so why not name them accordingly?

> +/*
> + * __insert_bkpt - insert breakpoint
> + * Insert a breakpoint into the process that includes @tsk, at the
> + * virtual address @user_bkpt->vaddr.
> + *
> + * All threads of the probed process must be stopped while
> + * @__insert_bkpt() runs.

I hope not,.. the pte swizzle we do above does not require any such
thing, stale comment?

> + * Possible errors:
> + * -%ENOSYS: user_bkpt not supported for this architecture
> + * -%EINVAL: invalid instruction address
> + * -%EEXIST: breakpoint instruction already exists at that address
> + * -%EPERM: cannot probe this instruction
> + * -%EFAULT: failed to insert breakpoint instruction
> + */



> +static int pre_sstep(struct task_struct *tsk, struct user_bkpt *user_bkpt,
> +		struct user_bkpt_task_arch_info *tskinfo, struct pt_regs *regs)
> +{
> +	return pre_xol(tsk, user_bkpt, tskinfo, regs);
> +}
> +

> +static int post_sstep(struct task_struct *tsk, struct user_bkpt *user_bkpt,
> +		struct user_bkpt_task_arch_info *tskinfo, struct pt_regs *regs)
> +{
> +	return post_xol(tsk, user_bkpt, tskinfo, regs);
> +}

What's the point of these functions?


> +static int __remove_bkpt(struct task_struct *tsk,
> +					struct user_bkpt *user_bkpt)
> +{
> +	if (validate_address(tsk, user_bkpt->vaddr) != 0)
> +		return -EINVAL;
> +	return set_orig_insn(tsk, user_bkpt, true);
> +}

Why would we even consider calling this function on something that would
fail the validate_address() test? If that fails we would not have
installed the breakpoint to begin with, hence there would be no reason
to remove it.

> +bool __weak is_bkpt_insn(struct user_bkpt *user_bkpt)
> +{
> +	return (user_bkpt->opcode == arch->bkpt_insn);
> +}

Again, assumes the instruction thing is a scalar.



The big thing I'm missing in this patch is generic code handling the
actual breakpoint.. but maybe that's somewhere in the next patches.. /me
goes look.



  reply	other threads:[~2010-09-01 19:38 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-25 13:41 [PATCHv11 2.6.36-rc2-tip 0/15] 0: Uprobes Patches Srikar Dronamraju
2010-08-25 13:41 ` [PATCHv11 2.6.36-rc2-tip 1/15] 1: mm: Move replace_page() / write_protect_page() to mm/memory.c Srikar Dronamraju
2010-08-25 13:41 ` [PATCHv11 2.6.36-rc2-tip 2/15] 2: uprobes: Breakpoint insertion/removal in user space applications Srikar Dronamraju
2010-09-01 19:38   ` Peter Zijlstra [this message]
2010-08-25 13:41 ` [PATCHv11 2.6.36-rc2-tip 3/15] 3: uprobes: Slot allocation for Execution out of line(XOL) Srikar Dronamraju
2010-09-01 20:13   ` Peter Zijlstra
2010-09-03 16:40     ` Srikar Dronamraju
2010-09-03 16:51       ` Peter Zijlstra
2010-09-03 17:26         ` Srikar Dronamraju
2010-09-03 17:41           ` Peter Zijlstra
2010-09-06  5:38             ` Srikar Dronamraju
2010-09-03 17:25       ` Peter Zijlstra
2010-09-02  8:23   ` Peter Zijlstra
2010-09-02 17:47     ` Srikar Dronamraju
2010-09-03  7:26       ` Peter Zijlstra
2010-09-06 17:59         ` Srikar Dronamraju
2010-09-06 18:20           ` Peter Zijlstra
2010-09-06 18:28           ` Peter Zijlstra
2010-08-25 13:42 ` [PATCHv11 2.6.36-rc2-tip 4/15] 4: uprobes: x86 specific functions for user space breakpointing Srikar Dronamraju
2010-09-03 10:26   ` Andi Kleen
2010-09-03 17:48     ` Srikar Dronamraju
2010-09-03 18:00       ` Peter Zijlstra
2010-09-06  7:53       ` Andi Kleen
2010-09-06 13:44         ` Srikar Dronamraju
2010-09-06 14:16           ` Andi Kleen
2010-09-07  0:56           ` Masami Hiramatsu
2010-08-25 13:42 ` [PATCHv11 2.6.36-rc2-tip 5/15] 5: uprobes: Uprobes (un)registration and exception handling Srikar Dronamraju
2010-09-01 21:43   ` Peter Zijlstra
2010-09-02  8:12     ` Peter Zijlstra
2010-09-03 16:42     ` Srikar Dronamraju
2010-09-03 17:19       ` Peter Zijlstra
2010-09-06 17:46         ` Srikar Dronamraju
2010-09-06 18:15           ` Peter Zijlstra
2010-09-06 18:15           ` Peter Zijlstra
2010-09-07  6:48             ` Srikar Dronamraju
2010-09-07  9:33               ` Peter Zijlstra
2010-09-07 11:51                 ` Srikar Dronamraju
2010-09-07 12:25                   ` Peter Zijlstra
2010-09-06 18:25           ` Mathieu Desnoyers
2010-09-06 20:40           ` Christoph Hellwig
2010-09-06 21:06             ` Peter Zijlstra
2010-09-06 21:12               ` Christoph Hellwig
2010-09-06 21:18                 ` Peter Zijlstra
2010-09-07 12:02             ` Srikar Dronamraju
2010-09-07 16:47               ` Mathieu Desnoyers
2010-09-03 17:27       ` Peter Zijlstra
2010-09-01 21:46   ` Peter Zijlstra
2010-08-25 13:42 ` [PATCHv11 2.6.36-rc2-tip 6/15] 6: uprobes: X86 support for Uprobes Srikar Dronamraju
2010-08-25 13:42 ` [PATCHv11 2.6.36-rc2-tip 7/15] 7: uprobes: Uprobes Documentation Srikar Dronamraju
2010-08-25 13:42 ` [PATCHv11 2.6.36-rc2-tip 8/15] 8: tracing: Extract out common code for kprobes/uprobes traceevents Srikar Dronamraju
2010-08-25 13:43 ` [PATCHv11 2.6.36-rc2-tip 9/15] 9: tracing: uprobes trace_event interface Srikar Dronamraju
2010-08-25 13:43 ` [PATCHv11 2.6.36-rc2-tip 10/15] 10: tracing: config option to enable both kprobe-tracer and uprobe-tracer Srikar Dronamraju
2010-08-26  6:02   ` Masami Hiramatsu
2010-08-27  9:31     ` Srikar Dronamraju
2010-08-27 11:04       ` Masami Hiramatsu
2010-08-27 12:17         ` Srikar Dronamraju
2010-08-27 15:37           ` Masami Hiramatsu
2010-08-27 14:10     ` [PATCHv11a " Srikar Dronamraju
2010-08-25 13:43 ` [PATCHv11 2.6.36-rc2-tip 11/15] 11: perf: list symbols in a dso in ascending order Srikar Dronamraju
2010-08-25 23:21   ` Arnaldo Carvalho de Melo
2010-08-26  4:32     ` Srikar Dronamraju
2010-08-30  8:35   ` [tip:perf/core] perf symbols: List symbols in a dso in ascending name order tip-bot for Srikar Dronamraju
2010-08-25 13:43 ` [PATCHv11 2.6.36-rc2-tip 12/15] 12: perf: show possible probes in a given file Srikar Dronamraju
2010-08-27 14:21   ` [PATCHv11a " Srikar Dronamraju
2010-10-20  9:56     ` Masami Hiramatsu
2010-08-25 13:43 ` [PATCHv11 2.6.36-rc2-tip 13/15] 13: perf: Loop thro each of the maps in a map_group Srikar Dronamraju
2010-08-25 13:44 ` [PATCHv11 2.6.36-rc2-tip 14/15] 14: perf: perf interface for uprobes Srikar Dronamraju
2010-08-25 13:44 ` [PATCHv11 2.6.36-rc2-tip 15/15] 15: perf: Show Potential probe points Srikar Dronamraju
2010-10-29  9:23 ` [PATCHv11 2.6.36-rc2-tip 0/15] 0: Uprobes Patches Christoph Hellwig
2010-10-29 10:48   ` Srikar Dronamraju
2010-11-04 18:45     ` Christoph Hellwig

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=1283369892.2059.1493.camel@laptop \
    --to=peterz@infradead.org \
    --cc=acme@infradead.org \
    --cc=akpm@linux-foundation.org \
    --cc=ananth@in.ibm.com \
    --cc=fche@redhat.com \
    --cc=fweisbec@gmail.com \
    --cc=hch@infradead.org \
    --cc=jkenisto@linux.vnet.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=masami.hiramatsu.pt@hitachi.com \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mingo@elte.hu \
    --cc=mjw@redhat.com \
    --cc=naren.devaiah@in.ibm.com \
    --cc=oleg@redhat.com \
    --cc=paulmck@linux.vnet.ibm.com \
    --cc=rdunlap@xenotime.net \
    --cc=rostedt@goodmis.org \
    --cc=srikar@linux.vnet.ibm.com \
    --cc=torvalds@linux-foundation.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.