Skip to content

Navigation Menu

Sign in
Sign up

Possible out-of-bounds write to header_data in PcapSession::PacketReady #305

Open

Description

Possible out-of-bounds write to header_data in PcapSession::PacketReady

I found a possible OOB write (CWE-787) in PcapSession::PacketReady. Dispatch records the
caller's packet buffer and its length (buffer_data/buffer_length) but records only the
pointer of the second "header" buffer (header_data) — never its length. When a packet arrives,
PacketReady clamps the copy into buffer_data to buffer_length, but then unconditionally
writes 16 fixed bytes (four 4-byte fields) into header_data with no size check. If the caller
passes a header Buffer smaller than 16 bytes, those memcpys write past the end of the Buffer's
backing store — a heap out-of-bounds write. The asymmetry with the properly-clamped
buffer_data path confirms the missing check.

File: pcap_session.cc

Function: PcapSession::PacketReady (destination captured in PcapSession::Dispatch)

// Dispatch(): buffer length is captured, header length is NOT
session->buffer_data = node::Buffer::Data(buffer_obj);
session->buffer_length = node::Buffer::Length(buffer_obj);
Local<Object> header_obj = info[1]->ToObject(...).FromMaybe(Local<v8::Object>());
session->header_data = node::Buffer::Data(header_obj); // no header length stored
// PacketReady(): buffer_data copy is clamped, header_data is not
size_t copy_len = pkthdr->caplen;
if (copy_len > session->buffer_length) copy_len = session->buffer_length;
memcpy(session->buffer_data, packet, copy_len); // bounded
memcpy(session->header_data, &(pkthdr->ts.tv_sec), 4);
memcpy(session->header_data + 4, &(pkthdr->ts.tv_usec), 4);
memcpy(session->header_data + 8, &(pkthdr->caplen), 4);
memcpy(session->header_data + 12, &(pkthdr->len), 4); // writes bytes 12..15 unconditionally
  1. Dispatch validates both arguments are Buffers but stores no length for the header buffer.
  2. PacketReady writes 16 bytes total to header_data (offsets 0, 4, 8, 12) every time a
    packet is dispatched, with no comparison against the header Buffer's real size.
  3. A header Buffer shorter than 16 bytes therefore takes an out-of-bounds heap write of up to
    16 bytes past its end.

JS trigger (if applicable):

const binding = require('./build/Release/pcap_binding');
const session = new binding.PcapSession();
// ... session.open_live(...) ...
const packetBuf = Buffer.alloc(65535);
const headerBuf = Buffer.alloc(4); // < 16 bytes
session.dispatch(packetBuf, headerBuf); // PacketReady writes 16 bytes into a 4-byte buffer

Suggested fix: in Dispatch, capture header_length = node::Buffer::Length(header_obj) and
require it to be at least 16 (throw otherwise), or have PacketReady bound its header writes to
the stored header length before each memcpy.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      AltStyle によって変換されたページ (->オリジナル) /