mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-15 00:34:10 +08:00
Bluetooth: Properly check L2CAP config option output buffer length
Validate the output buffer length for L2CAP config requests and responses to avoid overflowing the stack buffer used for building the option blocks. Cc: stable@vger.kernel.org Signed-off-by: Ben Seri <ben@armis.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
4dfc278803
commit
e860d2c904
@ -58,7 +58,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
|
|||||||
u8 code, u8 ident, u16 dlen, void *data);
|
u8 code, u8 ident, u16 dlen, void *data);
|
||||||
static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
|
static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
|
||||||
void *data);
|
void *data);
|
||||||
static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
|
static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size);
|
||||||
static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
|
static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
|
||||||
|
|
||||||
static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
|
static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
|
||||||
@ -1473,7 +1473,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
|
|||||||
|
|
||||||
set_bit(CONF_REQ_SENT, &chan->conf_state);
|
set_bit(CONF_REQ_SENT, &chan->conf_state);
|
||||||
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
|
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
|
||||||
l2cap_build_conf_req(chan, buf), buf);
|
l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
|
||||||
chan->num_conf_req++;
|
chan->num_conf_req++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2987,12 +2987,15 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
|
static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val, size_t size)
|
||||||
{
|
{
|
||||||
struct l2cap_conf_opt *opt = *ptr;
|
struct l2cap_conf_opt *opt = *ptr;
|
||||||
|
|
||||||
BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
|
BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
|
||||||
|
|
||||||
|
if (size < L2CAP_CONF_OPT_SIZE + len)
|
||||||
|
return;
|
||||||
|
|
||||||
opt->type = type;
|
opt->type = type;
|
||||||
opt->len = len;
|
opt->len = len;
|
||||||
|
|
||||||
@ -3017,7 +3020,7 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
|
|||||||
*ptr += L2CAP_CONF_OPT_SIZE + len;
|
*ptr += L2CAP_CONF_OPT_SIZE + len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
|
static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan, size_t size)
|
||||||
{
|
{
|
||||||
struct l2cap_conf_efs efs;
|
struct l2cap_conf_efs efs;
|
||||||
|
|
||||||
@ -3045,7 +3048,7 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
|
|||||||
}
|
}
|
||||||
|
|
||||||
l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
|
l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
|
||||||
(unsigned long) &efs);
|
(unsigned long) &efs, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void l2cap_ack_timeout(struct work_struct *work)
|
static void l2cap_ack_timeout(struct work_struct *work)
|
||||||
@ -3191,11 +3194,12 @@ static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
|
|||||||
chan->ack_win = chan->tx_win;
|
chan->ack_win = chan->tx_win;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
|
static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size)
|
||||||
{
|
{
|
||||||
struct l2cap_conf_req *req = data;
|
struct l2cap_conf_req *req = data;
|
||||||
struct l2cap_conf_rfc rfc = { .mode = chan->mode };
|
struct l2cap_conf_rfc rfc = { .mode = chan->mode };
|
||||||
void *ptr = req->data;
|
void *ptr = req->data;
|
||||||
|
void *endptr = data + data_size;
|
||||||
u16 size;
|
u16 size;
|
||||||
|
|
||||||
BT_DBG("chan %p", chan);
|
BT_DBG("chan %p", chan);
|
||||||
@ -3220,7 +3224,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
if (chan->imtu != L2CAP_DEFAULT_MTU)
|
if (chan->imtu != L2CAP_DEFAULT_MTU)
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr);
|
||||||
|
|
||||||
switch (chan->mode) {
|
switch (chan->mode) {
|
||||||
case L2CAP_MODE_BASIC:
|
case L2CAP_MODE_BASIC:
|
||||||
@ -3239,7 +3243,7 @@ done:
|
|||||||
rfc.max_pdu_size = 0;
|
rfc.max_pdu_size = 0;
|
||||||
|
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
|
||||||
(unsigned long) &rfc);
|
(unsigned long) &rfc, endptr - ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_MODE_ERTM:
|
case L2CAP_MODE_ERTM:
|
||||||
@ -3259,21 +3263,21 @@ done:
|
|||||||
L2CAP_DEFAULT_TX_WINDOW);
|
L2CAP_DEFAULT_TX_WINDOW);
|
||||||
|
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
|
||||||
(unsigned long) &rfc);
|
(unsigned long) &rfc, endptr - ptr);
|
||||||
|
|
||||||
if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
|
if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
|
||||||
l2cap_add_opt_efs(&ptr, chan);
|
l2cap_add_opt_efs(&ptr, chan, endptr - ptr);
|
||||||
|
|
||||||
if (test_bit(FLAG_EXT_CTRL, &chan->flags))
|
if (test_bit(FLAG_EXT_CTRL, &chan->flags))
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
|
||||||
chan->tx_win);
|
chan->tx_win, endptr - ptr);
|
||||||
|
|
||||||
if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
|
if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
|
||||||
if (chan->fcs == L2CAP_FCS_NONE ||
|
if (chan->fcs == L2CAP_FCS_NONE ||
|
||||||
test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
|
test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
|
||||||
chan->fcs = L2CAP_FCS_NONE;
|
chan->fcs = L2CAP_FCS_NONE;
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
|
||||||
chan->fcs);
|
chan->fcs, endptr - ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3291,17 +3295,17 @@ done:
|
|||||||
rfc.max_pdu_size = cpu_to_le16(size);
|
rfc.max_pdu_size = cpu_to_le16(size);
|
||||||
|
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
|
||||||
(unsigned long) &rfc);
|
(unsigned long) &rfc, endptr - ptr);
|
||||||
|
|
||||||
if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
|
if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
|
||||||
l2cap_add_opt_efs(&ptr, chan);
|
l2cap_add_opt_efs(&ptr, chan, endptr - ptr);
|
||||||
|
|
||||||
if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
|
if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
|
||||||
if (chan->fcs == L2CAP_FCS_NONE ||
|
if (chan->fcs == L2CAP_FCS_NONE ||
|
||||||
test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
|
test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
|
||||||
chan->fcs = L2CAP_FCS_NONE;
|
chan->fcs = L2CAP_FCS_NONE;
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
|
||||||
chan->fcs);
|
chan->fcs, endptr - ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3312,10 +3316,11 @@ done:
|
|||||||
return ptr - data;
|
return ptr - data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
|
static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data_size)
|
||||||
{
|
{
|
||||||
struct l2cap_conf_rsp *rsp = data;
|
struct l2cap_conf_rsp *rsp = data;
|
||||||
void *ptr = rsp->data;
|
void *ptr = rsp->data;
|
||||||
|
void *endptr = data + data_size;
|
||||||
void *req = chan->conf_req;
|
void *req = chan->conf_req;
|
||||||
int len = chan->conf_len;
|
int len = chan->conf_len;
|
||||||
int type, hint, olen;
|
int type, hint, olen;
|
||||||
@ -3417,7 +3422,7 @@ done:
|
|||||||
return -ECONNREFUSED;
|
return -ECONNREFUSED;
|
||||||
|
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
|
||||||
(unsigned long) &rfc);
|
(unsigned long) &rfc, endptr - ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == L2CAP_CONF_SUCCESS) {
|
if (result == L2CAP_CONF_SUCCESS) {
|
||||||
@ -3430,7 +3435,7 @@ done:
|
|||||||
chan->omtu = mtu;
|
chan->omtu = mtu;
|
||||||
set_bit(CONF_MTU_DONE, &chan->conf_state);
|
set_bit(CONF_MTU_DONE, &chan->conf_state);
|
||||||
}
|
}
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu, endptr - ptr);
|
||||||
|
|
||||||
if (remote_efs) {
|
if (remote_efs) {
|
||||||
if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
|
if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
|
||||||
@ -3444,7 +3449,7 @@ done:
|
|||||||
|
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
|
||||||
sizeof(efs),
|
sizeof(efs),
|
||||||
(unsigned long) &efs);
|
(unsigned long) &efs, endptr - ptr);
|
||||||
} else {
|
} else {
|
||||||
/* Send PENDING Conf Rsp */
|
/* Send PENDING Conf Rsp */
|
||||||
result = L2CAP_CONF_PENDING;
|
result = L2CAP_CONF_PENDING;
|
||||||
@ -3477,7 +3482,7 @@ done:
|
|||||||
set_bit(CONF_MODE_DONE, &chan->conf_state);
|
set_bit(CONF_MODE_DONE, &chan->conf_state);
|
||||||
|
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
|
||||||
sizeof(rfc), (unsigned long) &rfc);
|
sizeof(rfc), (unsigned long) &rfc, endptr - ptr);
|
||||||
|
|
||||||
if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
|
if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
|
||||||
chan->remote_id = efs.id;
|
chan->remote_id = efs.id;
|
||||||
@ -3491,7 +3496,7 @@ done:
|
|||||||
le32_to_cpu(efs.sdu_itime);
|
le32_to_cpu(efs.sdu_itime);
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
|
||||||
sizeof(efs),
|
sizeof(efs),
|
||||||
(unsigned long) &efs);
|
(unsigned long) &efs, endptr - ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3505,7 +3510,7 @@ done:
|
|||||||
set_bit(CONF_MODE_DONE, &chan->conf_state);
|
set_bit(CONF_MODE_DONE, &chan->conf_state);
|
||||||
|
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
|
||||||
(unsigned long) &rfc);
|
(unsigned long) &rfc, endptr - ptr);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3527,10 +3532,11 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
|
static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
|
||||||
void *data, u16 *result)
|
void *data, size_t size, u16 *result)
|
||||||
{
|
{
|
||||||
struct l2cap_conf_req *req = data;
|
struct l2cap_conf_req *req = data;
|
||||||
void *ptr = req->data;
|
void *ptr = req->data;
|
||||||
|
void *endptr = data + size;
|
||||||
int type, olen;
|
int type, olen;
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
|
struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
|
||||||
@ -3548,13 +3554,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
|
|||||||
chan->imtu = L2CAP_DEFAULT_MIN_MTU;
|
chan->imtu = L2CAP_DEFAULT_MIN_MTU;
|
||||||
} else
|
} else
|
||||||
chan->imtu = val;
|
chan->imtu = val;
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONF_FLUSH_TO:
|
case L2CAP_CONF_FLUSH_TO:
|
||||||
chan->flush_to = val;
|
chan->flush_to = val;
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
|
||||||
2, chan->flush_to);
|
2, chan->flush_to, endptr - ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONF_RFC:
|
case L2CAP_CONF_RFC:
|
||||||
@ -3568,13 +3574,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
|
|||||||
chan->fcs = 0;
|
chan->fcs = 0;
|
||||||
|
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
|
||||||
sizeof(rfc), (unsigned long) &rfc);
|
sizeof(rfc), (unsigned long) &rfc, endptr - ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONF_EWS:
|
case L2CAP_CONF_EWS:
|
||||||
chan->ack_win = min_t(u16, val, chan->ack_win);
|
chan->ack_win = min_t(u16, val, chan->ack_win);
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
|
||||||
chan->tx_win);
|
chan->tx_win, endptr - ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONF_EFS:
|
case L2CAP_CONF_EFS:
|
||||||
@ -3587,7 +3593,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
|
|||||||
return -ECONNREFUSED;
|
return -ECONNREFUSED;
|
||||||
|
|
||||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
|
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
|
||||||
(unsigned long) &efs);
|
(unsigned long) &efs, endptr - ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONF_FCS:
|
case L2CAP_CONF_FCS:
|
||||||
@ -3692,7 +3698,7 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
|
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
|
||||||
l2cap_build_conf_req(chan, buf), buf);
|
l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
|
||||||
chan->num_conf_req++;
|
chan->num_conf_req++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3900,7 +3906,7 @@ sendresp:
|
|||||||
u8 buf[128];
|
u8 buf[128];
|
||||||
set_bit(CONF_REQ_SENT, &chan->conf_state);
|
set_bit(CONF_REQ_SENT, &chan->conf_state);
|
||||||
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
|
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
|
||||||
l2cap_build_conf_req(chan, buf), buf);
|
l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
|
||||||
chan->num_conf_req++;
|
chan->num_conf_req++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3978,7 +3984,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
|
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
|
||||||
l2cap_build_conf_req(chan, req), req);
|
l2cap_build_conf_req(chan, req, sizeof(req)), req);
|
||||||
chan->num_conf_req++;
|
chan->num_conf_req++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4090,7 +4096,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Complete config. */
|
/* Complete config. */
|
||||||
len = l2cap_parse_conf_req(chan, rsp);
|
len = l2cap_parse_conf_req(chan, rsp, sizeof(rsp));
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
l2cap_send_disconn_req(chan, ECONNRESET);
|
l2cap_send_disconn_req(chan, ECONNRESET);
|
||||||
goto unlock;
|
goto unlock;
|
||||||
@ -4124,7 +4130,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
|
|||||||
if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
|
if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
|
||||||
u8 buf[64];
|
u8 buf[64];
|
||||||
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
|
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
|
||||||
l2cap_build_conf_req(chan, buf), buf);
|
l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
|
||||||
chan->num_conf_req++;
|
chan->num_conf_req++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4184,7 +4190,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
|
|||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
len = l2cap_parse_conf_rsp(chan, rsp->data, len,
|
len = l2cap_parse_conf_rsp(chan, rsp->data, len,
|
||||||
buf, &result);
|
buf, sizeof(buf), &result);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
l2cap_send_disconn_req(chan, ECONNRESET);
|
l2cap_send_disconn_req(chan, ECONNRESET);
|
||||||
goto done;
|
goto done;
|
||||||
@ -4214,7 +4220,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
|
|||||||
/* throw out any old stored conf requests */
|
/* throw out any old stored conf requests */
|
||||||
result = L2CAP_CONF_SUCCESS;
|
result = L2CAP_CONF_SUCCESS;
|
||||||
len = l2cap_parse_conf_rsp(chan, rsp->data, len,
|
len = l2cap_parse_conf_rsp(chan, rsp->data, len,
|
||||||
req, &result);
|
req, sizeof(req), &result);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
l2cap_send_disconn_req(chan, ECONNRESET);
|
l2cap_send_disconn_req(chan, ECONNRESET);
|
||||||
goto done;
|
goto done;
|
||||||
@ -4791,7 +4797,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result,
|
|||||||
set_bit(CONF_REQ_SENT, &chan->conf_state);
|
set_bit(CONF_REQ_SENT, &chan->conf_state);
|
||||||
l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
|
l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
|
||||||
L2CAP_CONF_REQ,
|
L2CAP_CONF_REQ,
|
||||||
l2cap_build_conf_req(chan, buf), buf);
|
l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
|
||||||
chan->num_conf_req++;
|
chan->num_conf_req++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7465,7 +7471,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
|
|||||||
set_bit(CONF_REQ_SENT, &chan->conf_state);
|
set_bit(CONF_REQ_SENT, &chan->conf_state);
|
||||||
l2cap_send_cmd(conn, l2cap_get_ident(conn),
|
l2cap_send_cmd(conn, l2cap_get_ident(conn),
|
||||||
L2CAP_CONF_REQ,
|
L2CAP_CONF_REQ,
|
||||||
l2cap_build_conf_req(chan, buf),
|
l2cap_build_conf_req(chan, buf, sizeof(buf)),
|
||||||
buf);
|
buf);
|
||||||
chan->num_conf_req++;
|
chan->num_conf_req++;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user