BPF List
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: Song Liu <songliubraving@fb.com>
Cc: Song Liu <song@kernel.org>, Networking <netdev@vger.kernel.org>,
	bpf <bpf@vger.kernel.org>, lkml <linux-kernel@vger.kernel.org>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Kernel Team <Kernel-team@fb.com>,
	"jolsa@kernel.org" <jolsa@kernel.org>,
	"mhiramat@kernel.org" <mhiramat@kernel.org>
Subject: Re: [PATCH v2 bpf-next 5/5] bpf: trampoline: support FTRACE_OPS_FL_SHARE_IPMODIFY
Date: Wed, 6 Jul 2022 21:18:58 -0400	[thread overview]
Message-ID: <20220706211858.67f9254d@rorschach.local.home> (raw)
In-Reply-To: <9E7BD8AD-483A-4960-B4C6-223CC715D2AF@fb.com>

On Thu, 7 Jul 2022 00:19:07 +0000
Song Liu <songliubraving@fb.com> wrote:

> >> In this specific race condition, register_bpf() will succeed, as it already
> >> got tr->mutex. But the IPMODIFY (livepatch) side will fail and retry.   
> > 
> > What else takes the tr->mutex ?  
> 
> tr->mutex is the local mutex for a single BPF trampoline, we only need to take
> it when we make changes to the trampoline (add/remove fentry/fexit programs). 
> 
> > 
> > If it preempts anything else taking that mutex, when this runs, then it
> > needs to be careful.
> > 
> > You said this can happen when the live patch came first. This isn't racing
> > against live patch, it's racing against anything that takes the tr->mutex
> > and then adds a bpf trampoline to a location that has a live patch.  
> 
> There are a few scenarios here:
> 1. Live patch is already applied, then a BPF trampoline is being registered 
> to the same function. In bpf_trampoline_update(), register_fentry returns
> -EAGAIN, and this will be resolved. 

Where will it be resolved?

> 
> 2. BPF trampoline is already registered, then a live patch is being applied 
> to the same function. The live patch code need to ask the bpf trampoline to
> prepare the trampoline before live patch. This is done by calling 
> bpf_tramp_ftrace_ops_func. 
> 
> 2.1 If nothing else is modifying the trampoline at the same time, 
> bpf_tramp_ftrace_ops_func will succeed. 
> 
> 2.2 In rare cases, if something else is holding tr->mutex to make changes to 
> the trampoline (add/remove fentry functions, etc.), mutex_trylock in 
> bpf_tramp_ftrace_ops_func will fail, and live patch will fail. However, the 
> change to BPF trampoline will still succeed. It is common for live patch to
> retry, so we just need to try live patch again when no one is making changes 
> to the BPF trampoline in parallel. 

If the live patch is going to try again, and the task doing the live
patch is SCHED_FIFO, and the task holding the tr->mutex is SCHED_OTHER
(or just a lower priority), then there is a chance that the live patch
task preempted the tr->mutex owner, and let's say the tr->mutex owner
is pinned to the CPU (by the user or whatever), then because the live
patch task is in a loop trying to take that mutex, it will never let
the owner continue.

Yes, this is a real scenario with trylock on mutexes. We hit it all the
time in RT.

> 
> >   
> >> 
> >> Since both livepatch and bpf trampoline changes are rare operations, I think 
> >> the chance of the race condition is low enough. 


A low race condition in a world that does this a billion times a day,
ends up being not so rare.

I like to say, "I live in a world where the unlikely is very much likely!"


> >> 
> >> Does this make sense?
> >>   
> > 
> > It's low, and if it is also a privileged operation then there's less to be
> > concern about.  
> 
> Both live patch and BPF trampoline are privileged operations. 

This makes the issue less of an issue, but if there's an application
that does this with setuid or something, there's a chance that it can
be used by an attacker as well.

> 
> > As if it is not, then we could have a way to deadlock the
> > system. I'm more concerned that this will lead to a CVE than it just
> > happening randomly. In other words, it only takes something that can run at
> > a real-time priority to connect to a live patch location, and something
> > that runs at a low priority to take a tr->mutex. If an attacker has both,
> > then it can pin both to a CPU and then cause the deadlock to the system.
> > 
> > One hack to fix this is to add a msleep(1) in the failed case of the
> > trylock. This will at least give the owner of the lock a millisecond to
> > release it. This was what the RT patch use to do with spin_trylock() that
> > was converted to a mutex (and we worked hard to remove all of them).  
> 
> The fix is really simple. But I still think we don't need it. We only hit
> the trylock case for something with IPMODIFY. The non-privileged user 
> should not be able to do that, right?

For now, perhaps. But what useful applications are there going to be in
the future that performs these privileged operations on behalf of a
non-privileged user?

In other words, if we can fix it now, we should, and avoid debugging
this issue 5 years from now where it may take months to figure out.

-- Steve

  reply	other threads:[~2022-07-07  1:19 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-02 19:37 [PATCH v2 bpf-next 0/5] ftrace: host klp and bpf trampoline together Song Liu
2022-06-02 19:37 ` [PATCH v2 bpf-next 1/5] ftrace: allow customized flags for ftrace_direct_multi ftrace_ops Song Liu
2022-07-13 23:18   ` Steven Rostedt
2022-07-14  0:11     ` Song Liu
2022-07-14  0:38       ` Steven Rostedt
2022-07-14  1:42         ` Song Liu
2022-07-14  2:55           ` Steven Rostedt
2022-07-14  4:37             ` Song Liu
2022-07-14 13:22               ` Steven Rostedt
2022-06-02 19:37 ` [PATCH v2 bpf-next 2/5] ftrace: add modify_ftrace_direct_multi_nolock Song Liu
2022-06-02 19:37 ` [PATCH v2 bpf-next 3/5] ftrace: introduce FTRACE_OPS_FL_SHARE_IPMODIFY Song Liu
2022-06-06  8:20   ` Jiri Olsa
2022-06-06 15:35     ` Song Liu
2022-07-14  0:33   ` Steven Rostedt
2022-07-15  0:13     ` Song Liu
2022-07-15  0:48       ` Steven Rostedt
2022-07-15  2:04         ` Song Liu
2022-07-15  2:46           ` Steven Rostedt
2022-07-15  2:50             ` Song Liu
2022-07-15 17:42               ` Song Liu
2022-07-15 19:12                 ` Steven Rostedt
2022-07-15 19:49                   ` Song Liu
2022-07-15 19:59                     ` Steven Rostedt
2022-07-15 20:21                       ` Song Liu
2022-07-15 21:29                         ` Steven Rostedt
2022-07-15 21:48                           ` Song Liu
2022-07-15 21:50                             ` Steven Rostedt
2022-06-02 19:37 ` [PATCH v2 bpf-next 4/5] bpf, x64: Allow to use caller address from stack Song Liu
2022-06-02 19:37 ` [PATCH v2 bpf-next 5/5] bpf: trampoline: support FTRACE_OPS_FL_SHARE_IPMODIFY Song Liu
2022-07-06 19:38   ` Steven Rostedt
2022-07-06 21:37     ` Song Liu
2022-07-06 21:40       ` Steven Rostedt
2022-07-06 21:50         ` Song Liu
2022-07-06 22:15         ` Song Liu
2022-07-06 22:29           ` Steven Rostedt
2022-07-07  0:19             ` Song Liu
2022-07-07  1:18               ` Steven Rostedt [this message]
2022-07-07  2:11                 ` Song Liu
2022-06-06 22:57 ` [PATCH v2 bpf-next 0/5] ftrace: host klp and bpf trampoline together Song Liu
2022-07-11 23:55 ` Steven Rostedt
2022-07-12  5:15   ` Song Liu
2022-07-12 13:36     ` Steven Rostedt

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=20220706211858.67f9254d@rorschach.local.home \
    --to=rostedt@goodmis.org \
    --cc=Kernel-team@fb.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=song@kernel.org \
    --cc=songliubraving@fb.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox