Bluetooth: SCO: require CAP_NET_BIND_SERVICE to bind
Subsystems (2)
Luiz Augusto von Dentz
maintainerPATCH 1/2 Bluetooth: SCO: require CAP_NET_BIND_SERVICE to bind
From: Luiz Augusto von Dentz <[email protected]>
SCO sockets have no PSM or port namespace: binding one simply reserves the ability to accept any incoming eSCO/SCO connection on the adapter. That is equivalent to listening on a well-known service, which L2CAP already restricts to CAP_NET_BIND_SERVICE in l2cap_validate_bredr_psm()/l2cap_validate_le_psm().
Apply the same restriction to sco_sock_bind() so unprivileged processes can no longer hijack incoming SCO links.
--- net/bluetooth/sco.c | 7 +++++++ 1 file changed, 7 insertions(+)
net/bluetooth/sco.c +7 -0
@@ -667,6 +667,13 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr_unsized *addr,BT_DBG ("sk %p %pMR" , sk, &sa->sco_bdaddr); +/* Binding a SCO socket reserves the ability to accept any incoming +* eSCO/SCO connection on the adapter, so restrict it in the same way +* L2CAP restricts well-known PSMs. +*/ +if (!capable (CAP_NET_BIND_SERVICE )) +return -EACCES ; +lock_sock (sk);if (sk->sk_state !=BT_OPEN ) {
Signature · 1 line
2.54.0
Luiz Augusto von Dentz
maintainerPATCH 2/2 Bluetooth: ISO: require CAP_NET_BIND_SERVICE to bind
From: Luiz Augusto von Dentz <[email protected]>
ISO sockets have no PSM or port namespace: binding one reserves the ability to accept any incoming CIS or to sync to broadcast streams on the adapter. That is equivalent to listening on a well-known service, which L2CAP already restricts to CAP_NET_BIND_SERVICE in l2cap_validate_bredr_psm()/l2cap_validate_le_psm().
Apply the same restriction to iso_sock_bind() so unprivileged processes can no longer hijack incoming ISO links.
--- net/bluetooth/iso.c | 7 +++++++ 1 file changed, 7 insertions(+)
net/bluetooth/iso.c +7 -0
@@ -1200,6 +1200,13 @@ static int iso_sock_bind(struct socket *sock, struct sockaddr_unsized *addr, addr->sa_family != AF_BLUETOOTH)return -EINVAL ; +/* Binding an ISO socket reserves the ability to accept any incoming +* CIS/BIS on the adapter, so restrict it in the same way L2CAP +* restricts well-known PSMs. +*/ +if (!capable (CAP_NET_BIND_SERVICE )) +return -EACCES ; +lock_sock (sk); if ((sk->sk_state == BT_CONNECT2 || sk->sk_state == BT_CONNECTED) &&
Signature · 1 line
2.54.0
Hi,
to, 2026-08-27 kello 14:01 -0400, Luiz Augusto von Dentz kirjoitti:
Quoted 7 lines
From: Luiz Augusto von Dentz <[email protected]>
SCO sockets have no PSM or port namespace: binding one simply reserves the ability to accept any incoming eSCO/SCO connection on the adapter. That is equivalent to listening on a well-known service, which L2CAP already restricts to
CAP_NET_BIND_SERVICEin l2cap_validate_bredr_psm()/l2cap_validate_le_psm().
In current Linux userspace, sound servers that do HFP listen on SCO sockets, and I think often don't have CAP_NET_BIND_SERVICE.
Do they continue working with this change?
Quoted 27 lines
Apply the same restriction to
sco_sock_bind()so unprivileged processes can no longer hijack incoming SCO links.Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")Signed-off-by Luiz Augusto von Dentz <[email protected]>--- net/bluetooth/sco.c | 7 +++++++ 1 file changed, 7 insertions(+)net/bluetooth/sco.c +7
-0@@ -667,6 +667,13 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr_unsized *addr,BT_DBG ("sk %p %pMR" , sk, &sa->sco_bdaddr); +/* Binding a SCO socket reserves the ability to accept any incoming +* eSCO/SCO connection on the adapter, so restrict it in the same way +* L2CAP restricts well-known PSMs. +*/ +if (!capable (CAP_NET_BIND_SERVICE )) +return -EACCES ; +lock_sock (sk);if (sk->sk_state !=BT_OPEN ) {
Signature · 1 line
Pauli Virtanen
Luiz Augusto von Dentz
maintainerHi Pauli,
Quoted 12 lines · Pauli Virtanen
Hi,
to, 2026-08-27 kello 14:01 -0400, Luiz Augusto von Dentz kirjoitti:
Quoted 7 lines
From: Luiz Augusto von Dentz <[email protected]>
SCO sockets have no PSM or port namespace: binding one simply reserves the ability to accept any incoming eSCO/SCO connection on the adapter. That is equivalent to listening on a well-known service, which L2CAP already restricts to
CAP_NET_BIND_SERVICEin l2cap_validate_bredr_psm()/l2cap_validate_le_psm().
Quoted 4 lines
In current Linux userspace, sound servers that do HFP listen on SCO sockets, and I think often don't have
CAP_NET_BIND_SERVICE.Do they continue working with this change?
Good question, that said this is a part of security hardening otherwise any process could start listening to an SCO connection, and the sound server would stop working. Btw, does the sound server have any special capability to, let's say, open the sound card device so perhaps we can gate it on sound capability as well.
Quoted 30 lines
Quoted 17 lines
Apply the same restriction to
sco_sock_bind()so unprivileged processes can no longer hijack incoming SCO links.Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")Signed-off-by Luiz Augusto von Dentz <[email protected]>--- net/bluetooth/sco.c | 7 +++++++ 1 file changed, 7 insertions(+)net/bluetooth/sco.c +0
-0@@ -667,6 +667,13 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr_unsized *addr,BT_DBG ("sk %p %pMR" , sk, &sa->sco_bdaddr);net/bluetooth/sco.c static int sco_sock_bind(struct socket *sock, struct sockaddr_unsized *addr, · line 679
Quoted 10 lines
net/bluetooth/sco.c +7
-0+/* Binding a SCO socket reserves the ability to accept any incoming +* eSCO/SCO connection on the adapter, so restrict it in the same way +* L2CAP restricts well-known PSMs. +*/ +if (!capable (CAP_NET_BIND_SERVICE )) +return -EACCES ; +lock_sock (sk);if (sk->sk_state !=BT_OPEN ) {--
Pauli Virtanen
Signature · 1 line
Luiz Augusto von Dentz
Hi,
pe, 2026-08-28 kello 09:50 -0400, Luiz Augusto von Dentz kirjoitti:
Quoted 13 lines · Pauli Virtanen
Quoted 12 lines
to, 2026-08-27 kello 14:01 -0400, Luiz Augusto von Dentz kirjoitti:
Quoted 7 lines
From: Luiz Augusto von Dentz <[email protected]>
SCO sockets have no PSM or port namespace: binding one simply reserves the ability to accept any incoming eSCO/SCO connection on the adapter. That is equivalent to listening on a well-known service, which L2CAP already restricts to
CAP_NET_BIND_SERVICEin l2cap_validate_bredr_psm()/l2cap_validate_le_psm().In current Linux userspace, sound servers that do HFP listen on SCO sockets, and I think often don't have
CAP_NET_BIND_SERVICE.
Quoted 7 lines
Quoted 1 line
Do they continue working with this change?
Good question, that said this is a part of security hardening otherwise any process could start listening to an SCO connection, and the sound server would stop working. Btw, does the sound server have any special capability to, let's say, open the sound card device so perhaps we can gate it on sound capability as well.
For ALSA, the sound hardware access is controlled by device file permissions in /dev/snd/* Not sure if that's usable here, or if there's some other per-user controlled solution that could be used.
In most current distros sound server runs with user permissions without special capabilities, and don't have CAP_NET_BIND_SERVICE, so I'd expect this patch breaks userspace.
Giving this capability to them allows binding to low network ports, so it probably makes the hardening issue worse and not better.
The next simplest is probably separate executable with setcap bit set, which gives a SCO listen socket for those who can run it based on file permissions.
For ISO bluetoothd manages this (so can be gated with DBus/selinux policies), and it could make sense for it to be made to work like that for SCO too.
Quoted 32 lines
Quoted 30 lines
Quoted 17 lines
Apply the same restriction to
sco_sock_bind()so unprivileged processes can no longer hijack incoming SCO links.Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")Signed-off-by Luiz Augusto von Dentz <[email protected]>--- net/bluetooth/sco.c | 7 +++++++ 1 file changed, 7 insertions(+)net/bluetooth/sco.c +0
-0@@ -667,6 +667,13 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr_unsized *addr,BT_DBG ("sk %p %pMR" , sk, &sa->sco_bdaddr);net/bluetooth/sco.c static int sco_sock_bind(struct socket *sock, struct sockaddr_unsized *addr, · line 679
Quoted 10 lines
net/bluetooth/sco.c +7
-0+/* Binding a SCO socket reserves the ability to accept any incoming +* eSCO/SCO connection on the adapter, so restrict it in the same way +* L2CAP restricts well-known PSMs. +*/ +if (!capable (CAP_NET_BIND_SERVICE )) +return -EACCES ; +lock_sock (sk);if (sk->sk_state !=BT_OPEN ) {--
Pauli Virtanen
Luiz Augusto von Dentz
maintainerHi Pauli,
Quoted 25 lines · Pauli Virtanen
Hi,
pe, 2026-08-28 kello 09:50 -0400, Luiz Augusto von Dentz kirjoitti:
Quoted 13 lines · Pauli Virtanen
Quoted 12 lines
to, 2026-08-27 kello 14:01 -0400, Luiz Augusto von Dentz kirjoitti:
Quoted 7 lines
From: Luiz Augusto von Dentz <[email protected]>
SCO sockets have no PSM or port namespace: binding one simply reserves the ability to accept any incoming eSCO/SCO connection on the adapter. That is equivalent to listening on a well-known service, which L2CAP already restricts to
CAP_NET_BIND_SERVICEin l2cap_validate_bredr_psm()/l2cap_validate_le_psm().In current Linux userspace, sound servers that do HFP listen on SCO sockets, and I think often don't have
CAP_NET_BIND_SERVICE.Quoted 7 lines
Quoted 1 line
Do they continue working with this change?
Good question, that said this is a part of security hardening otherwise any process could start listening to an SCO connection, and the sound server would stop working. Btw, does the sound server have any special capability to, let's say, open the sound card device so perhaps we can gate it on sound capability as well.
Quoted 3 lines
For ALSA, the sound hardware access is controlled by device file permissions in
/dev/snd/*Not sure if that's usable here, or if there's some other per-user controlled solution that could be used.
Ok, so you are saying anyone user with file access to /dev/snd/* can grab the hardware for itself, since pipewire is just a regular user it just works because it is the first one to open it?
Quoted 6 lines
In most current distros sound server runs with user permissions without special capabilities, and don't have
CAP_NET_BIND_SERVICE, so I'd expect this patch breaks userspace.Giving this capability to them allows binding to low network ports, so it probably makes the hardening issue worse and not better.
You would grant it to a specific set of binaries, probably via a systemd file. This would block other users, which currently might just be testing tools like isotest, where you just use sudo instead, or an AI agent trying to fabricate vulnerabilities.
Quoted 3 lines
The next simplest is probably separate executable with setcap bit set, which gives a SCO listen socket for those who can run it based on file permissions.
What file permission? Afaik a socket protocol doesn't have file permissions, or does it? The is no open just bind which is what we are trying to protect.
Quoted 3 lines
For ISO bluetoothd manages this (so can be gated with DBus/selinux policies), and it could make sense for it to be made to work like that for SCO too.
Yeah, bluetoothd manages this for ISO and I wish we did this for SCO too, maybe via Profle interface which I guess PipeWire registers, but it just for RFCOMM/AT commands, right? Anyway this is too late because we cannot break support of older versions of pipewire/bluetoothd + new kernel, so we need a way to determine if SCO usage is allowed or not.
Quoted 32 lines
Quoted 32 lines
Quoted 30 lines
Quoted 17 lines
Apply the same restriction to
sco_sock_bind()so unprivileged processes can no longer hijack incoming SCO links.Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")Signed-off-by Luiz Augusto von Dentz <[email protected]>--- net/bluetooth/sco.c | 7 +++++++ 1 file changed, 7 insertions(+)net/bluetooth/sco.c +0
-0@@ -667,6 +667,13 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr_unsized *addr,BT_DBG ("sk %p %pMR" , sk, &sa->sco_bdaddr);net/bluetooth/sco.c static int sco_sock_bind(struct socket *sock, struct sockaddr_unsized *addr, · line 679
Quoted 10 lines
net/bluetooth/sco.c +7
-0+/* Binding a SCO socket reserves the ability to accept any incoming +* eSCO/SCO connection on the adapter, so restrict it in the same way +* L2CAP restricts well-known PSMs. +*/ +if (!capable (CAP_NET_BIND_SERVICE )) +return -EACCES ; +lock_sock (sk);if (sk->sk_state !=BT_OPEN ) {--
Pauli Virtanen
Signature · 1 line
Luiz Augusto von Dentz
pe, 2026-08-28 kello 12:46 -0400, Luiz Augusto von Dentz kirjoitti:
Quoted 23 lines · Pauli Virtanen
Quoted 22 lines
pe, 2026-08-28 kello 09:50 -0400, Luiz Augusto von Dentz kirjoitti:
Quoted 20 lines · Pauli Virtanen
Quoted 9 lines
to, 2026-08-27 kello 14:01 -0400, Luiz Augusto von Dentz kirjoitti:
Quoted 7 lines
From: Luiz Augusto von Dentz <[email protected]>
SCO sockets have no PSM or port namespace: binding one simply reserves the ability to accept any incoming eSCO/SCO connection on the adapter. That is equivalent to listening on a well-known service, which L2CAP already restricts to
CAP_NET_BIND_SERVICEin l2cap_validate_bredr_psm()/l2cap_validate_le_psm().Quoted 4 lines
In current Linux userspace, sound servers that do HFP listen on SCO sockets, and I think often don't have
CAP_NET_BIND_SERVICE.Do they continue working with this change?
Good question, that said this is a part of security hardening otherwise any process could start listening to an SCO connection, and the sound server would stop working. Btw, does the sound server have any special capability to, let's say, open the sound card device so perhaps we can gate it on sound capability as well.
Quoted 7 lines
Quoted 3 lines
For ALSA, the sound hardware access is controlled by device file permissions in
/dev/snd/*Not sure if that's usable here, or if there's some other per-user controlled solution that could be used.Ok, so you are saying anyone user with file access to
/dev/snd/*can grab the hardware for itself, since pipewire is just a regular user it just works because it is the first one to open it?
Normally udev adjusts the /dev/snd/* file permissions, so that only the user who has the current "active seat" ie virtual console, can access them.
So they are not system-wide accessible to all users in mainstream current distros.
If the user with active seat runs multiple applications that want exclusive access to /dev/snd/*, they need to coordinate with themselves who gets the access. There exists a DBus protocol for cooperatively doing this, but usually everything just passes through the sound server so it's not needed.
Quoted 11 lines
Quoted 6 lines
In most current distros sound server runs with user permissions without special capabilities, and don't have
CAP_NET_BIND_SERVICE, so I'd expect this patch breaks userspace.Giving this capability to them allows binding to low network ports, so it probably makes the hardening issue worse and not better.
You would grant it to a specific set of binaries, probably via a systemd file. This would block other users, which currently might just be testing tools like isotest, where you just use sudo instead, or an AI agent trying to fabricate vulnerabilities.
That requires these binaries are hardened like suid-executables to only use the capability for SCO ...
Granting capabilities with systemd AFAIK does not work for user services, so not sure there's other alternative than setcap.
Quoted 7 lines
Quoted 3 lines
The next simplest is probably separate executable with setcap bit set, which gives a SCO listen socket for those who can run it based on file permissions.
What file permission? Afaik a socket protocol doesn't have file permissions, or does it? The is no open just bind which is what we are trying to protect.
I mean the file permissions of the executable file.
... hardening like that is easier to do by moving it to separate "suid" executable, which has setcap cap_net_bind_service=p executable file bits set, and chmod/chown permissions to restrict it to specific users.
Quoted 9 lines
Quoted 3 lines
For ISO bluetoothd manages this (so can be gated with DBus/selinux policies), and it could make sense for it to be made to work like that for SCO too.
Yeah, bluetoothd manages this for ISO and I wish we did this for SCO too, maybe via Profle interface which I guess PipeWire registers, but it just for RFCOMM/AT commands, right? Anyway this is too late because we cannot break support of older versions of pipewire/bluetoothd + new kernel, so we need a way to determine if SCO usage is allowed or not.
If sound server developers have to start thinking about separate executable/services for hardening this, it would be simpler to just add new DBus API to bluetoothd that does just SCO bind.
So I'm not really seeing a way to add the hardening now, without this type of ground work first, or accepting that distros have to temporarily set cap_net_bind_service=p (or some other capability) on the executable files. Which then allows sound servers to do other things like bind to low network ports as a side effect.
Quoted 34 lines
Quoted 32 lines
Quoted 32 lines
Quoted 30 lines
Quoted 17 lines
Apply the same restriction to
sco_sock_bind()so unprivileged processes can no longer hijack incoming SCO links.Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")Signed-off-by Luiz Augusto von Dentz <[email protected]>--- net/bluetooth/sco.c | 7 +++++++ 1 file changed, 7 insertions(+)net/bluetooth/sco.c +0
-0@@ -667,6 +667,13 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr_unsized *addr,BT_DBG ("sk %p %pMR" , sk, &sa->sco_bdaddr);net/bluetooth/sco.c static int sco_sock_bind(struct socket *sock, struct sockaddr_unsized *addr, · line 679
Quoted 10 lines
net/bluetooth/sco.c +7
-0+/* Binding a SCO socket reserves the ability to accept any incoming +* eSCO/SCO connection on the adapter, so restrict it in the same way +* L2CAP restricts well-known PSMs. +*/ +if (!capable (CAP_NET_BIND_SERVICE )) +return -EACCES ; +lock_sock (sk);if (sk->sk_state !=BT_OPEN ) {--
Pauli Virtanen
Signature · 1 line
Pauli Virtanen
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1152789
---Test result---
Test Summary:
CheckPatch PASS 1.08 seconds VerifyFixes PASS 0.07 seconds VerifySignedoff PASS 0.07 seconds GitLint PASS 0.42 seconds SubjectPrefix PASS 0.13 seconds BuildKernel PASS 27.76 seconds CheckAllWarning PASS 30.59 seconds CheckSparse PASS 29.04 seconds BuildKernel32 PASS 26.89 seconds CheckKernelLLVM SKIP 0.00 seconds TestRunnerSetup PASS 503.99 seconds TestRunner_iso-tester PASS 102.37 seconds TestRunner_sco-tester PASS 32.11 seconds IncrementalBuild PASS 29.64 seconds
Details
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found
https://github.com/bluez/bluetooth-next/pull/657
---
Regards,
Linux Bluetooth