@@ -52,7 +52,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
5252 u8 code , u8 ident , u16 dlen , void * data );
5353static void l2cap_send_cmd (struct l2cap_conn * conn , u8 ident , u8 code , u16 len ,
5454 void * data );
55- static int l2cap_build_conf_req (struct l2cap_chan * chan , void * data );
55+ static int l2cap_build_conf_req (struct l2cap_chan * chan , void * data , size_t data_size );
5656static void l2cap_send_disconn_req (struct l2cap_chan * chan , int err );
5757
5858static void l2cap_tx (struct l2cap_chan * chan , struct l2cap_ctrl * control ,
@@ -1298,7 +1298,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
12981298
12991299 set_bit (CONF_REQ_SENT , & chan -> conf_state );
13001300 l2cap_send_cmd (conn , l2cap_get_ident (conn ), L2CAP_CONF_REQ ,
1301- l2cap_build_conf_req (chan , buf ), buf );
1301+ l2cap_build_conf_req (chan , buf , sizeof ( buf ) ), buf );
13021302 chan -> num_conf_req ++ ;
13031303 }
13041304
@@ -2992,12 +2992,15 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
29922992 return len ;
29932993}
29942994
2995- static void l2cap_add_conf_opt (void * * ptr , u8 type , u8 len , unsigned long val )
2995+ static void l2cap_add_conf_opt (void * * ptr , u8 type , u8 len , unsigned long val , size_t size )
29962996{
29972997 struct l2cap_conf_opt * opt = * ptr ;
29982998
29992999 BT_DBG ("type 0x%2.2x len %u val 0x%lx" , type , len , val );
30003000
3001+ if (size < L2CAP_CONF_OPT_SIZE + len )
3002+ return ;
3003+
30013004 opt -> type = type ;
30023005 opt -> len = len ;
30033006
@@ -3022,7 +3025,7 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
30223025 * ptr += L2CAP_CONF_OPT_SIZE + len ;
30233026}
30243027
3025- static void l2cap_add_opt_efs (void * * ptr , struct l2cap_chan * chan )
3028+ static void l2cap_add_opt_efs (void * * ptr , struct l2cap_chan * chan , size_t size )
30263029{
30273030 struct l2cap_conf_efs efs ;
30283031
@@ -3050,7 +3053,7 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
30503053 }
30513054
30523055 l2cap_add_conf_opt (ptr , L2CAP_CONF_EFS , sizeof (efs ),
3053- (unsigned long ) & efs );
3056+ (unsigned long ) & efs , size );
30543057}
30553058
30563059static void l2cap_ack_timeout (struct work_struct * work )
@@ -3194,11 +3197,12 @@ static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
31943197 chan -> ack_win = chan -> tx_win ;
31953198}
31963199
3197- static int l2cap_build_conf_req (struct l2cap_chan * chan , void * data )
3200+ static int l2cap_build_conf_req (struct l2cap_chan * chan , void * data , size_t data_size )
31983201{
31993202 struct l2cap_conf_req * req = data ;
32003203 struct l2cap_conf_rfc rfc = { .mode = chan -> mode };
32013204 void * ptr = req -> data ;
3205+ void * endptr = data + data_size ;
32023206 u16 size ;
32033207
32043208 BT_DBG ("chan %pK" , chan );
@@ -3223,7 +3227,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
32233227
32243228done :
32253229 if (chan -> imtu != L2CAP_DEFAULT_MTU )
3226- l2cap_add_conf_opt (& ptr , L2CAP_CONF_MTU , 2 , chan -> imtu );
3230+ l2cap_add_conf_opt (& ptr , L2CAP_CONF_MTU , 2 , chan -> imtu , endptr - ptr );
32273231
32283232 switch (chan -> mode ) {
32293233 case L2CAP_MODE_BASIC :
@@ -3239,7 +3243,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
32393243 rfc .max_pdu_size = 0 ;
32403244
32413245 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC , sizeof (rfc ),
3242- (unsigned long ) & rfc );
3246+ (unsigned long ) & rfc , endptr - ptr );
32433247 break ;
32443248
32453249 case L2CAP_MODE_ERTM :
@@ -3259,21 +3263,21 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
32593263 L2CAP_DEFAULT_TX_WINDOW );
32603264
32613265 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC , sizeof (rfc ),
3262- (unsigned long ) & rfc );
3266+ (unsigned long ) & rfc , endptr - ptr );
32633267
32643268 if (test_bit (FLAG_EFS_ENABLE , & chan -> flags ))
3265- l2cap_add_opt_efs (& ptr , chan );
3269+ l2cap_add_opt_efs (& ptr , chan , endptr - ptr );
32663270
32673271 if (test_bit (FLAG_EXT_CTRL , & chan -> flags ))
32683272 l2cap_add_conf_opt (& ptr , L2CAP_CONF_EWS , 2 ,
3269- chan -> tx_win );
3273+ chan -> tx_win , endptr - ptr );
32703274
32713275 if (chan -> conn -> feat_mask & L2CAP_FEAT_FCS )
32723276 if (chan -> fcs == L2CAP_FCS_NONE ||
32733277 test_bit (CONF_RECV_NO_FCS , & chan -> conf_state )) {
32743278 chan -> fcs = L2CAP_FCS_NONE ;
32753279 l2cap_add_conf_opt (& ptr , L2CAP_CONF_FCS , 1 ,
3276- chan -> fcs );
3280+ chan -> fcs , endptr - ptr );
32773281 }
32783282 break ;
32793283
@@ -3291,17 +3295,17 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
32913295 rfc .max_pdu_size = cpu_to_le16 (size );
32923296
32933297 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC , sizeof (rfc ),
3294- (unsigned long ) & rfc );
3298+ (unsigned long ) & rfc , endptr - ptr );
32953299
32963300 if (test_bit (FLAG_EFS_ENABLE , & chan -> flags ))
3297- l2cap_add_opt_efs (& ptr , chan );
3301+ l2cap_add_opt_efs (& ptr , chan , endptr - ptr );
32983302
32993303 if (chan -> conn -> feat_mask & L2CAP_FEAT_FCS )
33003304 if (chan -> fcs == L2CAP_FCS_NONE ||
33013305 test_bit (CONF_RECV_NO_FCS , & chan -> conf_state )) {
33023306 chan -> fcs = L2CAP_FCS_NONE ;
33033307 l2cap_add_conf_opt (& ptr , L2CAP_CONF_FCS , 1 ,
3304- chan -> fcs );
3308+ chan -> fcs , endptr - ptr );
33053309 }
33063310 break ;
33073311 }
@@ -3312,10 +3316,11 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
33123316 return ptr - data ;
33133317}
33143318
3315- static int l2cap_parse_conf_req (struct l2cap_chan * chan , void * data )
3319+ static int l2cap_parse_conf_req (struct l2cap_chan * chan , void * data , size_t data_size )
33163320{
33173321 struct l2cap_conf_rsp * rsp = data ;
33183322 void * ptr = rsp -> data ;
3323+ void * endptr = data + data_size ;
33193324 void * req = chan -> conf_req ;
33203325 int len = chan -> conf_len ;
33213326 int type , hint , olen ;
@@ -3417,7 +3422,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
34173422 return - ECONNREFUSED ;
34183423
34193424 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC , sizeof (rfc ),
3420- (unsigned long ) & rfc );
3425+ (unsigned long ) & rfc , endptr - ptr );
34213426 }
34223427
34233428 if (result == L2CAP_CONF_SUCCESS ) {
@@ -3430,7 +3435,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
34303435 chan -> omtu = mtu ;
34313436 set_bit (CONF_MTU_DONE , & chan -> conf_state );
34323437 }
3433- l2cap_add_conf_opt (& ptr , L2CAP_CONF_MTU , 2 , chan -> omtu );
3438+ l2cap_add_conf_opt (& ptr , L2CAP_CONF_MTU , 2 , chan -> omtu , endptr - ptr );
34343439
34353440 if (remote_efs ) {
34363441 if (chan -> local_stype != L2CAP_SERV_NOTRAFIC &&
@@ -3444,7 +3449,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
34443449
34453450 l2cap_add_conf_opt (& ptr , L2CAP_CONF_EFS ,
34463451 sizeof (efs ),
3447- (unsigned long ) & efs );
3452+ (unsigned long ) & efs , endptr - ptr );
34483453 } else {
34493454 /* Send PENDING Conf Rsp */
34503455 result = L2CAP_CONF_PENDING ;
@@ -3477,7 +3482,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
34773482 set_bit (CONF_MODE_DONE , & chan -> conf_state );
34783483
34793484 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC ,
3480- sizeof (rfc ), (unsigned long ) & rfc );
3485+ sizeof (rfc ), (unsigned long ) & rfc , endptr - ptr );
34813486
34823487 if (test_bit (FLAG_EFS_ENABLE , & chan -> flags )) {
34833488 chan -> remote_id = efs .id ;
@@ -3491,7 +3496,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
34913496 le32_to_cpu (efs .sdu_itime );
34923497 l2cap_add_conf_opt (& ptr , L2CAP_CONF_EFS ,
34933498 sizeof (efs ),
3494- (unsigned long ) & efs );
3499+ (unsigned long ) & efs , endptr - ptr );
34953500 }
34963501 break ;
34973502
@@ -3505,7 +3510,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
35053510 set_bit (CONF_MODE_DONE , & chan -> conf_state );
35063511
35073512 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC , sizeof (rfc ),
3508- (unsigned long ) & rfc );
3513+ (unsigned long ) & rfc , endptr - ptr );
35093514
35103515 break ;
35113516
@@ -3527,10 +3532,11 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
35273532}
35283533
35293534static int l2cap_parse_conf_rsp (struct l2cap_chan * chan , void * rsp , int len ,
3530- void * data , u16 * result )
3535+ void * data , size_t size , u16 * result )
35313536{
35323537 struct l2cap_conf_req * req = data ;
35333538 void * ptr = req -> data ;
3539+ void * endptr = data + size ;
35343540 int type , olen ;
35353541 unsigned long val ;
35363542 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,
35483554 chan -> imtu = L2CAP_DEFAULT_MIN_MTU ;
35493555 } else
35503556 chan -> imtu = val ;
3551- l2cap_add_conf_opt (& ptr , L2CAP_CONF_MTU , 2 , chan -> imtu );
3557+ l2cap_add_conf_opt (& ptr , L2CAP_CONF_MTU , 2 , chan -> imtu , endptr - ptr );
35523558 break ;
35533559
35543560 case L2CAP_CONF_FLUSH_TO :
35553561 chan -> flush_to = val ;
35563562 l2cap_add_conf_opt (& ptr , L2CAP_CONF_FLUSH_TO ,
3557- 2 , chan -> flush_to );
3563+ 2 , chan -> flush_to , endptr - ptr );
35583564 break ;
35593565
35603566 case L2CAP_CONF_RFC :
@@ -3568,13 +3574,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
35683574 chan -> fcs = 0 ;
35693575
35703576 l2cap_add_conf_opt (& ptr , L2CAP_CONF_RFC ,
3571- sizeof (rfc ), (unsigned long ) & rfc );
3577+ sizeof (rfc ), (unsigned long ) & rfc , endptr - ptr );
35723578 break ;
35733579
35743580 case L2CAP_CONF_EWS :
35753581 chan -> ack_win = min_t (u16 , val , chan -> ack_win );
35763582 l2cap_add_conf_opt (& ptr , L2CAP_CONF_EWS , 2 ,
3577- chan -> tx_win );
3583+ chan -> tx_win , endptr - ptr );
35783584 break ;
35793585
35803586 case L2CAP_CONF_EFS :
@@ -3587,7 +3593,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
35873593 return - ECONNREFUSED ;
35883594
35893595 l2cap_add_conf_opt (& ptr , L2CAP_CONF_EFS , sizeof (efs ),
3590- (unsigned long ) & efs );
3596+ (unsigned long ) & efs , endptr - ptr );
35913597 break ;
35923598
35933599 case L2CAP_CONF_FCS :
@@ -3677,7 +3683,7 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
36773683 return ;
36783684
36793685 l2cap_send_cmd (conn , l2cap_get_ident (conn ), L2CAP_CONF_REQ ,
3680- l2cap_build_conf_req (chan , buf ), buf );
3686+ l2cap_build_conf_req (chan , buf , sizeof ( buf ) ), buf );
36813687 chan -> num_conf_req ++ ;
36823688}
36833689
@@ -3885,7 +3891,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
38853891 u8 buf [128 ];
38863892 set_bit (CONF_REQ_SENT , & chan -> conf_state );
38873893 l2cap_send_cmd (conn , l2cap_get_ident (conn ), L2CAP_CONF_REQ ,
3888- l2cap_build_conf_req (chan , buf ), buf );
3894+ l2cap_build_conf_req (chan , buf , sizeof ( buf ) ), buf );
38893895 chan -> num_conf_req ++ ;
38903896 }
38913897
@@ -3965,7 +3971,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
39653971 break ;
39663972
39673973 l2cap_send_cmd (conn , l2cap_get_ident (conn ), L2CAP_CONF_REQ ,
3968- l2cap_build_conf_req (chan , req ), req );
3974+ l2cap_build_conf_req (chan , req , sizeof ( req ) ), req );
39693975 chan -> num_conf_req ++ ;
39703976 break ;
39713977
@@ -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 ;
@@ -4776,7 +4782,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result,
47764782 set_bit (CONF_REQ_SENT , & chan -> conf_state );
47774783 l2cap_send_cmd (chan -> conn , l2cap_get_ident (chan -> conn ),
47784784 L2CAP_CONF_REQ ,
4779- l2cap_build_conf_req (chan , buf ), buf );
4785+ l2cap_build_conf_req (chan , buf , sizeof ( buf ) ), buf );
47804786 chan -> num_conf_req ++ ;
47814787 }
47824788 }
@@ -6662,7 +6668,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
66626668 set_bit (CONF_REQ_SENT , & chan -> conf_state );
66636669 l2cap_send_cmd (conn , l2cap_get_ident (conn ),
66646670 L2CAP_CONF_REQ ,
6665- l2cap_build_conf_req (chan , buf ),
6671+ l2cap_build_conf_req (chan , buf , sizeof ( buf ) ),
66666672 buf );
66676673 chan -> num_conf_req ++ ;
66686674 }
0 commit comments