@@ -549,17 +549,34 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
549
549
550
550
switch (recvmsg -> type ) {
551
551
case SMB_DIRECT_MSG_NEGOTIATE_REQ :
552
+ if (wc -> byte_len < sizeof (struct smb_direct_negotiate_req )) {
553
+ put_empty_recvmsg (t , recvmsg );
554
+ return ;
555
+ }
552
556
t -> negotiation_requested = true;
553
557
t -> full_packet_received = true;
554
558
wake_up_interruptible (& t -> wait_status );
555
559
break ;
556
560
case SMB_DIRECT_MSG_DATA_TRANSFER : {
557
561
struct smb_direct_data_transfer * data_transfer =
558
562
(struct smb_direct_data_transfer * )recvmsg -> packet ;
559
- int data_length = le32_to_cpu ( data_transfer -> data_length ) ;
563
+ unsigned int data_length ;
560
564
int avail_recvmsg_count , receive_credits ;
561
565
566
+ if (wc -> byte_len <
567
+ offsetof(struct smb_direct_data_transfer , padding )) {
568
+ put_empty_recvmsg (t , recvmsg );
569
+ return ;
570
+ }
571
+
572
+ data_length = le32_to_cpu (data_transfer -> data_length );
562
573
if (data_length ) {
574
+ if (wc -> byte_len < sizeof (struct smb_direct_data_transfer ) +
575
+ (u64 )data_length ) {
576
+ put_empty_recvmsg (t , recvmsg );
577
+ return ;
578
+ }
579
+
563
580
if (t -> full_packet_received )
564
581
recvmsg -> first_segment = true;
565
582
@@ -568,7 +585,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
568
585
else
569
586
t -> full_packet_received = true;
570
587
571
- enqueue_reassembly (t , recvmsg , data_length );
588
+ enqueue_reassembly (t , recvmsg , ( int ) data_length );
572
589
wake_up_interruptible (& t -> wait_reassembly_queue );
573
590
574
591
spin_lock (& t -> receive_credit_lock );
0 commit comments