diff options
author | Guy Harris <guy@alum.mit.edu> | 2018-08-05 21:35:49 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2019-10-02 13:37:40 -0700 |
commit | 0b6a6fd8f347e298e18a02266f879c28f97199e9 (patch) | |
tree | 310080d7acc4bf5049dff63776fffe4990d9c381 /rpcapd | |
parent | 080c59b49fccd2a1d5cd1a2525afde1d27454188 (diff) | |
download | libpcap-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.c | 24 |
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) { |