udhcpd: fix a bug in add_lease where it was reading at [-1]

It is not correct when we read lease file!

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2009-07-07 14:59:30 +02:00
parent a51543a3a4
commit 95cc814dbd
4 changed files with 35 additions and 21 deletions

View File

@ -89,7 +89,7 @@ struct dyn_lease {
* (dhcp packet has chaddr[16], not [6]) * (dhcp packet has chaddr[16], not [6])
*/ */
uint8_t lease_mac[6]; uint8_t lease_mac[6];
uint8_t hostname[20]; char hostname[20];
uint8_t pad[2]; uint8_t pad[2];
/* total size is a multiply of 4 */ /* total size is a multiply of 4 */
} PACKED; } PACKED;
@ -98,7 +98,8 @@ extern struct dyn_lease *g_leases;
struct dyn_lease *add_lease( struct dyn_lease *add_lease(
const uint8_t *chaddr, uint32_t yiaddr, const uint8_t *chaddr, uint32_t yiaddr,
leasetime_t leasetime, uint8_t *hostname leasetime_t leasetime,
const char *hostname, int hostname_len
) FAST_FUNC; ) FAST_FUNC;
int is_expired_lease(struct dyn_lease *lease) FAST_FUNC; int is_expired_lease(struct dyn_lease *lease) FAST_FUNC;
struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC; struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC;

View File

@ -420,7 +420,11 @@ void FAST_FUNC read_leases(const char *file)
continue; continue;
/* NB: add_lease takes "relative time", IOW, /* NB: add_lease takes "relative time", IOW,
* lease duration, not lease deadline. */ * lease duration, not lease deadline. */
if (!(add_lease(lease.lease_mac, lease.lease_nip, expires, lease.hostname))) { if (add_lease(lease.lease_mac, lease.lease_nip,
expires,
lease.hostname, sizeof(lease.hostname)
) == 0
) {
bb_error_msg("too many leases while loading %s", file); bb_error_msg("too many leases while loading %s", file);
break; break;
} }

View File

@ -50,10 +50,10 @@ static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr)
/* Add a lease into the table, clearing out any old ones */ /* Add a lease into the table, clearing out any old ones */
struct dyn_lease* FAST_FUNC add_lease( struct dyn_lease* FAST_FUNC add_lease(
const uint8_t *chaddr, uint32_t yiaddr, const uint8_t *chaddr, uint32_t yiaddr,
leasetime_t leasetime, uint8_t *hostname) leasetime_t leasetime,
const char *hostname, int hostname_len)
{ {
struct dyn_lease *oldest; struct dyn_lease *oldest;
uint8_t hostname_length;
/* clean out any old ones */ /* clean out any old ones */
clear_lease(chaddr, yiaddr); clear_lease(chaddr, yiaddr);
@ -63,16 +63,15 @@ struct dyn_lease* FAST_FUNC add_lease(
if (oldest) { if (oldest) {
oldest->hostname[0] = '\0'; oldest->hostname[0] = '\0';
if (hostname) { if (hostname) {
/* option size byte, + 1 for NUL */ char *p;
hostname_length = hostname[-1] + 1; if (hostname_len > sizeof(oldest->hostname))
if (hostname_length > sizeof(oldest->hostname)) hostname_len = sizeof(oldest->hostname);
hostname_length = sizeof(oldest->hostname); p = safe_strncpy(oldest->hostname, hostname, hostname_len);
hostname = (uint8_t*) safe_strncpy((char*)oldest->hostname, (char*)hostname, hostname_length);
/* sanitization (s/non-ASCII/^/g) */ /* sanitization (s/non-ASCII/^/g) */
while (*hostname) { while (*p) {
if (*hostname < ' ' || *hostname > 126) if (*p < ' ' || *p > 126)
*hostname = '^'; *p = '^';
hostname++; p++;
} }
} }
memcpy(oldest->lease_mac, chaddr, 6); memcpy(oldest->lease_mac, chaddr, 6);
@ -137,7 +136,7 @@ static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac)
temp.s_addr = nip; temp.s_addr = nip;
bb_info_msg("%s belongs to someone, reserving it for %u seconds", bb_info_msg("%s belongs to someone, reserving it for %u seconds",
inet_ntoa(temp), (unsigned)server_config.conflict_time); inet_ntoa(temp), (unsigned)server_config.conflict_time);
add_lease(blank_chaddr, nip, server_config.conflict_time, NULL); add_lease(blank_chaddr, nip, server_config.conflict_time, NULL, 0);
return 0; return 0;
} }

View File

@ -130,7 +130,8 @@ int FAST_FUNC send_offer(struct dhcp_packet *oldpacket)
uint32_t req_nip; uint32_t req_nip;
uint32_t lease_time_sec = server_config.max_lease_sec; uint32_t lease_time_sec = server_config.max_lease_sec;
uint32_t static_lease_ip; uint32_t static_lease_ip;
uint8_t *req_ip_opt, *p_host_name; uint8_t *req_ip_opt;
const char *p_host_name;
struct option_set *curr; struct option_set *curr;
struct in_addr addr; struct in_addr addr;
@ -173,8 +174,13 @@ int FAST_FUNC send_offer(struct dhcp_packet *oldpacket)
bb_error_msg("no IP addresses to give - OFFER abandoned"); bb_error_msg("no IP addresses to give - OFFER abandoned");
return -1; return -1;
} }
p_host_name = get_option(oldpacket, DHCP_HOST_NAME); p_host_name = (const char*) get_option(oldpacket, DHCP_HOST_NAME);
if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time, p_host_name)) { if (add_lease(packet.chaddr, packet.yiaddr,
server_config.offer_time,
p_host_name,
p_host_name ? (unsigned char)p_host_name[OPT_LEN - OPT_DATA] : 0
) == 0
) {
bb_error_msg("lease pool is full - OFFER abandoned"); bb_error_msg("lease pool is full - OFFER abandoned");
return -1; return -1;
} }
@ -218,7 +224,7 @@ int FAST_FUNC send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr)
struct option_set *curr; struct option_set *curr;
uint32_t lease_time_sec; uint32_t lease_time_sec;
struct in_addr addr; struct in_addr addr;
uint8_t *p_host_name; const char *p_host_name;
init_packet(&packet, oldpacket, DHCPACK); init_packet(&packet, oldpacket, DHCPACK);
packet.yiaddr = yiaddr; packet.yiaddr = yiaddr;
@ -242,8 +248,12 @@ int FAST_FUNC send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr)
if (send_packet(&packet, 0) < 0) if (send_packet(&packet, 0) < 0)
return -1; return -1;
p_host_name = get_option(oldpacket, DHCP_HOST_NAME); p_host_name = (const char*) get_option(oldpacket, DHCP_HOST_NAME);
add_lease(packet.chaddr, packet.yiaddr, lease_time_sec, p_host_name); add_lease(packet.chaddr, packet.yiaddr,
lease_time_sec,
p_host_name,
p_host_name ? (unsigned char)p_host_name[OPT_LEN - OPT_DATA] : 0
);
if (ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY) { if (ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY) {
/* rewrite the file with leases at every new acceptance */ /* rewrite the file with leases at every new acceptance */
write_leases(); write_leases();