Browse Source

[efi] Match behaviour of SnpDxe for truncated received packets

The UEFI specification does not state whether or not a return value of
EFI_BUFFER_TOO_SMALL from the SNP Receive() method should follow the
usual EFI API behaviour of allowing the caller to retry the request
with an increased buffer size.

Examination of the SnpDxe driver in EDK2 suggests that Receive() will
just return the truncated packet (complete with any requested
link-layer header fields), so match this behaviour.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 7 years ago
parent
commit
e8f30571a3
1 changed files with 9 additions and 13 deletions
  1. 9
    13
      src/interface/efi/efi_snp.c

+ 9
- 13
src/interface/efi/efi_snp.c View File

710
 	const void *iob_ll_src;
710
 	const void *iob_ll_src;
711
 	uint16_t iob_net_proto;
711
 	uint16_t iob_net_proto;
712
 	unsigned int iob_flags;
712
 	unsigned int iob_flags;
713
-	size_t max_len;
713
+	size_t copy_len;
714
 	int rc;
714
 	int rc;
715
 
715
 
716
 	DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
716
 	DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
732
 	}
732
 	}
733
 	DBGC2 ( snpdev, "+%zx\n", iob_len ( iobuf ) );
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
 	/* Dequeue packet */
735
 	/* Dequeue packet */
744
 	list_del ( &iobuf->list );
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
 	/* Attempt to decode link-layer header */
745
 	/* Attempt to decode link-layer header */
750
 	if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
746
 	if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
765
 	if ( net_proto )
761
 	if ( net_proto )
766
 		*net_proto = ntohs ( iob_net_proto );
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
  out_bad_ll_header:
767
  out_bad_ll_header:
771
 	free_iob ( iobuf );
768
 	free_iob ( iobuf );
772
- out_too_long:
773
  out_no_packet:
769
  out_no_packet:
774
 	return EFIRC ( rc );
770
 	return EFIRC ( rc );
775
 }
771
 }

Loading…
Cancel
Save