mbox series

[BlueZ,0/2] obexd: only run one instance at once

Message ID 20250416152039.971257-1-kernel.org@pileofstuff.org
Headers show
Series obexd: only run one instance at once | expand

Message

Andrew Sayers April 16, 2025, 3:19 p.m. UTC
Obex is a device-oriented protocol, so only one instance can run per device.
But Linux file security is user-oriented, so obexd should be a user service.
Tell systemd to only run this service for the first non-system user to log in.

This series causes systemd not to run obexd if it would just generate errors,
after adding a new bluez.tmpfiles file that distributors will need to install.

Signed-off-by: Andrew Sayers <kernel.org@pileofstuff.org>
---

Andrew Sayers (2):
      build: add bluez.tmpfiles
      obexd: only run one instance at once

 .gitignore                | 1 +
 configure.ac              | 1 +
 obexd/src/obex.service.in | 6 ++++++
 tools/bluez.tmpfiles.in   | 1 +
 4 files changed, 9 insertions(+)

Comments

Andrew Sayers April 18, 2025, 9:12 a.m. UTC | #1
On 16/04/2025 16:19, Andrew Sayers wrote:
> Obex is a device-oriented protocol, so only one instance can run per device.
> But Linux file security is user-oriented, so obexd should be a user service.
> Tell systemd to only run this service for the first non-system user to log in.
>
> Without this patch, errors like the following will occur if you
> use the "switch account" feature of your desktop environment,
> then log in with another account:
>
> Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 00001133-0000-1000-8000-00805f9b34fb which is already registered
> Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 00001132-0000-1000-8000-00805f9b34fb which is already registered
> Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 0000112f-0000-1000-8000-00805f9b34fb which is already registered
> Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 00001104-0000-1000-8000-00805f9b34fb which is already registered
> Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 00001106-0000-1000-8000-00805f9b34fb which is already registered
> Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 00001105-0000-1000-8000-00805f9b34fb which is already registered
> Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 00005005-0000-1000-8000-0002ee000001 which is already registered
> Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
>
> The above errors indicate the service completely failed to register, so this
> does not change the user experience beyond removing the above messages.
> Specifically, the first user who logs in to a multi-user system still retains
> obex access to devices paired by users who log in later.
>
> This is based on a pair of recent changes to the FluidSynth daemon:
>
> https://github.com/FluidSynth/fluidsynth/pull/1491
> https://github.com/FluidSynth/fluidsynth/pull/1528
>
> This was discussed in the comments for a GitHub advisory available at
> https://github.com/bluez/bluez/security/advisories/GHSA-fpgq-25xf-jcwv
> but comments are not shown in the published version of the advisory.
> To summarise the useful conversation with Luiz Augusto von Dentz:
>
> Obex requires access to the user's home directory, so an attacker can only
> transfer files between locations the user controls.  That may be a problem
> if the user who runs obexd is different to the user who paired the device,
> but solving that would involve pairing per-user, which causes other problems.
> Bluetooth connections can be initiated by peripherals, so switching user could
> trigger re-pairing and cause the original user to lose access to the device.
> This may seem reasonable for file access, but for example users would likely
> object to constantly re-pairing their Bluetooth keyboard.
>
> Signed-off-by: Andrew Sayers <kernel.org@pileofstuff.org>
> ---
>   obexd/src/obex.service.in | 6 ++++++
>   tools/bluez.tmpfiles.in   | 1 +
>   2 files changed, 7 insertions(+)
>
> diff --git a/obexd/src/obex.service.in b/obexd/src/obex.service.in
> index cf4d8c985..42d2185fb 100644
> --- a/obexd/src/obex.service.in
> +++ b/obexd/src/obex.service.in
> @@ -1,10 +1,16 @@
>   [Unit]
>   Description=Bluetooth OBEX service
> +# This is a user-specific service, but bluetooth is a device-specific protocol.
> +# Only run one instance at a time, even if multiple users log in at once:
> +ConditionPathExists=!/run/lock/bluez/obexd.lock
> +ConditionUser=!@system
>   
>   [Service]
>   Type=dbus
>   BusName=org.bluez.obex
>   ExecStart=@PKGLIBEXECDIR@/obexd
> +ExecStartPre=touch /run/lock/bluez/obexd.lock
> +ExecStopPost=rm -f /run/lock/bluez/obexd.lock

Recent experience with the equivalent FluidSynth patch shows that,
if a package maintainer upgrades without adding the tmpfile,
the above causes the service to fail in ways that users find confusing.

One solution would be to prefix a '-' to make systemd ignore errors:

+-ExecStartPre=touch /run/lock/bluez/obexd.lock
+-ExecStopPost=rm -f /run/lock/bluez/obexd.lock

That would reduce a missing tmpfile from a crash to just log spam.
But if the tmpfile gains a more important use case in future,
you might uncover bugs in distro's that never installed the tmpfile.

An alternative would be to add a comment like:

+# If the service fails on the following line, please ensure
+# the bluez tmpfile has been installed in /usr/lib/tmpfiles.d/
+ExecStartPre=touch /run/lock/bluez/obexd.lock
+ExecStopPost=rm -f /run/lock/bluez/obexd.lock

That wouldn't fix the problem, but would make it easier to debug,
and hopefully nudge users to file a useful report with their distro.

>   
>   [Install]
>   Alias=dbus-org.bluez.obex.service
> diff --git a/tools/bluez.tmpfiles.in b/tools/bluez.tmpfiles.in
> index e69de29bb..05b8ad65c 100644
> --- a/tools/bluez.tmpfiles.in
> +++ b/tools/bluez.tmpfiles.in
> @@ -0,0 +1 @@
> +d /run/lock/bluez 0777 root root
Luiz Augusto von Dentz April 18, 2025, 1:31 p.m. UTC | #2
Hi Andrew,

On Fri, Apr 18, 2025 at 5:12 AM Andrew Sayers
<andrew+antispam-20250418@pileofstuff.org> wrote:
>
> On 16/04/2025 16:19, Andrew Sayers wrote:
> > Obex is a device-oriented protocol, so only one instance can run per device.
> > But Linux file security is user-oriented, so obexd should be a user service.
> > Tell systemd to only run this service for the first non-system user to log in.
> >
> > Without this patch, errors like the following will occur if you
> > use the "switch account" feature of your desktop environment,
> > then log in with another account:
> >
> > Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 00001133-0000-1000-8000-00805f9b34fb which is already registered
> > Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 00001132-0000-1000-8000-00805f9b34fb which is already registered
> > Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 0000112f-0000-1000-8000-00805f9b34fb which is already registered
> > Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 00001104-0000-1000-8000-00805f9b34fb which is already registered
> > Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 00001106-0000-1000-8000-00805f9b34fb which is already registered
> > Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 00001105-0000-1000-8000-00805f9b34fb which is already registered
> > Mar 26 15:20:38 andrews-2024-laptop bluetoothd[873]: src/profile.c:register_profile() :1.2016 tried to register 00005005-0000-1000-8000-0002ee000001 which is already registered
> > Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> > Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> > Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> > Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> > Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> > Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> > Mar 26 15:20:38 andrews-2024-laptop obexd[1795560]: bluetooth: RequestProfile error: org.bluez.Error.NotPermitted, UUID already registered
> >
> > The above errors indicate the service completely failed to register, so this
> > does not change the user experience beyond removing the above messages.
> > Specifically, the first user who logs in to a multi-user system still retains
> > obex access to devices paired by users who log in later.
> >
> > This is based on a pair of recent changes to the FluidSynth daemon:
> >
> > https://github.com/FluidSynth/fluidsynth/pull/1491
> > https://github.com/FluidSynth/fluidsynth/pull/1528
> >
> > This was discussed in the comments for a GitHub advisory available at
> > https://github.com/bluez/bluez/security/advisories/GHSA-fpgq-25xf-jcwv
> > but comments are not shown in the published version of the advisory.
> > To summarise the useful conversation with Luiz Augusto von Dentz:
> >
> > Obex requires access to the user's home directory, so an attacker can only
> > transfer files between locations the user controls.  That may be a problem
> > if the user who runs obexd is different to the user who paired the device,
> > but solving that would involve pairing per-user, which causes other problems.
> > Bluetooth connections can be initiated by peripherals, so switching user could
> > trigger re-pairing and cause the original user to lose access to the device.
> > This may seem reasonable for file access, but for example users would likely
> > object to constantly re-pairing their Bluetooth keyboard.
> >
> > Signed-off-by: Andrew Sayers <kernel.org@pileofstuff.org>
> > ---
> >   obexd/src/obex.service.in | 6 ++++++
> >   tools/bluez.tmpfiles.in   | 1 +
> >   2 files changed, 7 insertions(+)
> >
> > diff --git a/obexd/src/obex.service.in b/obexd/src/obex.service.in
> > index cf4d8c985..42d2185fb 100644
> > --- a/obexd/src/obex.service.in
> > +++ b/obexd/src/obex.service.in
> > @@ -1,10 +1,16 @@
> >   [Unit]
> >   Description=Bluetooth OBEX service
> > +# This is a user-specific service, but bluetooth is a device-specific protocol.
> > +# Only run one instance at a time, even if multiple users log in at once:
> > +ConditionPathExists=!/run/lock/bluez/obexd.lock
> > +ConditionUser=!@system
> >
> >   [Service]
> >   Type=dbus
> >   BusName=org.bluez.obex
> >   ExecStart=@PKGLIBEXECDIR@/obexd
> > +ExecStartPre=touch /run/lock/bluez/obexd.lock
> > +ExecStopPost=rm -f /run/lock/bluez/obexd.lock
>
> Recent experience with the equivalent FluidSynth patch shows that,
> if a package maintainer upgrades without adding the tmpfile,
> the above causes the service to fail in ways that users find confusing.
>
> One solution would be to prefix a '-' to make systemd ignore errors:
>
> +-ExecStartPre=touch /run/lock/bluez/obexd.lock
> +-ExecStopPost=rm -f /run/lock/bluez/obexd.lock
>
> That would reduce a missing tmpfile from a crash to just log spam.
> But if the tmpfile gains a more important use case in future,
> you might uncover bugs in distro's that never installed the tmpfile.
>
> An alternative would be to add a comment like:
>
> +# If the service fails on the following line, please ensure
> +# the bluez tmpfile has been installed in /usr/lib/tmpfiles.d/
> +ExecStartPre=touch /run/lock/bluez/obexd.lock
> +ExecStopPost=rm -f /run/lock/bluez/obexd.lock
>
> That wouldn't fix the problem, but would make it easier to debug,
> and hopefully nudge users to file a useful report with their distro.

Yeah, let's do that, can you send an update to the series?

> >
> >   [Install]
> >   Alias=dbus-org.bluez.obex.service
> > diff --git a/tools/bluez.tmpfiles.in b/tools/bluez.tmpfiles.in
> > index e69de29bb..05b8ad65c 100644
> > --- a/tools/bluez.tmpfiles.in
> > +++ b/tools/bluez.tmpfiles.in
> > @@ -0,0 +1 @@
> > +d /run/lock/bluez 0777 root root