[PATCH v3 1/2] Bluetooth: SMP: honor local HIGH security when selecting legacy pairing method

Oleh Konko posted 2 patches 1 day, 18 hours ago
There is a newer version of this series
[PATCH v3 1/2] Bluetooth: SMP: honor local HIGH security when selecting legacy pairing method
Posted by Oleh Konko 1 day, 18 hours ago
tk_request() currently forces JUST_CFM whenever the remote auth_req
omits SMP_AUTH_MITM. That ignores the local pending_sec_level, even
though the responder may still require BT_SECURITY_HIGH.

The pairing-request path already rejects JUST_WORKS/JUST_CFM when
pending_sec_level >= BT_SECURITY_HIGH, so letting tk_request() ignore the
local MITM requirement can make method selection inconsistent with the
policy the stack already enforces.

Only select JUST_CFM when the remote does not request MITM and the local
side does not require HIGH security. Otherwise, derive the method from
the IO capability table.

Fixes: 2b64d153a0cc ("Bluetooth: Add MITM mechanism to LE-SMP")
Cc: stable@vger.kernel.org
Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Signed-off-by: Oleh Konko <security@1seal.org>
---
 net/bluetooth/smp.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index e67bf7b34ea..a9fb9b513d6 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -863,13 +863,14 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
 	bt_dev_dbg(hcon->hdev, "auth:%u lcl:%u rem:%u", auth, local_io,
 		   remote_io);
 
-	/* If neither side wants MITM, either "just" confirm an incoming
-	 * request or use just-works for outgoing ones. The JUST_CFM
-	 * will be converted to JUST_WORKS if necessary later in this
-	 * function. If either side has MITM look up the method from the
-	 * table.
+	/* If the remote doesn't request MITM and the local side doesn't
+	 * require HIGH security, either "just" confirm an incoming request
+	 * or use just-works for outgoing ones. The JUST_CFM will be
+	 * converted to JUST_WORKS if necessary later in this function.
+	 * Otherwise, look up the method from the table.
 	 */
-	if (!(auth & SMP_AUTH_MITM))
+	if (!(auth & SMP_AUTH_MITM) &&
+	    hcon->pending_sec_level < BT_SECURITY_HIGH)
 		smp->method = JUST_CFM;
 	else
 		smp->method = get_auth_method(smp, local_io, remote_io);
-- 
2.50.0


Re: [PATCH v3 1/2] Bluetooth: SMP: honor local HIGH security when selecting legacy pairing method
Posted by Luiz Augusto von Dentz 1 day, 14 hours ago
Hi Oleh,

On Mon, Mar 30, 2026 at 11:33 AM Oleh Konko <security@1seal.org> wrote:
>
> tk_request() currently forces JUST_CFM whenever the remote auth_req
> omits SMP_AUTH_MITM. That ignores the local pending_sec_level, even
> though the responder may still require BT_SECURITY_HIGH.
>
> The pairing-request path already rejects JUST_WORKS/JUST_CFM when
> pending_sec_level >= BT_SECURITY_HIGH, so letting tk_request() ignore the
> local MITM requirement can make method selection inconsistent with the
> policy the stack already enforces.
>
> Only select JUST_CFM when the remote does not request MITM and the local
> side does not require HIGH security. Otherwise, derive the method from
> the IO capability table.
>
> Fixes: 2b64d153a0cc ("Bluetooth: Add MITM mechanism to LE-SMP")
> Cc: stable@vger.kernel.org
> Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
> Signed-off-by: Oleh Konko <security@1seal.org>
> ---
>  net/bluetooth/smp.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index e67bf7b34ea..a9fb9b513d6 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -863,13 +863,14 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
>         bt_dev_dbg(hcon->hdev, "auth:%u lcl:%u rem:%u", auth, local_io,
>                    remote_io);
>
> -       /* If neither side wants MITM, either "just" confirm an incoming
> -        * request or use just-works for outgoing ones. The JUST_CFM
> -        * will be converted to JUST_WORKS if necessary later in this
> -        * function. If either side has MITM look up the method from the
> -        * table.
> +       /* If the remote doesn't request MITM and the local side doesn't
> +        * require HIGH security, either "just" confirm an incoming request
> +        * or use just-works for outgoing ones. The JUST_CFM will be
> +        * converted to JUST_WORKS if necessary later in this function.
> +        * Otherwise, look up the method from the table.
>          */
> -       if (!(auth & SMP_AUTH_MITM))
> +       if (!(auth & SMP_AUTH_MITM) &&
> +           hcon->pending_sec_level < BT_SECURITY_HIGH)
>                 smp->method = JUST_CFM;
>         else
>                 smp->method = get_auth_method(smp, local_io, remote_io);
> --
> 2.50.0

https://sashiko.dev/#/patchset/bt-smp-v3-b13a5d5f53ed4efaba74be7539453366%401seal.org

Seem valid, perhaps we will need to do something like the following to
force the SMP_AUTH_MITM bit in the response:

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 485e3468bd26..9841acc9d074 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1809,6 +1809,19 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn
*conn, struct sk_buff *skb)
                return 0;
        }

+       /* If we need MITM check that it can be achieved */
+       if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
+               u8 method;
+
+               method = get_auth_method(smp, conn->hcon->io_capability,
+                                        req->io_capability);
+               if (method == JUST_WORKS || method == JUST_CFM)
+                       return SMP_AUTH_REQUIREMENTS;
+
+               /* Force MITM bit if not set by initiator */
+               auth |= SMP_AUTH_MITM;
+       }
+
        build_pairing_cmd(conn, req, &rsp, auth);

        if (rsp.auth_req & SMP_AUTH_SC) {
@@ -1826,16 +1839,6 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn
*conn, struct sk_buff *skb)
        if (sec_level > conn->hcon->pending_sec_level)
                conn->hcon->pending_sec_level = sec_level;

-       /* If we need MITM check that it can be achieved */
-       if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
-               u8 method;
-
-               method = get_auth_method(smp, conn->hcon->io_capability,
-                                        req->io_capability);
-               if (method == JUST_WORKS || method == JUST_CFM)
-                       return SMP_AUTH_REQUIREMENTS;
-       }
-
        key_size = min(req->max_key_size, rsp.max_key_size);
        if (check_enc_key_size(conn, key_size))
                return SMP_ENC_KEY_SIZE;

-- 
Luiz Augusto von Dentz
Re: [PATCH v3 1/2] Bluetooth: SMP: honor local HIGH security when selecting legacy pairing method
Posted by Luiz Augusto von Dentz 1 day, 17 hours ago
Hi @Christian Eggers,

On Mon, Mar 30, 2026 at 11:33 AM Oleh Konko <security@1seal.org> wrote:
>
> tk_request() currently forces JUST_CFM whenever the remote auth_req
> omits SMP_AUTH_MITM. That ignores the local pending_sec_level, even
> though the responder may still require BT_SECURITY_HIGH.
>
> The pairing-request path already rejects JUST_WORKS/JUST_CFM when
> pending_sec_level >= BT_SECURITY_HIGH, so letting tk_request() ignore the
> local MITM requirement can make method selection inconsistent with the
> policy the stack already enforces.
>
> Only select JUST_CFM when the remote does not request MITM and the local
> side does not require HIGH security. Otherwise, derive the method from
> the IO capability table.
>
> Fixes: 2b64d153a0cc ("Bluetooth: Add MITM mechanism to LE-SMP")
> Cc: stable@vger.kernel.org
> Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
> Signed-off-by: Oleh Konko <security@1seal.org>
> ---
>  net/bluetooth/smp.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index e67bf7b34ea..a9fb9b513d6 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -863,13 +863,14 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
>         bt_dev_dbg(hcon->hdev, "auth:%u lcl:%u rem:%u", auth, local_io,
>                    remote_io);
>
> -       /* If neither side wants MITM, either "just" confirm an incoming
> -        * request or use just-works for outgoing ones. The JUST_CFM
> -        * will be converted to JUST_WORKS if necessary later in this
> -        * function. If either side has MITM look up the method from the
> -        * table.
> +       /* If the remote doesn't request MITM and the local side doesn't
> +        * require HIGH security, either "just" confirm an incoming request
> +        * or use just-works for outgoing ones. The JUST_CFM will be
> +        * converted to JUST_WORKS if necessary later in this function.
> +        * Otherwise, look up the method from the table.
>          */
> -       if (!(auth & SMP_AUTH_MITM))
> +       if (!(auth & SMP_AUTH_MITM) &&
> +           hcon->pending_sec_level < BT_SECURITY_HIGH)
>                 smp->method = JUST_CFM;
>         else
>                 smp->method = get_auth_method(smp, local_io, remote_io);
> --
> 2.50.0

Do you have any capacity to test if such change affects any SMP test with PTS?

-- 
Luiz Augusto von Dentz