From 476c6db58d9081b076b7a8ee4a3e54836060d52b Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.de>
Date: Thu, 20 Dec 2012 12:55:18 +0100
Subject: [PATCH] Picked up obvious fixes (memleaks/segfaults) from 4.2.5rc1
References: bnc#794578
Upstream: in 4.2.5rc1

---
 client/dhc6.c       |   11 +++++++----
 common/alloc.c      |    8 ++++----
 common/execute.c    |    2 ++
 omapip/connection.c |   29 +++++++++++++++--------------
 omapip/dispatch.c   |   11 +++++++++--
 omapip/listener.c   |    9 ++++++++-
 omapip/protocol.c   |   21 ++++++++++++++-------
 omapip/trace.c      |   14 +++++++++-----
 server/db.c         |    3 +--
 server/ddns.c       |    7 ++++++-
 server/failover.c   |    6 +++++-
 11 Dateien geändert, 80 Zeilen hinzugefügt(+), 41 Zeilen entfernt(-)

diff --git a/client/dhc6.c b/client/dhc6.c
index 633f9b1..c04f373 100644
--- a/client/dhc6.c
+++ b/client/dhc6.c
@@ -213,8 +213,10 @@ dhcpv6_client_assignments(void)
 	memset(&DHCPv6DestAddr, 0, sizeof(DHCPv6DestAddr));
 	DHCPv6DestAddr.sin6_family = AF_INET6;
 	DHCPv6DestAddr.sin6_port = remote_port;
-	inet_pton(AF_INET6, All_DHCP_Relay_Agents_and_Servers,
-		  &DHCPv6DestAddr.sin6_addr);
+	if (inet_pton(AF_INET6, All_DHCP_Relay_Agents_and_Servers,
+		      &DHCPv6DestAddr.sin6_addr) <= 0) {
+		log_fatal("Bad address %s", All_DHCP_Relay_Agents_and_Servers);
+	}
 
 	code = D6O_CLIENTID;
 	if (!option_code_hash_lookup(&clientid_option,
@@ -655,7 +657,8 @@ dhc6_leaseify(struct packet *packet)
 	 * not sure based on what additional keys now).
 	 */
 	oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
-	if (!evaluate_option_cache(&lease->server_id, packet, NULL, NULL,
+	if ((oc == NULL) ||
+	    !evaluate_option_cache(&lease->server_id, packet, NULL, NULL,
 				   lease->options, NULL, &global_scope,
 				   oc, MDL) ||
 	    lease->server_id.len == 0) {
@@ -4023,7 +4026,7 @@ dhc6_check_times(struct client_state *client)
 				/* Set rebind to 3/4 expiration interval. */
 				tmp = ia->starts;
 				tmp += use_expire + (use_expire / 2);
-			} else if (ia->renew == 0xffffffff)
+			} else if (ia->rebind == 0xffffffff)
 				tmp = MAX_TIME;
 			else
 				tmp = ia->starts + ia->rebind;
diff --git a/common/alloc.c b/common/alloc.c
index f2ddc8a..ae97721 100644
--- a/common/alloc.c
+++ b/common/alloc.c
@@ -831,11 +831,11 @@ int dns_host_entry_dereference (ptr, file, line)
 #endif
 	}
 
-	(*ptr) -> refcnt--;
-	rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1, RC_MISC);
-	if (!(*ptr) -> refcnt)
+	(*ptr)->refcnt--;
+	rc_register (file, line, ptr, *ptr, (*ptr)->refcnt, 1, RC_MISC);
+	if ((*ptr)->refcnt == 0) {
 		dfree ((*ptr), file, line);
-	if ((*ptr) -> refcnt < 0) {
+	} else if ((*ptr)->refcnt < 0) {
 		log_error ("%s(%d): negative refcnt!", file, line);
 #if defined (DEBUG_RC_HISTORY)
 		dump_rc_history (*ptr);
diff --git a/common/execute.c b/common/execute.c
index 363ffa6..47be65b 100644
--- a/common/execute.c
+++ b/common/execute.c
@@ -327,6 +327,7 @@ int execute_statements (result, packet, lease, client_state,
 
 		      case set_statement:
 		      case define_statement:
+			status = 1;
 			if (!scope) {
 				log_error("set %s: no scope",
 					   r->data.set.name);
@@ -421,6 +422,7 @@ int execute_statements (result, packet, lease, client_state,
 			log_debug ("exec: let %s", r -> data.let.name);
 #endif
 			ns = (struct binding_scope *)0;
+			status = 0;
 			binding_scope_allocate (&ns, MDL);
 			e = r;
 
diff --git a/omapip/connection.c b/omapip/connection.c
index a919968..2027323 100644
--- a/omapip/connection.c
+++ b/omapip/connection.c
@@ -396,22 +396,23 @@ static void trace_connect_input (trace_type_t *ttype,
 	/* Find the matching connect object, if there is one. */
 	omapi_array_foreach_begin (omapi_connections,
 				   omapi_connection_object_t, lp) {
-	    for (i = 0; (lp -> connect_list &&
-			 i < lp -> connect_list -> count); i++) {
+	    for (i = 0; (lp->connect_list &&
+			 i < lp->connect_list->count); i++) {
 		    if (!memcmp (&remote.sin_addr,
-				 &lp -> connect_list -> addresses [i].address,
+				 &lp->connect_list->addresses[i].address,
 				 sizeof remote.sin_addr) &&
 			(ntohs (remote.sin_port) ==
-			 lp -> connect_list -> addresses [i].port))
-			lp -> state = omapi_connection_connected;
-			lp -> remote_addr = remote;
-			lp -> remote_addr.sin_family = AF_INET;
-			omapi_addr_list_dereference (&lp -> connect_list, MDL);
-			lp -> index = connect_index;
-			status = omapi_signal_in ((omapi_object_t *)lp,
-						  "connect");
-			omapi_connection_dereference (&lp, MDL);
-			return;
+			 lp->connect_list->addresses[i].port)) {
+			    lp->state = omapi_connection_connected;
+			    lp->remote_addr = remote;
+			    lp->remote_addr.sin_family = AF_INET;
+			    omapi_addr_list_dereference(&lp->connect_list, MDL);
+			    lp->index = connect_index;
+			    status = omapi_signal_in((omapi_object_t *)lp,
+						     "connect");
+			    omapi_connection_dereference (&lp, MDL);
+			    return;
+		    }
 		}
 	} omapi_array_foreach_end (omapi_connections,
 				   omapi_connection_object_t, lp);
@@ -628,7 +629,7 @@ isc_result_t omapi_connection_connect (omapi_object_t *h)
 
 static isc_result_t omapi_connection_connect_internal (omapi_object_t *h)
 {
-	int error;
+	int error = 0;
 	omapi_connection_object_t *c;
 	socklen_t sl;
 	isc_result_t status;
diff --git a/omapip/dispatch.c b/omapip/dispatch.c
index 4039659..e6aae45 100644
--- a/omapip/dispatch.c
+++ b/omapip/dispatch.c
@@ -171,8 +171,15 @@ omapi_iscsock_cb(isc_task_t   *task,
 	if ((flags == ISC_SOCKFDWATCH_READ) &&
 	    (obj->reader != NULL) &&
 	    (obj->inner != NULL)) {
-		obj->reader(obj->inner);
-		/* We always ask for more when reading */
+		status = obj->reader(obj->inner);
+		/* 
+		 * If we are shutting down (basically tried to
+		 * read and got no bytes) we don't need to try
+		 * again.
+		 */
+		if (status == ISC_R_SHUTTINGDOWN)
+			return (0);
+		/* Otherwise We always ask for more when reading */
 		return (1);
 	} else if ((flags == ISC_SOCKFDWATCH_WRITE) &&
 		 (obj->writer != NULL) &&
diff --git a/omapip/listener.c b/omapip/listener.c
index 30259eb..138b0f2 100644
--- a/omapip/listener.c
+++ b/omapip/listener.c
@@ -84,7 +84,14 @@ isc_result_t omapi_listen_addr (omapi_object_t *h,
 	obj = (omapi_listener_object_t *)0;
 	status = omapi_listener_allocate (&obj, MDL);
 	if (status != ISC_R_SUCCESS)
-		return status;
+		/*
+		 * we could simply return here but by going to
+		 * error_exit we keep the code check tools happy
+		 * without removing the NULL check on obj at
+		 * the exit, which we could skip curently but
+		 * might want in the future.
+		 */
+		goto error_exit;
 	obj->socket = -1;
 
 	/* Connect this object to the inner object. */
diff --git a/omapip/protocol.c b/omapip/protocol.c
index 9906489..112bf12 100644
--- a/omapip/protocol.c
+++ b/omapip/protocol.c
@@ -354,7 +354,7 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
 	omapi_protocol_object_t *p;
 	omapi_object_t *c;
 	omapi_message_object_t *m;
-	omapi_value_t *signature;
+	omapi_value_t *signature = NULL;
 	u_int16_t nlen;
 	u_int32_t vlen;
 	u_int32_t th;
@@ -680,7 +680,6 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
 	      case omapi_protocol_signature_wait:
 		if (p -> message -> id_object) {
 			/* Compute the signature of the message. */
-			signature = (omapi_value_t *)0;
 			status = omapi_get_value_str (c, (omapi_object_t *)0,
 						      "input-signature",
 						      &signature);
@@ -707,7 +706,9 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
 					       p -> message -> authlen);
 			
 		if (status != ISC_R_SUCCESS) {
-			omapi_value_dereference (&signature, MDL);
+			if (signature != NULL) {
+				omapi_value_dereference (&signature, MDL);
+			}
 			omapi_disconnect (c, 1);
 			return ISC_R_NOMEMORY;
 		}
@@ -726,7 +727,9 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
 			p->verify_result = DHCP_R_INVALIDKEY;
 		}
 
-		omapi_value_dereference (&signature, MDL);
+		if (signature != NULL) {
+			omapi_value_dereference (&signature, MDL);
+		}
 
 		/* Process the message. */
 	      message_done:
@@ -860,10 +863,10 @@ isc_result_t omapi_protocol_set_value (omapi_object_t *h,
 	p = (omapi_protocol_object_t *)h;
 
 	if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
-		if (value -> type != omapi_datatype_object)
+		if (!value || value -> type != omapi_datatype_object)
 			return DHCP_R_INVALIDARG;
 
-		if (!value || !value -> u.object) {
+		if (!value -> u.object) {
 			p -> default_auth = (omapi_remote_auth_t *)0;
 		} else {
 			for (r = p -> remote_auth_list; r; r = r -> next)
@@ -987,7 +990,11 @@ isc_result_t omapi_protocol_configure_security (omapi_object_t *h,
 	l -> verify_auth = verify_auth;
 	l -> insecure = 0;
 
-	return omapi_listener_configure_security (h -> outer, verify_addr);
+	if (h -> outer != NULL) {
+		return omapi_listener_configure_security (h -> outer, verify_addr);
+	} else {
+		return DHCP_R_INVALIDARG;
+	}
 }
 					      
 
diff --git a/omapip/trace.c b/omapip/trace.c
index 9c4e11e..96bf19a 100644
--- a/omapip/trace.c
+++ b/omapip/trace.c
@@ -235,6 +235,7 @@ isc_result_t trace_write_packet_iov (trace_type_t *ttype,
 
 	/* We have to swap out the data, because it may be read back on a
 	   machine of different endianness. */
+	memset(&tmp, 0, sizeof(tmp));
 	tmp.type_index = htonl (ttype -> index);
 	tmp.when = htonl (time ((time_t *)0)); /* XXX */
 	tmp.length = htonl (length);
@@ -690,27 +691,30 @@ isc_result_t trace_get_file (trace_type_t *ttype,
 	}
 
 	result = trace_get_next_packet (&ttype, tpkt, buf, len, &max);
+	/* done with tpkt, free it */
+	dfree (tpkt, MDL);
 	if (result != ISC_R_SUCCESS) {
-		dfree (tpkt, MDL);
-		if (*buf)
+		if (*buf) {
 			dfree (*buf, MDL);
+			*buf = NULL;
+		}
 		return result;
 	}
 
 	/* Make sure the filename is right. */
 	if (strcmp (filename, *buf)) {
 		log_error ("Read file %s when expecting %s", *buf, filename);
+		dfree (*buf, MDL);
+		*buf = NULL;
+
 		status = fsetpos (traceinfile, &curpos);
 		if (status < 0) {
 			log_error ("fsetpos in tracefile failed: %m");
-			dfree (tpkt, MDL);
-			dfree (*buf, MDL);
 			return DHCP_R_PROTOCOLERROR;
 		}
 		return ISC_R_UNEXPECTEDTOKEN;
 	}
 
-	dfree (tpkt, MDL);
 	return ISC_R_SUCCESS;
 }
 #endif /* TRACING */
diff --git a/server/db.c b/server/db.c
index ed031dc..c9e0b86 100644
--- a/server/db.c
+++ b/server/db.c
@@ -66,10 +66,9 @@ write_binding_scope(FILE *db_file, struct binding *bnd, char *prepend) {
 				errno = 0;
 				fprintf(db_file, "%sset %s = \"%s\";",
 					prepend, bnd->name, s);
+				dfree(s, MDL);
 				if (errno)
 					return ISC_R_FAILURE;
-
-				dfree(s, MDL);
 			} else {
 			    return ISC_R_FAILURE;
 			}
diff --git a/server/ddns.c b/server/ddns.c
index 0c93073..9af6f94 100644
--- a/server/ddns.c
+++ b/server/ddns.c
@@ -1092,7 +1092,12 @@ ddns_update_lease_ptr(struct lease    *lease,
 {
 	char ddns_address[MAX_ADDRESS_STRING_LEN];
 	sprintf(ddns_address, "unknown");
-	if (ddns_cb) {
+	if (ddns_cb == NULL) {
+		log_info("%s(%d): No control block for lease update",
+			 file, line);
+		return (ISC_R_FAILURE);
+	}
+	else {
 		strncpy(ddns_address, piaddr(ddns_cb->address), 
 			MAX_ADDRESS_STRING_LEN);
 	}
diff --git a/server/failover.c b/server/failover.c
index 45e6b62..5a6d37f 100644
--- a/server/failover.c
+++ b/server/failover.c
@@ -4452,7 +4452,9 @@ isc_result_t dhcp_failover_send_connectack (omapi_object_t *l,
 	       ? dhcp_failover_make_option(FTO_RELATIONSHIP_NAME, FMA,
 					   strlen(state->name), state->name)
 	       : (link->imsg->options_present & FTB_RELATIONSHIP_NAME)
-		  ? &link->imsg->relationship_name
+		  ? dhcp_failover_make_option(FTO_RELATIONSHIP_NAME, FMA,
+					      link->imsg->relationship_name.count,
+					      link->imsg->relationship_name.data)
 		  : &skip_failover_option,
 	      state
 	       ? dhcp_failover_make_option (FTO_MAX_UNACKED, FMA,
@@ -6333,6 +6335,8 @@ static isc_result_t failover_message_dereference (failover_message_t **mp,
 			dfree (m -> hba.data, file, line);
 		if (m -> message.data)
 			dfree (m -> message.data, file, line);
+		if (m -> relationship_name.data)
+			dfree (m -> relationship_name.data, file, line);
 		if (m -> reply_options.data)
 			dfree (m -> reply_options.data, file, line);
 		if (m -> request_options.data)
-- 
1.7.10.4

