Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'bt-fix' (bluetooth fixes from Marcel)

Pull bluetooth fix from Marcel Holtmann:
"All of our mgmt-tester, l2cap-test and rfcomm-tester unit tests are
passing with this patch"

* emailed patch from Marcel Holtmann <marcel@holtmann.org>:
Bluetooth: Properly check L2CAP config option output buffer length

+43 -37
+43 -37
net/bluetooth/l2cap_core.c
··· 58 58 u8 code, u8 ident, u16 dlen, void *data); 59 59 static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, 60 60 void *data); 61 - static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); 61 + static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size); 62 62 static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err); 63 63 64 64 static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, ··· 1473 1473 1474 1474 set_bit(CONF_REQ_SENT, &chan->conf_state); 1475 1475 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, 1476 - l2cap_build_conf_req(chan, buf), buf); 1476 + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); 1477 1477 chan->num_conf_req++; 1478 1478 } 1479 1479 ··· 2987 2987 return len; 2988 2988 } 2989 2989 2990 - static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) 2990 + static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val, size_t size) 2991 2991 { 2992 2992 struct l2cap_conf_opt *opt = *ptr; 2993 2993 2994 2994 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val); 2995 + 2996 + if (size < L2CAP_CONF_OPT_SIZE + len) 2997 + return; 2995 2998 2996 2999 opt->type = type; 2997 3000 opt->len = len; ··· 3020 3017 *ptr += L2CAP_CONF_OPT_SIZE + len; 3021 3018 } 3022 3019 3023 - static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) 3020 + static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan, size_t size) 3024 3021 { 3025 3022 struct l2cap_conf_efs efs; 3026 3023 ··· 3048 3045 } 3049 3046 3050 3047 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs), 3051 - (unsigned long) &efs); 3048 + (unsigned long) &efs, size); 3052 3049 } 3053 3050 3054 3051 static void l2cap_ack_timeout(struct work_struct *work) ··· 3194 3191 chan->ack_win = chan->tx_win; 3195 3192 } 3196 3193 3197 - static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) 3194 + static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size) 3198 3195 { 3199 3196 struct l2cap_conf_req *req = data; 3200 3197 struct l2cap_conf_rfc rfc = { .mode = chan->mode }; 3201 3198 void *ptr = req->data; 3199 + void *endptr = data + data_size; 3202 3200 u16 size; 3203 3201 3204 3202 BT_DBG("chan %p", chan); ··· 3224 3220 3225 3221 done: 3226 3222 if (chan->imtu != L2CAP_DEFAULT_MTU) 3227 - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); 3223 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr); 3228 3224 3229 3225 switch (chan->mode) { 3230 3226 case L2CAP_MODE_BASIC: ··· 3243 3239 rfc.max_pdu_size = 0; 3244 3240 3245 3241 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), 3246 - (unsigned long) &rfc); 3242 + (unsigned long) &rfc, endptr - ptr); 3247 3243 break; 3248 3244 3249 3245 case L2CAP_MODE_ERTM: ··· 3263 3259 L2CAP_DEFAULT_TX_WINDOW); 3264 3260 3265 3261 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), 3266 - (unsigned long) &rfc); 3262 + (unsigned long) &rfc, endptr - ptr); 3267 3263 3268 3264 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) 3269 - l2cap_add_opt_efs(&ptr, chan); 3265 + l2cap_add_opt_efs(&ptr, chan, endptr - ptr); 3270 3266 3271 3267 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) 3272 3268 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, 3273 - chan->tx_win); 3269 + chan->tx_win, endptr - ptr); 3274 3270 3275 3271 if (chan->conn->feat_mask & L2CAP_FEAT_FCS) 3276 3272 if (chan->fcs == L2CAP_FCS_NONE || 3277 3273 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) { 3278 3274 chan->fcs = L2CAP_FCS_NONE; 3279 3275 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, 3280 - chan->fcs); 3276 + chan->fcs, endptr - ptr); 3281 3277 } 3282 3278 break; 3283 3279 ··· 3295 3291 rfc.max_pdu_size = cpu_to_le16(size); 3296 3292 3297 3293 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), 3298 - (unsigned long) &rfc); 3294 + (unsigned long) &rfc, endptr - ptr); 3299 3295 3300 3296 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) 3301 - l2cap_add_opt_efs(&ptr, chan); 3297 + l2cap_add_opt_efs(&ptr, chan, endptr - ptr); 3302 3298 3303 3299 if (chan->conn->feat_mask & L2CAP_FEAT_FCS) 3304 3300 if (chan->fcs == L2CAP_FCS_NONE || 3305 3301 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) { 3306 3302 chan->fcs = L2CAP_FCS_NONE; 3307 3303 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, 3308 - chan->fcs); 3304 + chan->fcs, endptr - ptr); 3309 3305 } 3310 3306 break; 3311 3307 } ··· 3316 3312 return ptr - data; 3317 3313 } 3318 3314 3319 - static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) 3315 + static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data_size) 3320 3316 { 3321 3317 struct l2cap_conf_rsp *rsp = data; 3322 3318 void *ptr = rsp->data; 3319 + void *endptr = data + data_size; 3323 3320 void *req = chan->conf_req; 3324 3321 int len = chan->conf_len; 3325 3322 int type, hint, olen; ··· 3422 3417 return -ECONNREFUSED; 3423 3418 3424 3419 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), 3425 - (unsigned long) &rfc); 3420 + (unsigned long) &rfc, endptr - ptr); 3426 3421 } 3427 3422 3428 3423 if (result == L2CAP_CONF_SUCCESS) { ··· 3435 3430 chan->omtu = mtu; 3436 3431 set_bit(CONF_MTU_DONE, &chan->conf_state); 3437 3432 } 3438 - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); 3433 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu, endptr - ptr); 3439 3434 3440 3435 if (remote_efs) { 3441 3436 if (chan->local_stype != L2CAP_SERV_NOTRAFIC && ··· 3449 3444 3450 3445 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, 3451 3446 sizeof(efs), 3452 - (unsigned long) &efs); 3447 + (unsigned long) &efs, endptr - ptr); 3453 3448 } else { 3454 3449 /* Send PENDING Conf Rsp */ 3455 3450 result = L2CAP_CONF_PENDING; ··· 3482 3477 set_bit(CONF_MODE_DONE, &chan->conf_state); 3483 3478 3484 3479 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, 3485 - sizeof(rfc), (unsigned long) &rfc); 3480 + sizeof(rfc), (unsigned long) &rfc, endptr - ptr); 3486 3481 3487 3482 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { 3488 3483 chan->remote_id = efs.id; ··· 3496 3491 le32_to_cpu(efs.sdu_itime); 3497 3492 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, 3498 3493 sizeof(efs), 3499 - (unsigned long) &efs); 3494 + (unsigned long) &efs, endptr - ptr); 3500 3495 } 3501 3496 break; 3502 3497 ··· 3510 3505 set_bit(CONF_MODE_DONE, &chan->conf_state); 3511 3506 3512 3507 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), 3513 - (unsigned long) &rfc); 3508 + (unsigned long) &rfc, endptr - ptr); 3514 3509 3515 3510 break; 3516 3511 ··· 3532 3527 } 3533 3528 3534 3529 static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, 3535 - void *data, u16 *result) 3530 + void *data, size_t size, u16 *result) 3536 3531 { 3537 3532 struct l2cap_conf_req *req = data; 3538 3533 void *ptr = req->data; 3534 + void *endptr = data + size; 3539 3535 int type, olen; 3540 3536 unsigned long val; 3541 3537 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; ··· 3554 3548 chan->imtu = L2CAP_DEFAULT_MIN_MTU; 3555 3549 } else 3556 3550 chan->imtu = val; 3557 - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); 3551 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr); 3558 3552 break; 3559 3553 3560 3554 case L2CAP_CONF_FLUSH_TO: 3561 3555 chan->flush_to = val; 3562 3556 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 3563 - 2, chan->flush_to); 3557 + 2, chan->flush_to, endptr - ptr); 3564 3558 break; 3565 3559 3566 3560 case L2CAP_CONF_RFC: ··· 3574 3568 chan->fcs = 0; 3575 3569 3576 3570 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, 3577 - sizeof(rfc), (unsigned long) &rfc); 3571 + sizeof(rfc), (unsigned long) &rfc, endptr - ptr); 3578 3572 break; 3579 3573 3580 3574 case L2CAP_CONF_EWS: 3581 3575 chan->ack_win = min_t(u16, val, chan->ack_win); 3582 3576 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, 3583 - chan->tx_win); 3577 + chan->tx_win, endptr - ptr); 3584 3578 break; 3585 3579 3586 3580 case L2CAP_CONF_EFS: ··· 3593 3587 return -ECONNREFUSED; 3594 3588 3595 3589 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), 3596 - (unsigned long) &efs); 3590 + (unsigned long) &efs, endptr - ptr); 3597 3591 break; 3598 3592 3599 3593 case L2CAP_CONF_FCS: ··· 3698 3692 return; 3699 3693 3700 3694 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, 3701 - l2cap_build_conf_req(chan, buf), buf); 3695 + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); 3702 3696 chan->num_conf_req++; 3703 3697 } 3704 3698 ··· 3906 3900 u8 buf[128]; 3907 3901 set_bit(CONF_REQ_SENT, &chan->conf_state); 3908 3902 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, 3909 - l2cap_build_conf_req(chan, buf), buf); 3903 + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); 3910 3904 chan->num_conf_req++; 3911 3905 } 3912 3906 ··· 3984 3978 break; 3985 3979 3986 3980 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, 3987 - l2cap_build_conf_req(chan, req), req); 3981 + l2cap_build_conf_req(chan, req, sizeof(req)), req); 3988 3982 chan->num_conf_req++; 3989 3983 break; 3990 3984 ··· 4096 4090 } 4097 4091 4098 4092 /* Complete config. */ 4099 - len = l2cap_parse_conf_req(chan, rsp); 4093 + len = l2cap_parse_conf_req(chan, rsp, sizeof(rsp)); 4100 4094 if (len < 0) { 4101 4095 l2cap_send_disconn_req(chan, ECONNRESET); 4102 4096 goto unlock; ··· 4130 4124 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) { 4131 4125 u8 buf[64]; 4132 4126 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, 4133 - l2cap_build_conf_req(chan, buf), buf); 4127 + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); 4134 4128 chan->num_conf_req++; 4135 4129 } 4136 4130 ··· 4190 4184 char buf[64]; 4191 4185 4192 4186 len = l2cap_parse_conf_rsp(chan, rsp->data, len, 4193 - buf, &result); 4187 + buf, sizeof(buf), &result); 4194 4188 if (len < 0) { 4195 4189 l2cap_send_disconn_req(chan, ECONNRESET); 4196 4190 goto done; ··· 4220 4214 /* throw out any old stored conf requests */ 4221 4215 result = L2CAP_CONF_SUCCESS; 4222 4216 len = l2cap_parse_conf_rsp(chan, rsp->data, len, 4223 - req, &result); 4217 + req, sizeof(req), &result); 4224 4218 if (len < 0) { 4225 4219 l2cap_send_disconn_req(chan, ECONNRESET); 4226 4220 goto done; ··· 4797 4791 set_bit(CONF_REQ_SENT, &chan->conf_state); 4798 4792 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn), 4799 4793 L2CAP_CONF_REQ, 4800 - l2cap_build_conf_req(chan, buf), buf); 4794 + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); 4801 4795 chan->num_conf_req++; 4802 4796 } 4803 4797 } ··· 7471 7465 set_bit(CONF_REQ_SENT, &chan->conf_state); 7472 7466 l2cap_send_cmd(conn, l2cap_get_ident(conn), 7473 7467 L2CAP_CONF_REQ, 7474 - l2cap_build_conf_req(chan, buf), 7468 + l2cap_build_conf_req(chan, buf, sizeof(buf)), 7475 7469 buf); 7476 7470 chan->num_conf_req++; 7477 7471 }