CVE-2017-9732: Uncontrolled Resource Consumption (CWE-400)
value: The read_packet function in knc (Kerberised NetCat) before 1.11-1 is vulnerable to denial of service (memory exhaustion) that can be exploited remotely without authentication, possibly affecting another services running on the targeted host.
CWE description: The product does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.
CVSS v3 base score: 7.5
Published: 2018-12-20T23:29Z
Repository: https://github.com/elric1/knc
Language: C
Files changed: bin/gssstdio.c
Commit date: 2017-09-27 21:19:05 -0400
Commit message: knc: fix a couple of memory leaks.

One of these can be remotely triggered during the authentication
phase which leads to a remote DoS possibility.

Pointed out by: Imre Rad <radimre83@gmail.com>

Diff: diff --git a/bin/gssstdio.c b/bin/gssstdio.c
index 6a94208..01199fe 100644
--- a/bin/gssstdio.c
+++ b/bin/gssstdio.c
@@ -218,14 +218,17 @@ again:
 
 	maj = gss_accept_sec_context(&min, &ctx, GSS_C_NO_CREDENTIAL,
 	    &in, GSS_C_NO_CHANNEL_BINDINGS, &client, &mech_oid, &out, NULL,
 	    NULL, NULL);
 
+	gss_release_buffer(&min, &in);
+
 	if (out.length && write_packet(fd, &out)) {
 		gss_release_buffer(&min, &out);
 		return NULL;
 	}
+	gss_release_buffer(&min, &out);
 
 	GSTD_GSS_ERROR(maj, min, NULL, "gss_accept_sec_context");
 
 	if (maj & GSS_S_CONTINUE_NEEDED)
 		goto again;
@@ -471,11 +474,11 @@ read_packet(int fd, gss_buffer_t buf, int timeout, int first)
 		if (ret == -1) {
 			if (errno == EINTR || errno == EAGAIN)
 				return -2;
 
 			LOG(LOG_ERR, ("%s", strerror(errno)));
-			return -1;
+			goto bail;
 		}
 
 		if (ret == 0) {		/* EOF */
 			/* Failure to read ANY length just means we're done */
 			if (len_buf_pos == 0)
@@ -484,11 +487,11 @@ read_packet(int fd, gss_buffer_t buf, int timeout, int first)
 			/*
 			 * Otherwise, we got EOF mid-length, and that's
 			 * a protocol error.
 			 */
 			LOG(LOG_INFO, ("EOF reading packet len"));
-			return -1;
+			goto bail;
 		}
 
 		len_buf_pos += ret;
 	}
 
@@ -504,32 +507,33 @@ read_packet(int fd, gss_buffer_t buf, int timeout, int first)
 	 * slop in enc overhead, beyond the actual maximum number of
 	 * bytes of decrypted payload.
 	 */
 	if (len > GSTD_MAXPACKETCONTENTS + 512) {
 		LOG(LOG_ERR, ("ridiculous length, %ld", len));
-		return -1;
+		goto bail;
 	}
 
 	if (!tmpbuf) {
 		if ((tmpbuf = malloc(len)) == NULL) {
 			LOG(LOG_CRIT, ("malloc failure, %ld bytes", len));
-			return -1;
+			goto bail;
 		}
 	}
 
 	ret = timed_read(fd, tmpbuf + tmpbuf_pos, len - tmpbuf_pos, timeout);
 	if (ret == -1) {
+
 		if (errno == EINTR || errno == EAGAIN)
 			return -2;
 
 		LOG(LOG_ERR, ("%s", strerror(errno)));
-		return -1;
+		goto bail;
 	}
 
 	if (ret == 0) {
 		LOG(LOG_ERR, ("EOF while reading packet (len=%d)", len));
-		return -1;
+		goto bail;
 	}
 
 	tmpbuf_pos += ret;
 
 	if (tmpbuf_pos == len) {
@@ -541,10 +545,16 @@ read_packet(int fd, gss_buffer_t buf, int timeout, int first)
 		LOG(LOG_DEBUG, ("read packet of length %d", buf->length));
 		return 1;
 	}
 
 	return -2;
+
+bail:
+	free(tmpbuf);
+	tmpbuf = NULL;
+
+	return -1;
 }
 
 static int
 write_packet(int fd, gss_buffer_t buf)
 {

Vulnerable code: 			return -1;
			return -1;
		return -1;
			return -1;
		return -1;
		return -1;
Fixed code: 	gss_release_buffer(&min, &in);

	gss_release_buffer(&min, &out);
			goto bail;
			goto bail;
		goto bail;
			goto bail;

		goto bail;
		goto bail;

bail:
	free(tmpbuf);
	tmpbuf = NULL;

	return -1;