tcpdump: Fix CVE-2018-16301
This fixes the following security problem: The command-line argument parser in tcpdump before 4.99.0 has a buffer overflow in tcpdump.c:read_infile(). To trigger this vulnerability the attacker needs to create a 4GB file on the local filesystem and to specify the file name as the value of the -F command-line argument of tcpdump. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
		| @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk | ||||
|  | ||||
| PKG_NAME:=tcpdump | ||||
| PKG_VERSION:=4.9.3 | ||||
| PKG_RELEASE:=3 | ||||
| PKG_RELEASE:=4 | ||||
|  | ||||
| PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz | ||||
| PKG_SOURCE_URL:=http://www.tcpdump.org/release/ | ||||
|   | ||||
							
								
								
									
										101
									
								
								package/network/utils/tcpdump/patches/102-CVE-2018-16301.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								package/network/utils/tcpdump/patches/102-CVE-2018-16301.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| From 8ab211a7ec728bb0ad8c766c8eeb12deb0a13b86 Mon Sep 17 00:00:00 2001 | ||||
| From: Guy Harris <gharris@sonic.net> | ||||
| Date: Wed, 30 Sep 2020 11:37:30 -0700 | ||||
| Subject: [PATCH] Handle very large -f files by rejecting them. | ||||
|  | ||||
| _read(), on Windows, has a 32-bit size argument and a 32-bit return | ||||
| value, so reject -f files that have more than 2^31-1 characters. | ||||
|  | ||||
| Add some #defines so that, on Windows, we use _fstati64 to get the size | ||||
| of that file, to handle large files. | ||||
|  | ||||
| Don't assume that our definition for ssize_t is the same size as size_t; | ||||
| by the time we want to print the return value of the read, we know it'll | ||||
| fit into an int, so just cast it to int and print it with %d. | ||||
|  | ||||
| (cherry picked from commit faf8fb70af3a013e5d662b8283dec742fd6b1a77) | ||||
| --- | ||||
|  netdissect-stdinc.h | 16 +++++++++++++++- | ||||
|  tcpdump.c           | 15 ++++++++++++--- | ||||
|  2 files changed, 27 insertions(+), 4 deletions(-) | ||||
|  | ||||
| --- a/netdissect-stdinc.h | ||||
| +++ b/netdissect-stdinc.h | ||||
| @@ -149,10 +149,17 @@ | ||||
|  #ifdef _MSC_VER | ||||
|  #define stat _stat | ||||
|  #define open _open | ||||
| -#define fstat _fstat | ||||
|  #define read _read | ||||
|  #define close _close | ||||
|  #define O_RDONLY _O_RDONLY | ||||
| + | ||||
| +/* | ||||
| + * We define our_fstat64 as _fstati64, and define our_statb as | ||||
| + * struct _stati64, so we get 64-bit file sizes. | ||||
| + */ | ||||
| +#define our_fstat _fstati64 | ||||
| +#define our_statb struct _stati64 | ||||
| + | ||||
|  #endif  /* _MSC_VER */ | ||||
|   | ||||
|  /* | ||||
| @@ -211,6 +218,13 @@ typedef char* caddr_t; | ||||
|   | ||||
|  #include <arpa/inet.h> | ||||
|   | ||||
| +/* | ||||
| + * We should have large file support enabled, if it's available, | ||||
| + * so just use fstat as our_fstat and struct stat as our_statb. | ||||
| + */ | ||||
| +#define our_fstat fstat | ||||
| +#define our_statb struct stat | ||||
| + | ||||
|  #endif /* _WIN32 */ | ||||
|   | ||||
|  #ifndef HAVE___ATTRIBUTE__ | ||||
| --- a/tcpdump.c | ||||
| +++ b/tcpdump.c | ||||
| @@ -108,6 +108,7 @@ The Regents of the University of Califor | ||||
|  #endif /* HAVE_CAP_NG_H */ | ||||
|  #endif /* HAVE_LIBCAP_NG */ | ||||
|   | ||||
| +#include "netdissect-stdinc.h" | ||||
|  #include "netdissect.h" | ||||
|  #include "interface.h" | ||||
|  #include "addrtoname.h" | ||||
| @@ -861,15 +862,22 @@ read_infile(char *fname) | ||||
|  { | ||||
|  	register int i, fd, cc; | ||||
|  	register char *cp; | ||||
| -	struct stat buf; | ||||
| +	our_statb buf; | ||||
|   | ||||
|  	fd = open(fname, O_RDONLY|O_BINARY); | ||||
|  	if (fd < 0) | ||||
|  		error("can't open %s: %s", fname, pcap_strerror(errno)); | ||||
|   | ||||
| -	if (fstat(fd, &buf) < 0) | ||||
| +	if (our_fstat(fd, &buf) < 0) | ||||
|  		error("can't stat %s: %s", fname, pcap_strerror(errno)); | ||||
|   | ||||
| +	/* | ||||
| +	 * Reject files whose size doesn't fit into an int; a filter | ||||
| +	 * *that* large will probably be too big. | ||||
| +	 */ | ||||
| +	if (buf.st_size > INT_MAX) | ||||
| +		error("%s is too large", fname); | ||||
| + | ||||
|  	cp = malloc((u_int)buf.st_size + 1); | ||||
|  	if (cp == NULL) | ||||
|  		error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1, | ||||
| @@ -878,7 +886,8 @@ read_infile(char *fname) | ||||
|  	if (cc < 0) | ||||
|  		error("read %s: %s", fname, pcap_strerror(errno)); | ||||
|  	if (cc != buf.st_size) | ||||
| -		error("short read %s (%d != %d)", fname, cc, (int)buf.st_size); | ||||
| +		error("short read %s (%d != %d)", fname, (int) cc, | ||||
| +		    (int)buf.st_size); | ||||
|   | ||||
|  	close(fd); | ||||
|  	/* replace "# comment" with spaces */ | ||||
		Reference in New Issue
	
	Block a user
	 Hauke Mehrtens
					Hauke Mehrtens