tcpdump: Fix CVE-2018-16301
[openwrt/openwrt.git] / package / network / utils / tcpdump / patches / 102-CVE-2018-16301.patch
1 From 8ab211a7ec728bb0ad8c766c8eeb12deb0a13b86 Mon Sep 17 00:00:00 2001
2 From: Guy Harris <gharris@sonic.net>
3 Date: Wed, 30 Sep 2020 11:37:30 -0700
4 Subject: [PATCH] Handle very large -f files by rejecting them.
5
6 _read(), on Windows, has a 32-bit size argument and a 32-bit return
7 value, so reject -f files that have more than 2^31-1 characters.
8
9 Add some #defines so that, on Windows, we use _fstati64 to get the size
10 of that file, to handle large files.
11
12 Don't assume that our definition for ssize_t is the same size as size_t;
13 by the time we want to print the return value of the read, we know it'll
14 fit into an int, so just cast it to int and print it with %d.
15
16 (cherry picked from commit faf8fb70af3a013e5d662b8283dec742fd6b1a77)
17 ---
18 netdissect-stdinc.h | 16 +++++++++++++++-
19 tcpdump.c | 15 ++++++++++++---
20 2 files changed, 27 insertions(+), 4 deletions(-)
21
22 --- a/netdissect-stdinc.h
23 +++ b/netdissect-stdinc.h
24 @@ -149,10 +149,17 @@
25 #ifdef _MSC_VER
26 #define stat _stat
27 #define open _open
28 -#define fstat _fstat
29 #define read _read
30 #define close _close
31 #define O_RDONLY _O_RDONLY
32 +
33 +/*
34 + * We define our_fstat64 as _fstati64, and define our_statb as
35 + * struct _stati64, so we get 64-bit file sizes.
36 + */
37 +#define our_fstat _fstati64
38 +#define our_statb struct _stati64
39 +
40 #endif /* _MSC_VER */
41
42 /*
43 @@ -211,6 +218,13 @@ typedef char* caddr_t;
44
45 #include <arpa/inet.h>
46
47 +/*
48 + * We should have large file support enabled, if it's available,
49 + * so just use fstat as our_fstat and struct stat as our_statb.
50 + */
51 +#define our_fstat fstat
52 +#define our_statb struct stat
53 +
54 #endif /* _WIN32 */
55
56 #ifndef HAVE___ATTRIBUTE__
57 --- a/tcpdump.c
58 +++ b/tcpdump.c
59 @@ -108,6 +108,7 @@ The Regents of the University of Califor
60 #endif /* HAVE_CAP_NG_H */
61 #endif /* HAVE_LIBCAP_NG */
62
63 +#include "netdissect-stdinc.h"
64 #include "netdissect.h"
65 #include "interface.h"
66 #include "addrtoname.h"
67 @@ -861,15 +862,22 @@ read_infile(char *fname)
68 {
69 register int i, fd, cc;
70 register char *cp;
71 - struct stat buf;
72 + our_statb buf;
73
74 fd = open(fname, O_RDONLY|O_BINARY);
75 if (fd < 0)
76 error("can't open %s: %s", fname, pcap_strerror(errno));
77
78 - if (fstat(fd, &buf) < 0)
79 + if (our_fstat(fd, &buf) < 0)
80 error("can't stat %s: %s", fname, pcap_strerror(errno));
81
82 + /*
83 + * Reject files whose size doesn't fit into an int; a filter
84 + * *that* large will probably be too big.
85 + */
86 + if (buf.st_size > INT_MAX)
87 + error("%s is too large", fname);
88 +
89 cp = malloc((u_int)buf.st_size + 1);
90 if (cp == NULL)
91 error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1,
92 @@ -878,7 +886,8 @@ read_infile(char *fname)
93 if (cc < 0)
94 error("read %s: %s", fname, pcap_strerror(errno));
95 if (cc != buf.st_size)
96 - error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
97 + error("short read %s (%d != %d)", fname, (int) cc,
98 + (int)buf.st_size);
99
100 close(fd);
101 /* replace "# comment" with spaces */