Commits

Anonymous committed a8cd212

Unrevert last reversion. otto@ pointed out that it wasn't asprintf()
causing a problem, it was accessing uninitialized pointers.

Comments (0)

Files changed (3)

sbin/dhclient/dhclient.c

-/*	$OpenBSD: dhclient.c,v 1.209 2013/01/16 11:02:09 krw Exp $	*/
+/*	$OpenBSD: dhclient.c,v 1.210 2013/01/16 21:35:41 krw Exp $	*/
 
 /*
  * Copyright 2004 Henning Brauer <henning@openbsd.org>
 	char msg[2048];
 	struct in_addr a, b;
 	ssize_t n;
-	int linkstat;
+	int linkstat, rslt;
 	struct rt_msghdr *rtm;
 	struct if_msghdr *ifm;
 	struct ifa_msghdr *ifam;
 		sa = get_ifa((char *)ifam + ifam->ifam_hdrlen,
 		    ifam->ifam_addrs);
 		if (sa == NULL) {
-			errmsg = "sa == NULL";
+			rslt = asprintf(&errmsg, "%s sa == NULL", ifi->name);
 			goto die;
 		}
 
 				go_daemon();
 				break;
 			}
-			errmsg = "interface address added";
+			if (adding.s_addr != INADDR_ANY)
+				rslt = asprintf(&errmsg, "%s, not %s, added "
+				    "to %s", inet_ntoa(a), inet_ntoa(adding),
+				    ifi->name);
+			else
+				rslt = asprintf(&errmsg, "%s added to %s",
+				    inet_ntoa(a), ifi->name);
 		} else {
 			if (a.s_addr == deleting.s_addr) {
 				deleting.s_addr = INADDR_ANY;
 				add_address(ifi->name, 0, b, b);
 				break;
 			}
-			errmsg = "interface address deleted";
+			if (deleting.s_addr != INADDR_ANY)
+				rslt = asprintf(&errmsg, "%s, not %s, deleted "
+				    "from %s", inet_ntoa(a),
+				    inet_ntoa(deleting), ifi->name);
+			else
+				rslt = asprintf(&errmsg, "%s deleted from %s",
+				    inet_ntoa(a), ifi->name);
 		} 
 		goto die;
 	case RTM_IFINFO:
 		if (ifm->ifm_index != ifi->index)
 			break;
 		if ((rtm->rtm_flags & RTF_UP) == 0) {
-			errmsg = "interface down";
+			rslt = asprintf(&errmsg, "%s down", ifi->name);
 			goto die;
 		}
 
 		ifan = (struct if_announcemsghdr *)rtm;
 		if (ifan->ifan_what == IFAN_DEPARTURE &&
 		    ifan->ifan_index == ifi->index) {
-			errmsg = "interface departure";
+			rslt = asprintf(&errmsg, "%s departured", ifi->name);
 			goto die;
 		}
 		break;
 	return;
 
 die:
+	if (rslt == -1)
+		error("no memory for errmsg");
 	error("routehandler: %s", errmsg);
+	free(errmsg);
 }
 
 char **saved_argv;
 }
 
 void
-dhcpack(struct in_addr client_addr, struct option_data *options)
+dhcpack(struct in_addr client_addr, struct option_data *options, char *info)
 {
 	struct client_lease *lease;
 	time_t cur_time;
 	if (client->state != S_REBOOTING &&
 	    client->state != S_REQUESTING &&
 	    client->state != S_RENEWING &&
-	    client->state != S_REBINDING)
+	    client->state != S_REBINDING) {
+		note("Unexpected %s. State #%d", info, client->state);
 		return;
+	}
 
 	lease = packet_to_lease(client_addr, options);
 	if (!lease) {
-		note("DHCPACK isn't satisfactory.");
+		note("Unsatisfactory %s", info);
 		return;
 	}
 
+	note("%s", info);
+
 	client->new = lease;
 
 	/* Stop resending DHCPREQUEST. */
 }
 
 void
-dhcpoffer(struct in_addr client_addr, struct option_data *options)
+dhcpoffer(struct in_addr client_addr, struct option_data *options, char *info)
 {
 	struct client_lease *lease, *lp;
 	time_t stop_selecting;
-	char *name = options[DHO_DHCP_MESSAGE_TYPE].len ? "DHCPOFFER" :
-	    "BOOTREPLY";
-
-	if (client->state != S_SELECTING)
-		return;
 
-	lease = packet_to_lease(client_addr, options);
-	if (!lease) {
-		note("%s isn't satisfactory.", name);
+	if (client->state != S_SELECTING) {
+		note("Unexpected %s. State #%d.", info, client->state);
 		return;
 	}
 
 		if (!memcmp(&lp->address.s_addr, &client->packet.yiaddr,
 		    sizeof(in_addr_t))) {
 #ifdef DEBUG
-			debug("%s already seen.", name);
+			debug("Duplicate %s.", info);
 #endif
-			free_client_lease(lease);
 			return;
 		}
 	}
 
+	lease = packet_to_lease(client_addr, options);
+	if (!lease) {
+		note("Unsatisfactory %s", info);
+		return;
+	}
+
 	/*
 	 * Reject offers whose subnet is already configured on another
 	 * interface.
 		}
 	}
 
+	note("%s", info);
+
 	/* If the selecting interval has expired, go immediately to
 	   state_selecting().  Otherwise, time out into
 	   state_selecting at the select interval. */
 }
 
 void
-dhcpnak(struct in_addr client_addr, struct option_data *options)
+dhcpnak(struct in_addr client_addr, struct option_data *options, char *info)
 {
 	if (client->state != S_REBOOTING &&
 	    client->state != S_REQUESTING &&
 	    client->state != S_RENEWING &&
-	    client->state != S_REBINDING)
+	    client->state != S_REBINDING) {
+		note("Unexpected %s. State #%d", info, client->state);
 		return;
+	}
 
 	if (!client->active) {
-		note("DHCPNAK with no active lease.");
+		note("Unexpected %s. No active lease.", info);
 		return;
 	}
 
+	note("%s", info);
+
 	free_client_lease(client->active);
 	client->active = NULL;
 

sbin/dhclient/dhcpd.h

-/*	$OpenBSD: dhcpd.h,v 1.101 2013/01/16 11:02:09 krw Exp $	*/
+/*	$OpenBSD: dhcpd.h,v 1.102 2013/01/16 21:35:41 krw Exp $	*/
 
 /*
  * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
 extern int log_perror;
 extern int routefd;
 
-void dhcpoffer(struct in_addr, struct option_data *);
-void dhcpack(struct in_addr, struct option_data *);
-void dhcpnak(struct in_addr, struct option_data *);
+void dhcpoffer(struct in_addr, struct option_data *, char *);
+void dhcpack(struct in_addr, struct option_data *, char *);
+void dhcpnak(struct in_addr, struct option_data *, char *);
 
 void send_discover(void);
 void send_request(void);

sbin/dhclient/options.c

-/*	$OpenBSD: options.c,v 1.49 2013/01/16 11:02:10 krw Exp $	*/
+/*	$OpenBSD: options.c,v 1.50 2013/01/16 21:35:41 krw Exp $	*/
 
 /* DHCP options parsing and reassembly. */
 
 	struct dhcp_packet *packet = &client->packet;
 	struct option_data options[256];
 	struct reject_elem *ap;
-	void (*handler)(struct in_addr, struct option_data *);
-	char *type;
-	int i, options_valid = 1;
+	void (*handler)(struct in_addr, struct option_data *, char *);
+	char *type, *info;
+	int i, rslt, options_valid = 1;
 
 	if (packet->hlen > sizeof(packet->chaddr)) {
 		note("Discarding packet with invalid hlen.");
 		}
 	}
 
-	type = "";
+	type = "<unknown>";
 	handler = NULL;
 
 	if (options[DHO_DHCP_MESSAGE_TYPE].data) {
 		type = "BOOTREPLY";
 	}
 
-	if (handler && client->xid == client->packet.xid) {
-		if (hfrom->hlen == 6)
-			note("%s from %s (%s)", type, inet_ntoa(from),
-			    ether_ntoa((struct ether_addr *)hfrom->haddr));
-		else
-			note("%s from %s", type, inet_ntoa(from));
-	} else
+	if (hfrom->hlen == 6)
+		rslt = asprintf(&info, "%s from %s (%s)", type, inet_ntoa(from),
+		    ether_ntoa((struct ether_addr *)hfrom->haddr));
+	else
+		rslt = asprintf(&info, "%s from %s", type, inet_ntoa(from));
+	if (rslt == -1)
+		error("no memory for info string");
+
+	if (client->xid != client->packet.xid) {
+#ifdef DEBUG
+		debug("XID mismatch on %s", info);
+#endif
 		handler = NULL;
+	}
 
 	for (ap = config->reject_list; ap && handler; ap = ap->next)
 		if (from.s_addr == ap->addr.s_addr) {
-			note("%s from %s rejected.", type, inet_ntoa(from));
+			note("Rejected %s.", info);
 			handler = NULL;
 		}
 
 	if (handler)
-		(*handler)(from, options);
+		(*handler)(from, options, info);
+
+	free(info);
 
 	for (i = 0; i < 256; i++)
 		if (options[i].len && options[i].data)