]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[arp] Validate length of ARP packet
authorMichael Brown <mcb30@ipxe.org>
Sat, 12 Mar 2016 01:21:18 +0000 (01:21 +0000)
committerMichael Brown <mcb30@ipxe.org>
Sat, 12 Mar 2016 01:24:03 +0000 (01:24 +0000)
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 <mcb30@ipxe.org>
src/include/ipxe/if_arp.h
src/net/arp.c

index 4eb1f80b78eca04a2faec3baa905a0c6c8a625b8..9d7b03fe8c6583e6818c1036c54056b839a05545 100644 (file)
@@ -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 */
index 1e27c44e739309446c0ddb9748cf189dfe1bf9d8..c9b4109a978a6777ea6495b24b1a23e38eb9e61d 100644 (file)
@@ -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 ) {