Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[dhcp] Check for matching chaddr in received DHCP packets
On large networks a DHCP XID collision is possible.  Fix by explicitly
checking the chaddr in received DHCP packets.

Originally-fixed-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Sep 22, 2014
1 parent 5d9fbf3 commit 08bcc0f
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/net/udp/dhcp.c
Expand Up @@ -130,6 +130,29 @@ static inline const char * dhcp_msgtype_name ( unsigned int msgtype ) {
}
}

/**
* Transcribe DHCP client hardware address (for debugging)
*
* @v chaddr Client hardware address
* @v hlen Client hardware address length
*/
static const char * dhcp_chaddr_ntoa ( const void *chaddr, size_t hlen ) {
static char buf[ 48 /* 16 x ( "xx" + ":" or NUL ) */ ];
const uint8_t *chaddr_bytes = chaddr;
char *tmp = buf;

/* Sanity check */
assert ( hlen < ( sizeof ( buf ) / 3 ) );

/* Transcribe address */
while ( hlen-- ) {
tmp += sprintf ( tmp, "%s%02x", ( ( tmp == buf ) ? "" : ":" ),
*(chaddr_bytes++) );
}

return buf;
}

/****************************************************************************
*
* DHCP session
Expand Down Expand Up @@ -1159,6 +1182,8 @@ static int dhcp_deliver ( struct dhcp_session *dhcp,
struct dhcphdr *dhcphdr;
uint8_t msgtype = 0;
struct in_addr server_id = { 0 };
uint8_t chaddr[ sizeof ( dhcphdr->chaddr ) ];
unsigned int hlen;
int rc = 0;

/* Sanity checks */
Expand Down Expand Up @@ -1203,9 +1228,21 @@ static int dhcp_deliver ( struct dhcp_session *dhcp,
goto err_xid;
};

/* Check for matching client hardware address */
hlen = dhcp_chaddr ( dhcp->netdev, chaddr, NULL );
if ( memcmp ( dhcphdr->chaddr, chaddr, hlen ) != 0 ) {
DBGC ( dhcp, "DHCP %p %s from %s:%d has bad chaddr %s\n",
dhcp, dhcp_msgtype_name ( msgtype ),
inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ),
dhcp_chaddr_ntoa ( dhcphdr->chaddr, hlen ) );
rc = -EINVAL;
goto err_chaddr;
}

/* Handle packet based on current state */
dhcp->state->rx ( dhcp, dhcppkt, peer, msgtype, server_id );

err_chaddr:
err_xid:
dhcppkt_put ( dhcppkt );
err_alloc_dhcppkt:
Expand Down

0 comments on commit 08bcc0f

Please sign in to comment.