CVE-2023-25076: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow') (CWE-120)
value: A buffer overflow vulnerability exists in the handling of wildcard backend hosts of SNIProxy 0.6.0-2 and the master branch (commit: 822bb80df9b7b345cc9eba55df74a07b498819ba). A specially crafted HTTP or TLS packet can lead to arbitrary code execution. An attacker could send a malicious packet to trigger this vulnerability.
CWE description: The product copies an input buffer to an output buffer without verifying that the size of the input buffer is less than the size of the output buffer, leading to a buffer overflow.
CVSS v3 base score: 9.8
Published: 2023-03-30T15:15Z
Repository: https://github.com/dlundquist/sniproxy
Language: Other
Files changed: ChangeLog, configure.ac, debian/changelog, debian/compat, redhat/sniproxy.spec, setver.sh, src/address.c, tests/Makefile.am, tests/bad_dns_request_test, tests/slow_client_test
Commit date: 2023-03-16 21:57:26 -0700
Commit message: address: fix buffer overflow

Update tests to work on Debian 11.

Diff: diff --git a/ChangeLog b/ChangeLog
index fad3f81..a801a87 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
+2023-03-16  Dustin Lundquist <dustin@null-ptr.net>
+	0.6.1 Release
+
+	* Fix buffer overflow in address module
+	* Fix tests
+
 2018-12-05  Dustin Lundquist <dustin@null-ptr.net>
 	0.6.0 Release
 
 	* PROXY v1 protocol support
 	* SO_REUSEPORT support on Linux 3.9 and later
diff --git a/configure.ac b/configure.ac
index 1d0805b..cac74f1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,10 +1,10 @@
 #                                               -*- Autoconf -*-
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.60])
-AC_INIT([sniproxy], [0.6.0])
+AC_INIT([sniproxy], [0.6.1])
 AC_CONFIG_SRCDIR([src/sniproxy.c])
 AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([subdir-objects])
 AM_SILENT_RULES([yes])
 AC_GNU_SOURCE
diff --git a/debian/changelog b/debian/changelog
index 631a133..ed623a3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,12 @@
+sniproxy (0.6.1) unstable; urgency=high
+
+  * Fix buffer overflow in address module
+  * Fix tests
+
+ -- Dustin Lundquist <dustin@null-ptr.net>  Thu, 16 Mar 2023 21:53:48 -0700
+
 sniproxy (0.6.0) unstable; urgency=medium
 
   * PROXY v1 protocol support
   * SO_REUSEPORT support on Linux 3.9 and later
   * Listener ipv6_only directive to accept only IPv6 connections
@@ -8,11 +15,11 @@ sniproxy (0.6.0) unstable; urgency=medium
  -- Dustin Lundquist <dustin@null-ptr.net>  Wed, 05 Dec 2018 20:12:24 -0800
 
 sniproxy (0.5.0) unstable; urgency=medium
 
   * Transparent proxy support
-  * Use accept4() on Linix
+  * Use accept4() on Linux
   * Run as group specified in config
 
  -- Dustin Lundquist <dustin@null-ptr.net>  Wed, 26 Apr 2017 07:17:13 -0700
 
 sniproxy (0.4.0) unstable; urgency=medium
diff --git a/debian/compat b/debian/compat
index 45a4fb7..f599e28 100644
--- a/debian/compat
+++ b/debian/compat
@@ -1 +1 @@
-8
+10
diff --git a/redhat/sniproxy.spec b/redhat/sniproxy.spec
index 3633a1d..a3c6913 100644
--- a/redhat/sniproxy.spec
+++ b/redhat/sniproxy.spec
@@ -1,7 +1,7 @@
 Name: sniproxy
-Version: 0.6.0
+Version: 0.6.1
 Release: 1%{?dist}
 Summary: Transparent TLS and HTTP layer 4 proxy with SNI support
 
 Group: System Environment/Daemons
 License: BSD
@@ -44,10 +44,14 @@ rm -rf $RPM_BUILD_ROOT
 %{_mandir}/man5/sniproxy.conf.5.gz
 
 
 
 %changelog
+* Thu Mar 16 2023 Dustin Lundquist <dustin@null-ptr.net 0.6.1-1
+- Fix buffer overflow in address module
+- Fix tests
+
 * Wed Dec 5 2018 Dustin Lundquist <dustin@null-ptr.net> 0.6.0-1
 - PROXY v1 protocol support
 - SO_REUSEPORT support on Linux 3.9 and later
 - Listener ipv6_only directive to accept only IPv6 connections
 - TCP keepalive
diff --git a/setver.sh b/setver.sh
index 51c90a9..7e8a80b 100755
--- a/setver.sh
+++ b/setver.sh
@@ -1,8 +1,8 @@
 #!/bin/sh
 
-VERSION=0.6.0
+VERSION=0.6.1
 
 SOURCE_DIR=$(dirname $0)
 GIT_DIR=${SOURCE_DIR}/.git
 
 cd ${SOURCE_DIR}
diff --git a/src/address.c b/src/address.c
index 9a544a5..2811b7e 100644
--- a/src/address.c
+++ b/src/address.c
@@ -146,10 +146,12 @@ new_address(const char *hostname_or_ip) {
     /* [IPv6 address] */
     memset(&s, 0, sizeof(s));
     if (hostname_or_ip[0] == '[' &&
             (port = strchr(hostname_or_ip, ']')) != NULL) {
         len = (size_t)(port - hostname_or_ip - 1);
+        if (len >= INET6_ADDRSTRLEN)
+            return NULL;
 
         /* inet_pton() will not parse the IP correctly unless it is in a
          * separate string.
          */
         strncpy(ip_buf, hostname_or_ip + 1, len);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 19a4c61..706e218 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,8 +1,10 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src -g $(LIBEV_CFLAGS) $(LIBPCRE_CFLAGS) $(LIBUDNS_CFLAGS)
 AM_CFLAGS = -fno-strict-aliasing -Wall -Wextra -Wpedantic -Wwrite-strings
 
+.NOTPARALLEL:
+
 TESTS = address_test \
         buffer_test \
         cfg_tokenizer_test \
         table_test \
         http_test \
diff --git a/tests/bad_dns_request_test b/tests/bad_dns_request_test
index d37743f..7a0ea07 100755
--- a/tests/bad_dns_request_test
+++ b/tests/bad_dns_request_test
@@ -33,10 +33,15 @@ my $bad_requests = [
     {
         # Invalid hostname
         request => "GET / HTTP/1.1\r\nHost: \0example.com\r\n\r\n",
         client => \&http_client,
     },
+    {
+        # Exceed hostname buffer size
+        request => "GET / HTTP/1.1\r\nHost: [" . 'long.' x 60 . "example.com]\r\n\r\n",
+        client => \&http_client,
+    },
     {
         # Test client aborting connection before DNS response received
         request => "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n",
         client => \&http_client_abort,
     },
diff --git a/tests/slow_client_test b/tests/slow_client_test
index 6464872..4d9e975 100755
--- a/tests/slow_client_test
+++ b/tests/slow_client_test
@@ -29,15 +29,20 @@ sub slow_client($$) {
     alarm 10;
 
     my $socket = IO::Socket::INET->new(PeerAddr => '127.0.0.1',
             PeerPort => $port,
             Proto => "tcp",
-            Type => SOCK_STREAM)
+            Type => SOCK_STREAM,
+            Timeout => 5)
         or die "couldn't connect $!";
 
     $socket->send($request);
     foreach (split("\r\n", $request)) {
+        unless ($socket->connected()) {
+            print "Disconnected\n";
+            exit(0);
+        }
         $socket->send("$_\r\n");
         sleep(1);
     }
 
     my $buffer;

Vulnerable code: AC_INIT([sniproxy], [0.6.0])
  * Use accept4() on Linix
8
Version: 0.6.0
VERSION=0.6.0
            Type => SOCK_STREAM)
Fixed code: 2023-03-16  Dustin Lundquist <dustin@null-ptr.net>
	0.6.1 Release

	* Fix buffer overflow in address module
	* Fix tests

AC_INIT([sniproxy], [0.6.1])
sniproxy (0.6.1) unstable; urgency=high

  * Fix buffer overflow in address module
  * Fix tests

 -- Dustin Lundquist <dustin@null-ptr.net>  Thu, 16 Mar 2023 21:53:48 -0700

  * Use accept4() on Linux
10
Version: 0.6.1
* Thu Mar 16 2023 Dustin Lundquist <dustin@null-ptr.net 0.6.1-1
- Fix buffer overflow in address module
- Fix tests

VERSION=0.6.1
        if (len >= INET6_ADDRSTRLEN)
            return NULL;
.NOTPARALLEL:

    {
        # Exceed hostname buffer size
        request => "GET / HTTP/1.1\r\nHost: [" . 'long.' x 60 . "example.com]\r\n\r\n",
        client => \&http_client,
    },
            Type => SOCK_STREAM,
            Timeout => 5)
        unless ($socket->connected()) {
            print "Disconnected\n";
            exit(0);
        }