6370597 in.dhcpd core dumps. Double free on a DHCP network container record
authorBrian Utterback <Brian.Utterback@Sun.COM>
Mon, 19 Jul 2010 18:52:59 -0700
changeset 12876 78ceb0079fba
parent 12875 5783b6fe7ed5
child 12877 08987220809a
6370597 in.dhcpd core dumps. Double free on a DHCP network container record 6959836 dhcp server should set file limit even in debug mode.
usr/src/cmd/cmd-inet/usr.lib/in.dhcpd/bootp.c
usr/src/cmd/cmd-inet/usr.lib/in.dhcpd/dhcp.c
usr/src/cmd/cmd-inet/usr.lib/in.dhcpd/dhcpd.h
usr/src/cmd/cmd-inet/usr.lib/in.dhcpd/main.c
--- a/usr/src/cmd/cmd-inet/usr.lib/in.dhcpd/bootp.c	Mon Jul 19 14:09:27 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.lib/in.dhcpd/bootp.c	Mon Jul 19 18:52:59 2010 -0700
@@ -19,10 +19,8 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
  */
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -389,7 +387,7 @@
 			/* Note that the conversation has completed. */
 			pcd->state = ACK;
 
-			(void) update_offer(pcd, dnlp, 0, &no_ip, B_TRUE);
+			(void) update_offer(pcd, &dnlp, 0, &no_ip, B_TRUE);
 			existing_offer = B_TRUE;
 		}
 
--- a/usr/src/cmd/cmd-inet/usr.lib/in.dhcpd/dhcp.c	Mon Jul 19 14:09:27 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.lib/in.dhcpd/dhcp.c	Mon Jul 19 18:52:59 2010 -0700
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <stdio.h>
@@ -534,7 +533,7 @@
 			newlease = htonl(newlease);
 		else
 			newlease = htonl(now + newlease);
-		(void) update_offer(pcd, dnlp, newlease, NULL, B_TRUE);
+		(void) update_offer(pcd, &dnlp, newlease, NULL, B_TRUE);
 		existing_offer = B_TRUE;
 	} else {
 		unreserve = B_TRUE;
@@ -1880,15 +1879,15 @@
  * the interface we received the last DISCOVER on.
  *
  * pcd - per client data struct.
- * dnlp - pointer to current container entry. Performance: caching reduces
- * datastore activity, structure copying.
+ * dnlp - pointer to pointer to current container entry. Performance: caching
+ * reduces datastore activity, structure copying.
  * nlease - new lease time.
  * reservep - new offer address (expected in network order).
  * purge_cache - Multithreading: avoid redundant cache purging in
  * select_offer().
  */
 boolean_t
-update_offer(dsvc_clnt_t *pcd, dn_rec_list_t *dnlp, lease_t nlease,
+update_offer(dsvc_clnt_t *pcd, dn_rec_list_t **dnlp, lease_t nlease,
 	struct in_addr *reservep, boolean_t purge_cache)
 {
 	char		ntoab[INET_ADDRSTRLEN];
@@ -1901,10 +1900,10 @@
 	struct in_addr	off_ip;
 
 	/* Save the original datastore record. */
-	if (dnlp != NULL) {
-		if (pcd->dnlp != NULL && pcd->dnlp != dnlp)
+	if (dnlp != NULL && *dnlp != NULL) {
+		if (pcd->dnlp != NULL && pcd->dnlp != *dnlp)
 			dhcp_free_dd_list(pnd->dh, pcd->dnlp);
-		pcd->dnlp = dnlp;
+		pcd->dnlp = *dnlp;
 	}
 	if (pcd->dnlp != NULL)
 		dnp = pcd->dnlp->dnl_rec;
@@ -1954,6 +1953,10 @@
 			}
 			pcd->off_ip.s_addr = htonl(INADDR_ANY);
 			dhcp_free_dd_list(pnd->dh, pcd->dnlp);
+			if (dnlp != NULL && *dnlp != NULL &&
+			    pcd->dnlp == *dnlp) {
+				*dnlp = NULL;
+			}
 			pcd->dnlp = NULL;
 			return (B_FALSE);
 		}
--- a/usr/src/cmd/cmd-inet/usr.lib/in.dhcpd/dhcpd.h	Mon Jul 19 14:09:27 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.lib/in.dhcpd/dhcpd.h	Mon Jul 19 18:52:59 2010 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,15 +19,12 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef	_DHCPD_H
 #define	_DHCPD_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -203,7 +199,7 @@
 extern void	*monitor_client(void *);
 
 extern void	dhcp(dsvc_clnt_t *, PKT_LIST *);
-boolean_t	update_offer(dsvc_clnt_t *, dn_rec_list_t *, lease_t,
+boolean_t	update_offer(dsvc_clnt_t *, dn_rec_list_t **, lease_t,
 		    struct in_addr *, boolean_t);
 extern void	bootp(dsvc_clnt_t *, PKT_LIST *);
 extern void	get_netmask(struct in_addr *, struct in_addr *);
--- a/usr/src/cmd/cmd-inet/usr.lib/in.dhcpd/main.c	Mon Jul 19 14:09:27 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.lib/in.dhcpd/main.c	Mon Jul 19 18:52:59 2010 -0700
@@ -19,12 +19,9 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * This file contains the argument parsing routines of the dhcpd daemon.
  * It corresponds to the START state as spec'ed.
@@ -430,23 +427,24 @@
 		(void) dup2(0, 1);
 		(void) dup2(0, 2);
 
-		/* set NOFILE to unlimited */
-		rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
-		if ((err = setrlimit(RLIMIT_NOFILE, &rl)) < 0) {
-			dhcpmsg(LOG_ERR, "Cannot set open file limit: %s\n",
-			    strerror(errno));
-			return (err);
-		}
-		(void) enable_extended_FILE_stdio(-1, -1);
-
 		/* Detach console */
 		(void) setsid();
 
 		(void) openlog(DHCPD, LOG_PID, LOG_DAEMON);
-		if (verbose)
-			dhcpmsg(LOG_INFO, "Daemon started.\n");
 	}
 
+	/* set NOFILE to unlimited */
+	rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
+	if ((err = setrlimit(RLIMIT_NOFILE, &rl)) < 0) {
+		dhcpmsg(LOG_ERR, "Cannot set open file limit: %s\n",
+		    strerror(errno));
+		return (err);
+	}
+	(void) enable_extended_FILE_stdio(-1, -1);
+
+	if (verbose)
+		dhcpmsg(LOG_INFO, "Daemon started.\n");
+
 	/*
 	 * Block all signals in main thread - threads created will also
 	 * ignore signals.