|  | @@ -710,6 +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 | 714 |  	int rc;
 | 
		
	
		
			
			| 714 | 715 |  
 | 
		
	
		
			
			| 715 | 716 |  	DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
 | 
		
	
	
		
			
			|  | @@ -722,19 +723,28 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
 | 
		
	
		
			
			| 722 | 723 |  	/* Poll the network device */
 | 
		
	
		
			
			| 723 | 724 |  	efi_snp_poll ( snpdev );
 | 
		
	
		
			
			| 724 | 725 |  
 | 
		
	
		
			
			| 725 |  | -	/* Dequeue a packet, if one is available */
 | 
		
	
		
			
			|  | 726 | +	/* Check for an available packet */
 | 
		
	
		
			
			| 726 | 727 |  	iobuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
 | 
		
	
		
			
			| 727 | 728 |  	if ( ! iobuf ) {
 | 
		
	
		
			
			| 728 | 729 |  		DBGC2 ( snpdev, "\n" );
 | 
		
	
		
			
			| 729 | 730 |  		rc = -EAGAIN;
 | 
		
	
		
			
			| 730 | 731 |  		goto out_no_packet;
 | 
		
	
		
			
			| 731 | 732 |  	}
 | 
		
	
		
			
			| 732 |  | -	list_del ( &iobuf->list );
 | 
		
	
		
			
			| 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 | +	/* Dequeue packet */
 | 
		
	
		
			
			|  | 744 | +	list_del ( &iobuf->list );
 | 
		
	
		
			
			|  | 745 | +
 | 
		
	
		
			
			| 735 | 746 |  	/* Return packet to caller */
 | 
		
	
		
			
			| 736 | 747 |  	memcpy ( data, iobuf->data, iob_len ( iobuf ) );
 | 
		
	
		
			
			| 737 |  | -	*len = iob_len ( iobuf );
 | 
		
	
		
			
			| 738 | 748 |  
 | 
		
	
		
			
			| 739 | 749 |  	/* Attempt to decode link-layer header */
 | 
		
	
		
			
			| 740 | 750 |  	if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
 | 
		
	
	
		
			
			|  | @@ -759,6 +769,7 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
 | 
		
	
		
			
			| 759 | 769 |  
 | 
		
	
		
			
			| 760 | 770 |   out_bad_ll_header:
 | 
		
	
		
			
			| 761 | 771 |  	free_iob ( iobuf );
 | 
		
	
		
			
			|  | 772 | + out_too_long:
 | 
		
	
		
			
			| 762 | 773 |   out_no_packet:
 | 
		
	
		
			
			| 763 | 774 |  	return EFIRC ( rc );
 | 
		
	
		
			
			| 764 | 775 |  }
 |