|
@@ -710,7 +710,7 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
710
|
710
|
const void *iob_ll_src;
|
711
|
711
|
uint16_t iob_net_proto;
|
712
|
712
|
unsigned int iob_flags;
|
713
|
|
- size_t max_len;
|
|
713
|
+ size_t copy_len;
|
714
|
714
|
int rc;
|
715
|
715
|
|
716
|
716
|
DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
|
|
@@ -732,19 +732,15 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
732
|
732
|
}
|
733
|
733
|
DBGC2 ( snpdev, "+%zx\n", iob_len ( iobuf ) );
|
734
|
734
|
|
735
|
|
- /* Check buffer length */
|
736
|
|
- max_len = *len;
|
737
|
|
- *len = iob_len ( iobuf );
|
738
|
|
- if ( *len > max_len ) {
|
739
|
|
- rc = -ERANGE;
|
740
|
|
- goto out_too_long;
|
741
|
|
- }
|
742
|
|
-
|
743
|
735
|
/* Dequeue packet */
|
744
|
736
|
list_del ( &iobuf->list );
|
745
|
737
|
|
746
|
|
- /* Return packet to caller */
|
747
|
|
- memcpy ( data, iobuf->data, iob_len ( iobuf ) );
|
|
738
|
+ /* Return packet to caller, truncating to buffer length */
|
|
739
|
+ copy_len = iob_len ( iobuf );
|
|
740
|
+ if ( copy_len > *len )
|
|
741
|
+ copy_len = *len;
|
|
742
|
+ memcpy ( data, iobuf->data, copy_len );
|
|
743
|
+ *len = iob_len ( iobuf );
|
748
|
744
|
|
749
|
745
|
/* Attempt to decode link-layer header */
|
750
|
746
|
if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
|
|
@@ -765,11 +761,11 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
765
|
761
|
if ( net_proto )
|
766
|
762
|
*net_proto = ntohs ( iob_net_proto );
|
767
|
763
|
|
768
|
|
- rc = 0;
|
|
764
|
+ /* Check buffer length */
|
|
765
|
+ rc = ( ( copy_len == *len ) ? 0 : -ERANGE );
|
769
|
766
|
|
770
|
767
|
out_bad_ll_header:
|
771
|
768
|
free_iob ( iobuf );
|
772
|
|
- out_too_long:
|
773
|
769
|
out_no_packet:
|
774
|
770
|
return EFIRC ( rc );
|
775
|
771
|
}
|