@@ -57,7 +57,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
5757 u8 code , u8 ident , u16 dlen , void * data );
5858static void l2cap_send_cmd (struct l2cap_conn * conn , u8 ident , u8 code , u16 len ,
5959 void * data );
60- static int l2cap_build_conf_req (struct l2cap_chan * chan , void * data );
60+ static int l2cap_build_conf_req (struct l2cap_chan * chan , void * data , size_t data_size );
6161static void l2cap_send_disconn_req (struct l2cap_chan * chan , int err );
6262
6363static void l2cap_tx (struct l2cap_chan * chan , struct l2cap_ctrl * control ,
@@ -1462,7 +1462,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
14621462
14631463 set_bit (CONF_REQ_SENT , & chan -> conf_state );
14641464 l2cap_send_cmd (conn , l2cap_get_ident (conn ), L2CAP_CONF_REQ ,
1465- l2cap_build_conf_req (chan , buf ), buf );
1465+ l2cap_build_conf_req (chan , buf , sizeof ( buf ) ), buf );
14661466 chan -> num_conf_req ++ ;
14671467 }
14681468
@@ -2966,12 +2966,15 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
29662966 return len ;
29672967}
29682968
2969- static void l2cap_add_conf_opt (void * * ptr , u8 type , u8 len , unsigned long val )
2969+ static void l2cap_add_conf_opt (void * * ptr , u8 type , u8 len , unsigned long val , size_t size )
29702970{
29712971 struct l2cap_conf_opt * opt = * ptr ;
29722972
29732973 BT_DBG ("type 0x%2.2x len %u val 0x%lx" , type , len , val );
29742974
2975+ if (size < L2CAP_CONF_OPT_SIZE + len )
2976+ return ;
2977+
29752978 opt -> type = type ;
29762979 opt -> len = len ;
29772980
@@ -2996,7 +2999,7 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
29962999 * ptr += L2CAP_CONF_OPT_SIZE + len ;
29973000}
29983001
2999- static void l2cap_add_opt_efs (void * * ptr , struct l2cap_chan * chan )
3002+ static void l2cap_add_opt_efs (void * * ptr , struct l2cap_chan * chan , size_t size )
30003003{
30013004 struct l2cap_conf_efs efs ;
30023005
@@ -3024,7 +3027,7 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
30243027 }
30253028
30263029 l2cap_add_conf_opt (ptr , L2CAP_CONF_EFS , sizeof (efs ),
3027- (unsigned long ) & efs );
3030+ (unsigned long ) & efs , size );
30283031}
30293032
30303033static void l2cap_ack_timeout (struct work_struct * work )
@@ -3170,11 +3173,12 @@ static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
31703173 chan -> ack_win = chan -> tx_win ;
31713174}
31723175
3173- static int l2cap_build_conf_req (struct l2cap_chan * chan , void * data )
3176+ static int l2cap_build_conf_req (struct l2cap_chan * chan , void * data , size_t data_size )
31743177{
31753178 struct l2cap_conf_req * req = data ;
31763179 struct l2cap_conf_rfc rfc = { .mode = chan -> mode };
31773180 void * ptr = req -> data ;
3181+ void * endptr = data + data_size ;
31783182 u16 size ;
31793183
31803184 BT_DBG ("chan %p" , chan );
@@ -3199,7 +3203,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
31993203
32003204done :
32013205 if (chan -> imtu != L2CAP_DEFAULT_MTU )
3202- l2cap_add_conf_opt (& ptr , L2CAP_CONF_MTU , 2 , chan -> imtu );
3206+ l2cap_add_conf_opt (& ptr , L2CAP_CONF_MTU , 2 , chan -> imtu , endptr - ptr );
32033207
32043208 switch (chan -> mode ) {
32053209 case L2CAP_MODE_BASIC :
@@ -3218,7 +3222,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
32183222 rfc .max_pdu_size = 0 ;
32193223
32203224 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC , sizeof (rfc ),
3221- (unsigned long ) & rfc );
3225+ (unsigned long ) & rfc , endptr - ptr );
32223226 break ;
32233227
32243228 case L2CAP_MODE_ERTM :
@@ -3238,21 +3242,21 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
32383242 L2CAP_DEFAULT_TX_WINDOW );
32393243
32403244 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC , sizeof (rfc ),
3241- (unsigned long ) & rfc );
3245+ (unsigned long ) & rfc , endptr - ptr );
32423246
32433247 if (test_bit (FLAG_EFS_ENABLE , & chan -> flags ))
3244- l2cap_add_opt_efs (& ptr , chan );
3248+ l2cap_add_opt_efs (& ptr , chan , endptr - ptr );
32453249
32463250 if (test_bit (FLAG_EXT_CTRL , & chan -> flags ))
32473251 l2cap_add_conf_opt (& ptr , L2CAP_CONF_EWS , 2 ,
3248- chan -> tx_win );
3252+ chan -> tx_win , endptr - ptr );
32493253
32503254 if (chan -> conn -> feat_mask & L2CAP_FEAT_FCS )
32513255 if (chan -> fcs == L2CAP_FCS_NONE ||
32523256 test_bit (CONF_RECV_NO_FCS , & chan -> conf_state )) {
32533257 chan -> fcs = L2CAP_FCS_NONE ;
32543258 l2cap_add_conf_opt (& ptr , L2CAP_CONF_FCS , 1 ,
3255- chan -> fcs );
3259+ chan -> fcs , endptr - ptr );
32563260 }
32573261 break ;
32583262
@@ -3270,17 +3274,17 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
32703274 rfc .max_pdu_size = cpu_to_le16 (size );
32713275
32723276 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC , sizeof (rfc ),
3273- (unsigned long ) & rfc );
3277+ (unsigned long ) & rfc , endptr - ptr );
32743278
32753279 if (test_bit (FLAG_EFS_ENABLE , & chan -> flags ))
3276- l2cap_add_opt_efs (& ptr , chan );
3280+ l2cap_add_opt_efs (& ptr , chan , endptr - ptr );
32773281
32783282 if (chan -> conn -> feat_mask & L2CAP_FEAT_FCS )
32793283 if (chan -> fcs == L2CAP_FCS_NONE ||
32803284 test_bit (CONF_RECV_NO_FCS , & chan -> conf_state )) {
32813285 chan -> fcs = L2CAP_FCS_NONE ;
32823286 l2cap_add_conf_opt (& ptr , L2CAP_CONF_FCS , 1 ,
3283- chan -> fcs );
3287+ chan -> fcs , endptr - ptr );
32843288 }
32853289 break ;
32863290 }
@@ -3291,10 +3295,11 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
32913295 return ptr - data ;
32923296}
32933297
3294- static int l2cap_parse_conf_req (struct l2cap_chan * chan , void * data )
3298+ static int l2cap_parse_conf_req (struct l2cap_chan * chan , void * data , size_t data_size )
32953299{
32963300 struct l2cap_conf_rsp * rsp = data ;
32973301 void * ptr = rsp -> data ;
3302+ void * endptr = data + data_size ;
32983303 void * req = chan -> conf_req ;
32993304 int len = chan -> conf_len ;
33003305 int type , hint , olen ;
@@ -3396,7 +3401,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
33963401 return - ECONNREFUSED ;
33973402
33983403 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC , sizeof (rfc ),
3399- (unsigned long ) & rfc );
3404+ (unsigned long ) & rfc , endptr - ptr );
34003405 }
34013406
34023407 if (result == L2CAP_CONF_SUCCESS ) {
@@ -3409,7 +3414,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
34093414 chan -> omtu = mtu ;
34103415 set_bit (CONF_MTU_DONE , & chan -> conf_state );
34113416 }
3412- l2cap_add_conf_opt (& ptr , L2CAP_CONF_MTU , 2 , chan -> omtu );
3417+ l2cap_add_conf_opt (& ptr , L2CAP_CONF_MTU , 2 , chan -> omtu , endptr - ptr );
34133418
34143419 if (remote_efs ) {
34153420 if (chan -> local_stype != L2CAP_SERV_NOTRAFIC &&
@@ -3423,7 +3428,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
34233428
34243429 l2cap_add_conf_opt (& ptr , L2CAP_CONF_EFS ,
34253430 sizeof (efs ),
3426- (unsigned long ) & efs );
3431+ (unsigned long ) & efs , endptr - ptr );
34273432 } else {
34283433 /* Send PENDING Conf Rsp */
34293434 result = L2CAP_CONF_PENDING ;
@@ -3456,7 +3461,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
34563461 set_bit (CONF_MODE_DONE , & chan -> conf_state );
34573462
34583463 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC ,
3459- sizeof (rfc ), (unsigned long ) & rfc );
3464+ sizeof (rfc ), (unsigned long ) & rfc , endptr - ptr );
34603465
34613466 if (test_bit (FLAG_EFS_ENABLE , & chan -> flags )) {
34623467 chan -> remote_id = efs .id ;
@@ -3470,7 +3475,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
34703475 le32_to_cpu (efs .sdu_itime );
34713476 l2cap_add_conf_opt (& ptr , L2CAP_CONF_EFS ,
34723477 sizeof (efs ),
3473- (unsigned long ) & efs );
3478+ (unsigned long ) & efs , endptr - ptr );
34743479 }
34753480 break ;
34763481
@@ -3484,7 +3489,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
34843489 set_bit (CONF_MODE_DONE , & chan -> conf_state );
34853490
34863491 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC , sizeof (rfc ),
3487- (unsigned long ) & rfc );
3492+ (unsigned long ) & rfc , endptr - ptr );
34883493
34893494 break ;
34903495
@@ -3506,10 +3511,11 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
35063511}
35073512
35083513static int l2cap_parse_conf_rsp (struct l2cap_chan * chan , void * rsp , int len ,
3509- void * data , u16 * result )
3514+ void * data , size_t size , u16 * result )
35103515{
35113516 struct l2cap_conf_req * req = data ;
35123517 void * ptr = req -> data ;
3518+ void * endptr = data + size ;
35133519 int type , olen ;
35143520 unsigned long val ;
35153521 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
@@ -3527,13 +3533,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
35273533 chan -> imtu = L2CAP_DEFAULT_MIN_MTU ;
35283534 } else
35293535 chan -> imtu = val ;
3530- l2cap_add_conf_opt (& ptr , L2CAP_CONF_MTU , 2 , chan -> imtu );
3536+ l2cap_add_conf_opt (& ptr , L2CAP_CONF_MTU , 2 , chan -> imtu , endptr - ptr );
35313537 break ;
35323538
35333539 case L2CAP_CONF_FLUSH_TO :
35343540 chan -> flush_to = val ;
35353541 l2cap_add_conf_opt (& ptr , L2CAP_CONF_FLUSH_TO ,
3536- 2 , chan -> flush_to );
3542+ 2 , chan -> flush_to , endptr - ptr );
35373543 break ;
35383544
35393545 case L2CAP_CONF_RFC :
@@ -3547,13 +3553,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
35473553 chan -> fcs = 0 ;
35483554
35493555 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC ,
3550- sizeof (rfc ), (unsigned long ) & rfc );
3556+ sizeof (rfc ), (unsigned long ) & rfc , endptr - ptr );
35513557 break ;
35523558
35533559 case L2CAP_CONF_EWS :
35543560 chan -> ack_win = min_t (u16 , val , chan -> ack_win );
35553561 l2cap_add_conf_opt (& ptr , L2CAP_CONF_EWS , 2 ,
3556- chan -> tx_win );
3562+ chan -> tx_win , endptr - ptr );
35573563 break ;
35583564
35593565 case L2CAP_CONF_EFS :
@@ -3566,7 +3572,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
35663572 return - ECONNREFUSED ;
35673573
35683574 l2cap_add_conf_opt (& ptr , L2CAP_CONF_EFS , sizeof (efs ),
3569- (unsigned long ) & efs );
3575+ (unsigned long ) & efs , endptr - ptr );
35703576 break ;
35713577
35723578 case L2CAP_CONF_FCS :
@@ -3671,7 +3677,7 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
36713677 return ;
36723678
36733679 l2cap_send_cmd (conn , l2cap_get_ident (conn ), L2CAP_CONF_REQ ,
3674- l2cap_build_conf_req (chan , buf ), buf );
3680+ l2cap_build_conf_req (chan , buf , sizeof ( buf ) ), buf );
36753681 chan -> num_conf_req ++ ;
36763682}
36773683
@@ -3879,7 +3885,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
38793885 u8 buf [128 ];
38803886 set_bit (CONF_REQ_SENT , & chan -> conf_state );
38813887 l2cap_send_cmd (conn , l2cap_get_ident (conn ), L2CAP_CONF_REQ ,
3882- l2cap_build_conf_req (chan , buf ), buf );
3888+ l2cap_build_conf_req (chan , buf , sizeof ( buf ) ), buf );
38833889 chan -> num_conf_req ++ ;
38843890 }
38853891
@@ -3957,7 +3963,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
39573963 break ;
39583964
39593965 l2cap_send_cmd (conn , l2cap_get_ident (conn ), L2CAP_CONF_REQ ,
3960- l2cap_build_conf_req (chan , req ), req );
3966+ l2cap_build_conf_req (chan , req , sizeof ( req ) ), req );
39613967 chan -> num_conf_req ++ ;
39623968 break ;
39633969
@@ -4069,7 +4075,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
40694075 }
40704076
40714077 /* Complete config. */
4072- len = l2cap_parse_conf_req (chan , rsp );
4078+ len = l2cap_parse_conf_req (chan , rsp , sizeof ( rsp ) );
40734079 if (len < 0 ) {
40744080 l2cap_send_disconn_req (chan , ECONNRESET );
40754081 goto unlock ;
@@ -4103,7 +4109,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
41034109 if (!test_and_set_bit (CONF_REQ_SENT , & chan -> conf_state )) {
41044110 u8 buf [64 ];
41054111 l2cap_send_cmd (conn , l2cap_get_ident (conn ), L2CAP_CONF_REQ ,
4106- l2cap_build_conf_req (chan , buf ), buf );
4112+ l2cap_build_conf_req (chan , buf , sizeof ( buf ) ), buf );
41074113 chan -> num_conf_req ++ ;
41084114 }
41094115
@@ -4163,7 +4169,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
41634169 char buf [64 ];
41644170
41654171 len = l2cap_parse_conf_rsp (chan , rsp -> data , len ,
4166- buf , & result );
4172+ buf , sizeof ( buf ), & result );
41674173 if (len < 0 ) {
41684174 l2cap_send_disconn_req (chan , ECONNRESET );
41694175 goto done ;
@@ -4193,7 +4199,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
41934199 /* throw out any old stored conf requests */
41944200 result = L2CAP_CONF_SUCCESS ;
41954201 len = l2cap_parse_conf_rsp (chan , rsp -> data , len ,
4196- req , & result );
4202+ req , sizeof ( req ), & result );
41974203 if (len < 0 ) {
41984204 l2cap_send_disconn_req (chan , ECONNRESET );
41994205 goto done ;
@@ -4770,7 +4776,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result,
47704776 set_bit (CONF_REQ_SENT , & chan -> conf_state );
47714777 l2cap_send_cmd (chan -> conn , l2cap_get_ident (chan -> conn ),
47724778 L2CAP_CONF_REQ ,
4773- l2cap_build_conf_req (chan , buf ), buf );
4779+ l2cap_build_conf_req (chan , buf , sizeof ( buf ) ), buf );
47744780 chan -> num_conf_req ++ ;
47754781 }
47764782 }
@@ -7442,7 +7448,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
74427448 set_bit (CONF_REQ_SENT , & chan -> conf_state );
74437449 l2cap_send_cmd (conn , l2cap_get_ident (conn ),
74447450 L2CAP_CONF_REQ ,
7445- l2cap_build_conf_req (chan , buf ),
7451+ l2cap_build_conf_req (chan , buf , sizeof ( buf ) ),
74467452 buf );
74477453 chan -> num_conf_req ++ ;
74487454 }
0 commit comments