All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Masami Hiramatsu <mhiramat@kernel.org>
Cc: andrii@kernel.org, peterz@infradead.org, clm@meta.com,
	jolsa@kernel.org, mingo@kernel.org, paulmck@kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] uprobes: document the usage of mm->mmap_lock
Date: Wed, 10 Jul 2024 17:10:07 +0200	[thread overview]
Message-ID: <20240710151006.GB9228@redhat.com> (raw)
In-Reply-To: <20240710235159.23b8bc0f5247c358ccea699d@kernel.org>

On 07/10, Masami Hiramatsu wrote:
>
> On Wed, 10 Jul 2024 16:00:45 +0200
> Oleg Nesterov <oleg@redhat.com> wrote:
>
> > The comment above uprobe_write_opcode() is wrong, unapply_uprobe() calls
> > it under mmap_read_lock() and this is correct.
> >
> > And it is completely unclear why register_for_each_vma() takes mmap_lock
> > for writing, add a comment to explain that mmap_write_lock() is needed to
> > avoid the following race:
> >
> > 	- A task T hits the bp installed by uprobe and calls
> > 	  find_active_uprobe()
> >
> > 	- uprobe_unregister() removes this uprobe/bp
> >
> > 	- T calls find_uprobe() which returns NULL
> >
> > 	- another uprobe_register() installs the bp at the same address
> >
> > 	- T calls is_trap_at_addr() which returns true
> >
> > 	- T returns to handle_swbp() and gets SIGTRAP.

...

> >  int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
> > @@ -1046,7 +1046,12 @@ register_for_each_vma(struct uprobe *uprobe, struct uprobe_consumer *new)
> >
> >  		if (err && is_register)
> >  			goto free;
> > -
> > +		/*
> > +		 * We take mmap_lock for writing to avoid the race with
> > +		 * find_active_uprobe(), install_breakpoint() must not
> > +		 * make is_trap_at_addr() true right after find_uprobe()
> > +		 * returns NULL.
>
> Sorry, I couldn't catch the latter part. What is the relationship of
> taking the mmap_lock and install_breakpoint() and is_trap_at_addr() here?

Please the the changelog above, it tries to explain this race with more
details...

> You meant that find_active_uprobe() is using find_uprobe() which searchs
> uprobe form rbtree?

Yes,

> But it seems uprobe is already inserted to the rbtree
> in alloc_uprobe() so find_uprobe() will not return NULL here, right?

uprobe_register() -> alloc_uprobe() can come after
find_active_uprobe() -> find_uprobe() returns NULL.

Now, if uprobe_register() -> register_for_each_vma() used mmap_read_lock(), it
could do install_breakpoint() before find_active_uprobe() calls is_trap_at_addr().

In this case find_active_uprobe() returns with uprobe == NULL and is_swbp == 1,
handle_swbp() treat this case as the "normal" int3 without uprobe and do

	if (!uprobe) {
		if (is_swbp > 0) {
			/* No matching uprobe; signal SIGTRAP. */
			force_sig(SIGTRAP);

Does this answer your question?

Oleg.


  reply	other threads:[~2024-07-10 15:11 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-10 14:00 [PATCH 0/2] uprobes: document mmap_lock, don't abuse get_user_pages_remote() Oleg Nesterov
2024-07-10 14:00 ` [PATCH 1/2] uprobes: document the usage of mm->mmap_lock Oleg Nesterov
2024-07-10 14:51   ` Masami Hiramatsu
2024-07-10 15:10     ` Oleg Nesterov [this message]
2024-07-11  0:07       ` Masami Hiramatsu
2024-07-11  9:49         ` Oleg Nesterov
2024-07-11 14:19           ` Masami Hiramatsu
2024-07-11 15:25             ` Oleg Nesterov
2024-07-10 14:01 ` [PATCH 2/2] uprobes: is_trap_at_addr: don't use get_user_pages_remote() Oleg Nesterov
2024-07-10 15:15   ` Andrii Nakryiko
2024-07-10 16:30 ` [PATCH 0/3] uprobes: future cleanups for review Oleg Nesterov
2024-07-10 16:30   ` [PATCH 1/3] uprobes: kill uprobe_register_refctr() Oleg Nesterov
2024-07-10 18:03     ` Andrii Nakryiko
2024-07-10 19:32       ` Oleg Nesterov
2024-07-10 16:31   ` [PATCH 2/3] uprobes: simplify error handling for alloc_uprobe() Oleg Nesterov
2024-07-11 15:18     ` Masami Hiramatsu
2024-07-10 16:31   ` [PATCH 3/3] uprobes: make uprobe_register() return struct uprobe * Oleg Nesterov
2024-07-10 16:48     ` Jiri Olsa
2024-07-10 18:23       ` Andrii Nakryiko
2024-07-10 19:38         ` Jiri Olsa
2024-07-10 19:48           ` Andrii Nakryiko
2024-07-10 19:20       ` Oleg Nesterov
2024-07-10 18:21     ` Andrii Nakryiko
2024-07-10 20:16       ` Oleg Nesterov
2024-07-10 20:46         ` Andrii Nakryiko
2024-07-11  9:26     ` Oleg Nesterov
2024-07-11 17:11       ` Andrii Nakryiko
2024-07-11 18:26         ` Oleg Nesterov
2024-07-11  8:27   ` [PATCH 0/3] uprobes: future cleanups for review Peter Zijlstra
2024-07-11  8:45     ` Oleg Nesterov

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=20240710151006.GB9228@redhat.com \
    --to=oleg@redhat.com \
    --cc=andrii@kernel.org \
    --cc=clm@meta.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@kernel.org \
    --cc=paulmck@kernel.org \
    --cc=peterz@infradead.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.