All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
To: Greg KH <gregkh@linuxfoundation.org>
Cc: Yonghong Song <yhs@meta.com>, Jiri Kosina <jikos@kernel.org>,
	Jonathan Corbet <corbet@lwn.net>, Shuah Khan <shuah@kernel.org>,
	Alexei Starovoitov <alexei.starovoitov@gmail.com>,
	Tero Kristo <tero.kristo@linux.intel.com>,
	linux-kernel@vger.kernel.org, linux-input@vger.kernel.org,
	bpf@vger.kernel.org, linux-kselftest@vger.kernel.org,
	linux-doc@vger.kernel.org
Subject: Re: [PATCH hid v12 05/15] HID: bpf jmp table: simplify the logic of cleaning up programs
Date: Tue, 13 Dec 2022 08:59:02 +0100	[thread overview]
Message-ID: <CAO-hwJLs3a41cUvQ-sU04Pg4vJDiBGHfU=N_d_APhjEdQsR3Xg@mail.gmail.com> (raw)
In-Reply-To: <Y5gbg820K5LHI7K6@kroah.com>

On Tue, Dec 13, 2022 at 7:28 AM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Mon, Dec 12, 2022 at 10:39:26AM -0800, Yonghong Song wrote:
> >
> >
> > On 12/12/22 10:20 AM, Greg KH wrote:
> > > On Mon, Dec 12, 2022 at 09:52:03AM -0800, Yonghong Song wrote:
> > > >
> > > >
> > > > On 12/12/22 9:02 AM, Benjamin Tissoires wrote:
> > > > > On Thu, Nov 3, 2022 at 4:58 PM Benjamin Tissoires
> > > > > <benjamin.tissoires@redhat.com> wrote:
> > > > > >
> > > > > > Kind of a hack, but works for now:
> > > > > >
> > > > > > Instead of listening for any close of eBPF program, we now
> > > > > > decrement the refcount when we insert it in our internal
> > > > > > map of fd progs.
> > > > > >
> > > > > > This is safe to do because:
> > > > > > - we listen to any call of destructor of programs
> > > > > > - when a program is being destroyed, we disable it by removing
> > > > > >     it from any RCU list used by any HID device (so it will never
> > > > > >     be called)
> > > > > > - we then trigger a job to cleanup the prog fd map, but we overwrite
> > > > > >     the removal of the elements to not do anything on the programs, just
> > > > > >     remove the allocated space
> > > > > >
> > > > > > This is better than previously because we can remove the map of known
> > > > > > programs and their usage count. We now rely on the refcount of
> > > > > > bpf, which has greater chances of being accurate.
> > > > > >
> > > > > > Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> > > > > >
> > > > > > ---
> > > > >
> > > > > So... I am a little bit embarrassed, but it turns out that this hack
> > > > > is not safe enough.
> > > > >
> > > > > If I compile the kernel with LLVM=1, the function
> > > > > bpf_prog_put_deferred() is optimized in a weird way: if we are not in
> > > > > irq, the function is inlined into __bpf_prog_put(), but if we are, the
> > > > > function is still kept around as it is called in a scheduled work
> > > > > item.
> > > > >
> > > > > This is something I completely overlooked: I assume that if the
> > > > > function would be inlined, the HID entrypoint BPF preloaded object
> > > > > would not be able to bind, thus deactivating HID-BPF safely. But if a
> > > > > function can be both inlined and not inlined, then I have no
> > > > > guarantees that my cleanup call will be called. Meaning that a HID
> > > > > device might believe there is still a bpf function to call. And things
> > > > > will get messy, with kernel crashes and others.
> > > >
> > > > You should not rely fentry to a static function. This is unstable
> > > > as compiler could inline it if that static function is called
> > > > directly. You could attach to a global function if it is not
> > > > compiled with lto.
> > >
> > > But now that the kernel does support LTO, how can you be sure this will
> > > always work properly?  The code author does not know if LTO will kick in
> > > and optimize this away or not, that's the linker's job.
> >
> > Ya, that is right. So for in-kernel bpf programs, attaching to global
> > functions are not safe either. For other not-in-kernel bpf programs, it
> > may not work but that is user's responsibility to adjust properly
> > (to different functions based on a particular build, etc.).
>
> So if in-kernel bpf programs will not work or are not safe, how will
> in-kernel bpf programs properly attach?

Sorry if that wasn't clear. Loading a bpf program from the kernel is
fine and safe. But it was the use of it that wasn't.

In my case, HID-BPF to fix devices is safe (whether the program is
loaded from the kernel or from userspace): the bpf JIT/verifier
ensures that there are no out of bound read/write and the API is
properly defined. But the problem I am facing with the generic bpf
implementation is that it is made to be a global processing and to
attach to one given function, when I wanted to have a couple function
+ device.

So in this patch, I actually abused BPF to get free event
notifications when the bpf program was released.
The first implementation (HID: initial BPF implementation) was safer
than this patch because I was using BPF for notifications of my
internals but I wasn't messing up with the reference count. So if I
did not get the events, I wouldn't decrement the bpf_prog and the end
result means that the bpf program would stay forever attached to the
device. Not user friendly but it doesn't introduce a kernel crash.

However, this patch is messing with reference counting of an internal
kernel object assuming I would always get the event. This is not the
case and so I get read after free errors.

TL;DR: (ab)using BPF internally for kernel introspection to manage
kernel structures is just plain wrong. Mea culpa.

Cheers,
Benjamin


  reply	other threads:[~2022-12-13  8:00 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-03 15:57 [PATCH hid v12 00/15] Introduce eBPF support for HID devices Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 01/15] HID: fix I2C_HID not selected when I2C_HID_OF_ELAN is Benjamin Tissoires
2022-11-15 15:27   ` Jiri Kosina
2022-11-03 15:57 ` [PATCH hid v12 02/15] HID: Kconfig: split HID support and hid-core compilation Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 03/15] HID: initial BPF implementation Benjamin Tissoires
2022-11-23 13:25   ` Jon Hunter
2022-11-23 14:48     ` Benjamin Tissoires
2022-11-23 18:47       ` Jon Hunter
2022-11-23 20:13       ` Alexei Starovoitov
2022-11-24 15:50         ` Benjamin Tissoires
2022-11-29 18:00           ` Florent Revest
2022-11-30  8:49             ` Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 04/15] selftests: add tests for the HID-bpf initial implementation Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 05/15] HID: bpf jmp table: simplify the logic of cleaning up programs Benjamin Tissoires
2022-12-12 17:02   ` Benjamin Tissoires
2022-12-12 17:08     ` Jiri Kosina
2022-12-12 17:52     ` Yonghong Song
2022-12-12 18:20       ` Greg KH
2022-12-12 18:39         ` Yonghong Song
2022-12-13  6:28           ` Greg KH
2022-12-13  7:59             ` Benjamin Tissoires [this message]
2022-12-13 18:13             ` Yonghong Song
2022-11-03 15:57 ` [PATCH hid v12 06/15] HID: bpf: allocate data memory for device_event BPF programs Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 07/15] selftests/hid: add test to change the report size Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 08/15] HID: bpf: introduce hid_hw_request() Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 09/15] selftests/hid: add tests for bpf_hid_hw_request Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 10/15] HID: bpf: allow to change the report descriptor Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 11/15] selftests/hid: add report descriptor fixup tests Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 12/15] selftests/hid: Add a test for BPF_F_INSERT_HEAD Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 13/15] samples/hid: add new hid BPF example Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 14/15] samples/hid: add Surface Dial example Benjamin Tissoires
2022-11-03 15:57 ` [PATCH hid v12 15/15] Documentation: add HID-BPF docs Benjamin Tissoires
2022-11-15 15:32 ` [PATCH hid v12 00/15] Introduce eBPF support for HID devices Jiri Kosina

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='CAO-hwJLs3a41cUvQ-sU04Pg4vJDiBGHfU=N_d_APhjEdQsR3Xg@mail.gmail.com' \
    --to=benjamin.tissoires@redhat.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=bpf@vger.kernel.org \
    --cc=corbet@lwn.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=jikos@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=shuah@kernel.org \
    --cc=tero.kristo@linux.intel.com \
    --cc=yhs@meta.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 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.