From 64acfd9ddd73bf38802f8c57e054d13a57b14198 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sat, 12 Mar 2016 01:21:18 +0000 Subject: [PATCH] [arp] Validate length of ARP packet There is no practical way to generate an underlength ARP packet since an ARP packet is always padded up to the minimum Ethernet frame length (or dropped by the receiving Ethernet hardware if incorrectly padded), but the absence of an explicit check causes warnings from some analysis tools. Fix by adding an explicit check on the I/O buffer length. Signed-off-by: Michael Brown --- src/include/ipxe/if_arp.h | 10 ++++++++++ src/net/arp.c | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/src/include/ipxe/if_arp.h b/src/include/ipxe/if_arp.h index 4eb1f80b..9d7b03fe 100644 --- a/src/include/ipxe/if_arp.h +++ b/src/include/ipxe/if_arp.h @@ -99,4 +99,14 @@ static inline void * arp_target_pa ( struct arphdr *arphdr ) { return ( arp_target_ha ( arphdr ) + arphdr->ar_hln ); } +/** ARP packet length + * + * @v arphdr ARP header + * @ret len Length (including header) + */ +static inline size_t arp_len ( struct arphdr *arphdr ) { + return ( sizeof ( *arphdr ) + + ( 2 * ( arphdr->ar_hln + arphdr->ar_pln ) ) ); +} + #endif /* _IPXE_IF_ARP_H */ diff --git a/src/net/arp.c b/src/net/arp.c index 1e27c44e..c9b4109a 100644 --- a/src/net/arp.c +++ b/src/net/arp.c @@ -139,8 +139,15 @@ static int arp_rx ( struct io_buffer *iobuf, struct net_device *netdev, struct arp_net_protocol *arp_net_protocol; struct net_protocol *net_protocol; struct ll_protocol *ll_protocol; + size_t len = iob_len ( iobuf ); int rc; + /* Sanity check */ + if ( ( len < sizeof ( *arphdr ) ) || ( len < arp_len ( arphdr ) ) ) { + rc = -EINVAL; + goto done; + } + /* Identify network-layer and link-layer protocols */ arp_net_protocol = arp_find_protocol ( arphdr->ar_pro ); if ( ! arp_net_protocol ) {