@@ -8270,10 +8270,73 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
82708270 mutex_unlock (& conn -> chan_lock );
82718271}
82728272
8273+ /* Append fragment into frame respecting the maximum len of rx_skb */
8274+ static int l2cap_recv_frag (struct l2cap_conn * conn , struct sk_buff * skb ,
8275+ u16 len )
8276+ {
8277+ if (!conn -> rx_skb ) {
8278+ /* Allocate skb for the complete frame (with header) */
8279+ conn -> rx_skb = bt_skb_alloc (len , GFP_KERNEL );
8280+ if (!conn -> rx_skb )
8281+ return - ENOMEM ;
8282+ /* Init rx_len */
8283+ conn -> rx_len = len ;
8284+ }
8285+
8286+ /* Copy as much as the rx_skb can hold */
8287+ len = min_t (u16 , len , skb -> len );
8288+ skb_copy_from_linear_data (skb , skb_put (conn -> rx_skb , len ), len );
8289+ skb_pull (skb , len );
8290+ conn -> rx_len -= len ;
8291+
8292+ return len ;
8293+ }
8294+
8295+ static int l2cap_recv_len (struct l2cap_conn * conn , struct sk_buff * skb )
8296+ {
8297+ struct sk_buff * rx_skb ;
8298+ int len ;
8299+
8300+ /* Append just enough to complete the header */
8301+ len = l2cap_recv_frag (conn , skb , L2CAP_LEN_SIZE - conn -> rx_skb -> len );
8302+
8303+ /* If header could not be read just continue */
8304+ if (len < 0 || conn -> rx_skb -> len < L2CAP_LEN_SIZE )
8305+ return len ;
8306+
8307+ rx_skb = conn -> rx_skb ;
8308+ len = get_unaligned_le16 (rx_skb -> data );
8309+
8310+ /* Check if rx_skb has enough space to received all fragments */
8311+ if (len + (L2CAP_HDR_SIZE - L2CAP_LEN_SIZE ) <= skb_tailroom (rx_skb )) {
8312+ /* Update expected len */
8313+ conn -> rx_len = len + (L2CAP_HDR_SIZE - L2CAP_LEN_SIZE );
8314+ return L2CAP_LEN_SIZE ;
8315+ }
8316+
8317+ /* Reset conn->rx_skb since it will need to be reallocated in order to
8318+ * fit all fragments.
8319+ */
8320+ conn -> rx_skb = NULL ;
8321+
8322+ /* Reallocates rx_skb using the exact expected length */
8323+ len = l2cap_recv_frag (conn , rx_skb ,
8324+ len + (L2CAP_HDR_SIZE - L2CAP_LEN_SIZE ));
8325+ kfree_skb (rx_skb );
8326+
8327+ return len ;
8328+ }
8329+
8330+ static void l2cap_recv_reset (struct l2cap_conn * conn )
8331+ {
8332+ kfree_skb (conn -> rx_skb );
8333+ conn -> rx_skb = NULL ;
8334+ conn -> rx_len = 0 ;
8335+ }
8336+
82738337void l2cap_recv_acldata (struct hci_conn * hcon , struct sk_buff * skb , u16 flags )
82748338{
82758339 struct l2cap_conn * conn = hcon -> l2cap_data ;
8276- struct l2cap_hdr * hdr ;
82778340 int len ;
82788341
82798342 /* For AMP controller do not create l2cap conn */
@@ -8292,23 +8355,23 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
82928355 case ACL_START :
82938356 case ACL_START_NO_FLUSH :
82948357 case ACL_COMPLETE :
8295- if (conn -> rx_len ) {
8358+ if (conn -> rx_skb ) {
82968359 BT_ERR ("Unexpected start frame (len %d)" , skb -> len );
8297- kfree_skb (conn -> rx_skb );
8298- conn -> rx_skb = NULL ;
8299- conn -> rx_len = 0 ;
8360+ l2cap_recv_reset (conn );
83008361 l2cap_conn_unreliable (conn , ECOMM );
83018362 }
83028363
8303- /* Start fragment always begin with Basic L2CAP header */
8304- if (skb -> len < L2CAP_HDR_SIZE ) {
8305- BT_ERR ("Frame is too short (len %d)" , skb -> len );
8306- l2cap_conn_unreliable (conn , ECOMM );
8307- goto drop ;
8364+ /* Start fragment may not contain the L2CAP length so just
8365+ * copy the initial byte when that happens and use conn->mtu as
8366+ * expected length.
8367+ */
8368+ if (skb -> len < L2CAP_LEN_SIZE ) {
8369+ if (l2cap_recv_frag (conn , skb , conn -> mtu ) < 0 )
8370+ goto drop ;
8371+ return ;
83088372 }
83098373
8310- hdr = (struct l2cap_hdr * ) skb -> data ;
8311- len = __le16_to_cpu (hdr -> len ) + L2CAP_HDR_SIZE ;
8374+ len = get_unaligned_le16 (skb -> data ) + L2CAP_HDR_SIZE ;
83128375
83138376 if (len == skb -> len ) {
83148377 /* Complete frame received */
@@ -8325,38 +8388,43 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
83258388 goto drop ;
83268389 }
83278390
8328- /* Allocate skb for the complete frame (with header) */
8329- conn -> rx_skb = bt_skb_alloc (len , GFP_KERNEL );
8330- if (!conn -> rx_skb )
8391+ /* Append fragment into frame (with header) */
8392+ if (l2cap_recv_frag (conn , skb , len ) < 0 )
83318393 goto drop ;
83328394
8333- skb_copy_from_linear_data (skb , skb_put (conn -> rx_skb , skb -> len ),
8334- skb -> len );
8335- conn -> rx_len = len - skb -> len ;
83368395 break ;
83378396
83388397 case ACL_CONT :
83398398 BT_DBG ("Cont: frag len %d (expecting %d)" , skb -> len , conn -> rx_len );
83408399
8341- if (!conn -> rx_len ) {
8400+ if (!conn -> rx_skb ) {
83428401 BT_ERR ("Unexpected continuation frame (len %d)" , skb -> len );
83438402 l2cap_conn_unreliable (conn , ECOMM );
83448403 goto drop ;
83458404 }
83468405
8406+ /* Complete the L2CAP length if it has not been read */
8407+ if (conn -> rx_skb -> len < L2CAP_LEN_SIZE ) {
8408+ if (l2cap_recv_len (conn , skb ) < 0 ) {
8409+ l2cap_conn_unreliable (conn , ECOMM );
8410+ goto drop ;
8411+ }
8412+
8413+ /* Header still could not be read just continue */
8414+ if (conn -> rx_skb -> len < L2CAP_LEN_SIZE )
8415+ return ;
8416+ }
8417+
83478418 if (skb -> len > conn -> rx_len ) {
83488419 BT_ERR ("Fragment is too long (len %d, expected %d)" ,
83498420 skb -> len , conn -> rx_len );
8350- kfree_skb (conn -> rx_skb );
8351- conn -> rx_skb = NULL ;
8352- conn -> rx_len = 0 ;
8421+ l2cap_recv_reset (conn );
83538422 l2cap_conn_unreliable (conn , ECOMM );
83548423 goto drop ;
83558424 }
83568425
8357- skb_copy_from_linear_data (skb , skb_put (conn -> rx_skb , skb -> len ),
8358- skb -> len );
8359- conn -> rx_len -= skb -> len ;
8426+ /* Append fragment into frame (with header) */
8427+ l2cap_recv_frag (conn , skb , skb -> len );
83608428
83618429 if (!conn -> rx_len ) {
83628430 /* Complete frame received. l2cap_recv_frame
0 commit comments