[pcap-ng-format] sane maximum length for block_length

Michael Richardson mcr at sandelman.ca
Wed Sep 18 22:59:22 UTC 2019


     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      Block Total Length                       |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   o  Block Total Length (32 bits): an unsigned value giving the total
      size of this block, in octets.  For instance, the length of a
      block that does not have a body is 12 octets: 4 octets for the
      Block Type, 4 octets for the initial Block Total Length and 4
      octets for the trailing Block Total Length.  This value MUST be a
      multiple of 4.

In working on some CVEs, a number of them put nonsensically big values into
this field.  On amd64 quite a number of big values "just work", although with
some negative affect on the VM system as it allocates lots of level-2 pages.
On i386 systems, it just dies with out of memory.

We careful not to put any artificial restrictions on the size of the blocks,
and maybe 4G is big enough.   libpcap's pcap_ng reader takes this block total
length and uses it to estimate a good buffer for reading:

	/*
	 * Allocate a buffer into which to read blocks.  We default to
	 * the maximum of:
	 *
	 *	the total length of the SHB for which we read the header;
	 *
	 *	2K, which should be more than large enough for an Enhanced
	 *	Packet Block containing a full-size Ethernet frame, and
	 *	leaving room for some options.
	 *
	 * If we find a bigger block, we reallocate the buffer, up to
	 * the maximum size.  We start out with a maximum size based
	 * on a maximum snapshot length of MAXIMUM_SNAPLEN; if we see
	 * any link-layer header types with a larger maximum snapshot
	 * length, we boost the maximum.
	 */
	p->bufsize = 2048;
	if (p->bufsize < total_length)
		p->bufsize = total_length;
	p->buffer = malloc(p->bufsize);
	if (p->buffer == NULL) {
		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
		free(p);
		*err = 1;
		return (NULL);
	}

(total_length comes from the pcap-ng file)
It seems to be that numbers bigger than 1MB here for a *Section Header Block*
should be more than enough.   If we knew the size of the file (it's not a
pipe, and it's not coming from a stream de-compressor), then we could set
another reasonable maximum.  In that case, we could mmap() the file and win
much more.

I'm going to insert some sane value checks into the block_total_length.
I'll put them clearly in a header, and they ought to be per block-type.
Is it reasonable for the internet-draft to say something about each type?

--
]               Never tell me the odds!                 | ipv6 mesh networks [
]   Michael Richardson, Sandelman Software Works        |    IoT architect   [
]     mcr at sandelman.ca  http://www.sandelman.ca/        |   ruby on rails    [






-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 487 bytes
Desc: not available
URL: <http://www.winpcap.org/pipermail/pcap-ng-format/attachments/20190918/f13a9786/attachment.sig>


More information about the pcap-ng-format mailing list