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.
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.
9 Add some #defines so that, on Windows, we use _fstati64 to get the size
10 of that file, to handle large files.
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.
16 (cherry picked from commit faf8fb70af3a013e5d662b8283dec742fd6b1a77)
18 netdissect-stdinc.h | 16 +++++++++++++++-
19 tcpdump.c | 15 ++++++++++++---
20 2 files changed, 27 insertions(+), 4 deletions(-)
22 --- a/netdissect-stdinc.h
23 +++ b/netdissect-stdinc.h
31 #define O_RDONLY _O_RDONLY
34 + * We define our_fstat64 as _fstati64, and define our_statb as
35 + * struct _stati64, so we get 64-bit file sizes.
37 +#define our_fstat _fstati64
38 +#define our_statb struct _stati64
43 @@ -211,6 +218,13 @@ typedef char* caddr_t;
45 #include <arpa/inet.h>
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.
51 +#define our_fstat fstat
52 +#define our_statb struct stat
56 #ifndef HAVE___ATTRIBUTE__
59 @@ -108,6 +108,7 @@ The Regents of the University of Califor
60 #endif /* HAVE_CAP_NG_H */
61 #endif /* HAVE_LIBCAP_NG */
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)
69 register int i, fd, cc;
74 fd = open(fname, O_RDONLY|O_BINARY);
76 error("can't open %s: %s", fname, pcap_strerror(errno));
78 - if (fstat(fd, &buf) < 0)
79 + if (our_fstat(fd, &buf) < 0)
80 error("can't stat %s: %s", fname, pcap_strerror(errno));
83 + * Reject files whose size doesn't fit into an int; a filter
84 + * *that* large will probably be too big.
86 + if (buf.st_size > INT_MAX)
87 + error("%s is too large", fname);
89 cp = malloc((u_int)buf.st_size + 1);
91 error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1,
92 @@ -878,7 +886,8 @@ read_infile(char *fname)
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,
101 /* replace "# comment" with spaces */