summaryrefslogtreecommitdiff
path: root/rpcapd
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2018-08-05 21:35:49 -0700
committerGuy Harris <guy@alum.mit.edu>2019-10-02 13:37:40 -0700
commit0b6a6fd8f347e298e18a02266f879c28f97199e9 (patch)
tree310080d7acc4bf5049dff63776fffe4990d9c381 /rpcapd
parent080c59b49fccd2a1d5cd1a2525afde1d27454188 (diff)
downloadlibpcap-0b6a6fd8f347e298e18a02266f879c28f97199e9.tar.gz
Limit the size of a filter program.
This makes it harder to run the Windows daemon our of memory. It also addresses Include Security issue F1: [libpcap] Remote Packet Capture Daemon (RPCAPD) Integer Overflow Leads to Heap Buffer Overflow.
Diffstat (limited to 'rpcapd')
-rw-r--r--rpcapd/daemon.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/rpcapd/daemon.c b/rpcapd/daemon.c
index c338ade4..46af8316 100644
--- a/rpcapd/daemon.c
+++ b/rpcapd/daemon.c
@@ -2224,6 +2224,23 @@ daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars,
return 0;
}
+//
+// We impose a limit on the filter program size, so that, on Windows,
+// where there's only one server process with multiple threads, it's
+// harder to eat all the server address space by sending larger filter
+// programs. (This isn't an issue on UN*X, where there are multiple
+// server processes, one per client connection.)
+//
+// We pick a value that limits each filter to 64K; that value is twice
+// the in-kernel limit for Linux and 16 times the in-kernel limit for
+// *BSD and macOS.
+//
+// It also prevents an overflow on 32-bit platforms when calculating
+// the total size of the filter program. (It's not an issue on 64-bit
+// platforms with a 64-bit size_t, as the filter size is 32 bits.)
+//
+#define RPCAP_BPF_MAXINSNS 8192
+
static int
daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session, uint32 *plenp, char *errmsgbuf)
{
@@ -2253,6 +2270,13 @@ daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session
return -2;
}
+ if (bf_prog.bf_len > RPCAP_BPF_MAXINSNS)
+ {
+ snprintf(errmsgbuf, PCAP_ERRBUF_SIZE,
+ "Filter program is larger than the maximum size of %u instructions",
+ RPCAP_BPF_MAXINSNS);
+ return -2;
+ }
bf_insn = (struct bpf_insn *) malloc (sizeof(struct bpf_insn) * bf_prog.bf_len);
if (bf_insn == NULL)
{