Skip to content

Commit 9f2c8a0

Browse files
committed
Bluetooth: Replace RFCOMM link mode with security level
Change the RFCOMM internals to use the new security levels and remove the link mode details. Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 2af6b9d commit 9f2c8a0

File tree

3 files changed

+79
-31
lines changed

3 files changed

+79
-31
lines changed

include/net/bluetooth/rfcomm.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@ struct rfcomm_dlc {
183183
u8 remote_v24_sig;
184184
u8 mscex;
185185
u8 out;
186-
187-
u32 link_mode;
186+
u8 sec_level;
187+
u8 role_switch;
188188
u32 defer_setup;
189189

190190
uint mtu;
@@ -307,7 +307,8 @@ struct rfcomm_pinfo {
307307
struct bt_sock bt;
308308
struct rfcomm_dlc *dlc;
309309
u8 channel;
310-
u32 link_mode;
310+
u8 sec_level;
311+
u8 role_switch;
311312
};
312313

313314
int rfcomm_init_sockets(void);

net/bluetooth/rfcomm/core.c

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -223,21 +223,11 @@ static int rfcomm_l2sock_create(struct socket **sock)
223223
return err;
224224
}
225225

226-
static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d)
226+
static inline int rfcomm_check_security(struct rfcomm_dlc *d)
227227
{
228228
struct sock *sk = d->session->sock->sk;
229-
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
230229

231-
if (d->link_mode & RFCOMM_LM_SECURE)
232-
return hci_conn_security(conn->hcon, BT_SECURITY_HIGH);
233-
234-
if (d->link_mode & RFCOMM_LM_ENCRYPT)
235-
return hci_conn_security(conn->hcon, BT_SECURITY_MEDIUM);
236-
237-
if (d->link_mode & RFCOMM_LM_AUTH)
238-
return hci_conn_security(conn->hcon, BT_SECURITY_LOW);
239-
240-
return 1;
230+
return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level);
241231
}
242232

243233
/* ---- RFCOMM DLCs ---- */
@@ -390,7 +380,7 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
390380
d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
391381

392382
if (s->state == BT_CONNECTED) {
393-
if (rfcomm_check_link_mode(d))
383+
if (rfcomm_check_security(d))
394384
rfcomm_send_pn(s, 1, d);
395385
else
396386
set_bit(RFCOMM_AUTH_PENDING, &d->flags);
@@ -1192,15 +1182,15 @@ void rfcomm_dlc_accept(struct rfcomm_dlc *d)
11921182
d->state_change(d, 0);
11931183
rfcomm_dlc_unlock(d);
11941184

1195-
if (d->link_mode & RFCOMM_LM_MASTER)
1185+
if (d->role_switch)
11961186
hci_conn_switch_role(l2cap_pi(sk)->conn->hcon, 0x00);
11971187

11981188
rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
11991189
}
12001190

12011191
static void rfcomm_check_accept(struct rfcomm_dlc *d)
12021192
{
1203-
if (rfcomm_check_link_mode(d)) {
1193+
if (rfcomm_check_security(d)) {
12041194
if (d->defer_setup) {
12051195
set_bit(RFCOMM_DEFER_SETUP, &d->flags);
12061196
rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
@@ -1660,7 +1650,7 @@ static void rfcomm_process_connect(struct rfcomm_session *s)
16601650
d = list_entry(p, struct rfcomm_dlc, list);
16611651
if (d->state == BT_CONFIG) {
16621652
d->mtu = s->mtu;
1663-
if (rfcomm_check_link_mode(d)) {
1653+
if (rfcomm_check_security(d)) {
16641654
rfcomm_send_pn(s, 1, d);
16651655
} else {
16661656
set_bit(RFCOMM_AUTH_PENDING, &d->flags);
@@ -1748,10 +1738,6 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
17481738
} else
17491739
rfcomm_dlc_accept(d);
17501740
}
1751-
if (d->link_mode & RFCOMM_LM_SECURE) {
1752-
struct sock *sk = s->sock->sk;
1753-
hci_conn_change_link_key(l2cap_pi(sk)->conn->hcon);
1754-
}
17551741
continue;
17561742
} else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) {
17571743
rfcomm_dlc_clear_timer(d);
@@ -1994,7 +1980,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
19941980
d = list_entry(p, struct rfcomm_dlc, list);
19951981

19961982
if (!status && encrypt == 0x00 &&
1997-
(d->link_mode & RFCOMM_LM_ENCRYPT) &&
1983+
d->sec_level == BT_SECURITY_HIGH &&
19981984
(d->state == BT_CONNECTED ||
19991985
d->state == BT_CONFIG)) {
20001986
__rfcomm_dlc_close(d, ECONNREFUSED);

net/bluetooth/rfcomm/sock.c

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,19 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
261261

262262
if (parent) {
263263
sk->sk_type = parent->sk_type;
264-
pi->link_mode = rfcomm_pi(parent)->link_mode;
265264
pi->dlc->defer_setup = bt_sk(parent)->defer_setup;
265+
266+
pi->sec_level = rfcomm_pi(parent)->sec_level;
267+
pi->role_switch = rfcomm_pi(parent)->role_switch;
266268
} else {
267-
pi->link_mode = 0;
268269
pi->dlc->defer_setup = 0;
270+
271+
pi->sec_level = BT_SECURITY_LOW;
272+
pi->role_switch = 0;
269273
}
270274

271-
pi->dlc->link_mode = pi->link_mode;
275+
pi->dlc->sec_level = pi->sec_level;
276+
pi->dlc->role_switch = pi->role_switch;
272277
}
273278

274279
static struct proto rfcomm_proto = {
@@ -408,7 +413,8 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
408413
bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr);
409414
rfcomm_pi(sk)->channel = sa->rc_channel;
410415

411-
d->link_mode = rfcomm_pi(sk)->link_mode;
416+
d->sec_level = rfcomm_pi(sk)->sec_level;
417+
d->role_switch = rfcomm_pi(sk)->role_switch;
412418

413419
err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
414420
if (!err)
@@ -741,7 +747,14 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u
741747
break;
742748
}
743749

744-
rfcomm_pi(sk)->link_mode = opt;
750+
if (opt & RFCOMM_LM_AUTH)
751+
rfcomm_pi(sk)->sec_level = BT_SECURITY_LOW;
752+
if (opt & RFCOMM_LM_ENCRYPT)
753+
rfcomm_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
754+
if (opt & RFCOMM_LM_SECURE)
755+
rfcomm_pi(sk)->sec_level = BT_SECURITY_HIGH;
756+
757+
rfcomm_pi(sk)->role_switch = (opt & RFCOMM_LM_MASTER);
745758
break;
746759

747760
default:
@@ -756,7 +769,8 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u
756769
static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
757770
{
758771
struct sock *sk = sock->sk;
759-
int err = 0;
772+
struct bt_security sec;
773+
int len, err = 0;
760774
u32 opt;
761775

762776
BT_DBG("sk %p", sk);
@@ -767,6 +781,23 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
767781
lock_sock(sk);
768782

769783
switch (optname) {
784+
case BT_SECURITY:
785+
sec.level = BT_SECURITY_LOW;
786+
787+
len = min_t(unsigned int, sizeof(sec), optlen);
788+
if (copy_from_user((char *) &sec, optval, len)) {
789+
err = -EFAULT;
790+
break;
791+
}
792+
793+
if (sec.level > BT_SECURITY_HIGH) {
794+
err = -EINVAL;
795+
break;
796+
}
797+
798+
rfcomm_pi(sk)->sec_level = sec.level;
799+
break;
800+
770801
case BT_DEFER_SETUP:
771802
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
772803
err = -EINVAL;
@@ -796,6 +827,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
796827
struct sock *l2cap_sk;
797828
struct rfcomm_conninfo cinfo;
798829
int len, err = 0;
830+
u32 opt;
799831

800832
BT_DBG("sk %p", sk);
801833

@@ -806,7 +838,26 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
806838

807839
switch (optname) {
808840
case RFCOMM_LM:
809-
if (put_user(rfcomm_pi(sk)->link_mode, (u32 __user *) optval))
841+
switch (rfcomm_pi(sk)->sec_level) {
842+
case BT_SECURITY_LOW:
843+
opt = RFCOMM_LM_AUTH;
844+
break;
845+
case BT_SECURITY_MEDIUM:
846+
opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
847+
break;
848+
case BT_SECURITY_HIGH:
849+
opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT |
850+
RFCOMM_LM_SECURE;
851+
break;
852+
default:
853+
opt = 0;
854+
break;
855+
}
856+
857+
if (rfcomm_pi(sk)->role_switch)
858+
opt |= RFCOMM_LM_MASTER;
859+
860+
if (put_user(opt, (u32 __user *) optval))
810861
err = -EFAULT;
811862
break;
812863

@@ -840,6 +891,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
840891
static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
841892
{
842893
struct sock *sk = sock->sk;
894+
struct bt_security sec;
843895
int len, err = 0;
844896

845897
BT_DBG("sk %p", sk);
@@ -853,6 +905,15 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c
853905
lock_sock(sk);
854906

855907
switch (optname) {
908+
case BT_SECURITY:
909+
sec.level = rfcomm_pi(sk)->sec_level;
910+
911+
len = min_t(unsigned int, len, sizeof(sec));
912+
if (copy_to_user(optval, (char *) &sec, len))
913+
err = -EFAULT;
914+
915+
break;
916+
856917
case BT_DEFER_SETUP:
857918
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
858919
err = -EINVAL;

0 commit comments

Comments
 (0)