From: Marco d'Itri <md@linux.it>
Date: Sat, 14 May 2022 02:57:49 +0800
Subject: Fix parsing of lines longer than 2047 characters

If a line in /etc/hosts.{allow,deny} is longer than BUFLEN-1 (2047)
characters then len will be set to 1 at the end of the xgets() loop.

At the next iteration, fgets will be passed a buffer of length 1, so it
will only be able to read an empty string (the buffer must always have
space for the trailing NUL).

strlen(3) on the empty string will return 0, so len will not be modified
anymore and the last step will repeat forever.

To reproduce:
perl -e 'print "#sshd: " . ("127.0.0.1, " x 210) . "\n"' > hosts.deny
tcpdmatch -d test localhost
Bug-Debian: http://bugs.debian.org/596261
---
 hosts_access.c | 4 +++-
 misc.c         | 2 ++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/hosts_access.c b/hosts_access.c
index 761e644..cd73d8f 100644
--- a/hosts_access.c
+++ b/hosts_access.c
@@ -165,7 +165,9 @@ struct request_info *request;
 	while (match == NO && xgets(sv_list, sizeof(sv_list), fp) != 0) {
 	    if (sv_list[strlen(sv_list) - 1] != '\n') {
 		tcpd_warn("missing newline or line too long");
-		continue;
+		tcpd_warn("all the subsequent rules will be ignored");
+		match = ERR;
+		break;
 	    }
 	    if (sv_list[0] == '#' || sv_list[strspn(sv_list, " \t\r\n")] == 0)
 		continue;
diff --git a/misc.c b/misc.c
index c283e06..1eb3334 100644
--- a/misc.c
+++ b/misc.c
@@ -45,6 +45,8 @@ FILE   *fp;
 	}
 	ptr += got;
 	len -= got;
+	if (len == 1)
+	    return(start);
 	ptr[0] = 0;
     }
     return (ptr > start ? start : 0);
