Back to Blog
critical SEVERITY7 min read

Critical Buffer Overflow in veejay packet.c: How Unchecked Network Packet Sizes Enable Remote Code Execution

A critical heap buffer overflow vulnerability was discovered in veejay's `packet.c` networking code, where `veejay_memcpy` operations used attacker-controlled size values from network packet headers without any boundary validation. This flaw could allow a remote attacker to send crafted packets that trigger heap corruption, potentially leading to arbitrary code execution. The fix adds proper buffer-length checks before any memory copy operations, ensuring that packet sizes are validated against

O
By orbisai0security
May 28, 2026

Critical Buffer Overflow in veejay packet.c: How Unchecked Network Packet Sizes Enable Remote Code Execution

Introduction

Buffer overflow vulnerabilities are among the oldest and most dangerous classes of security bugs in systems programming — and they're far from extinct. In 2024, a critical buffer overflow was identified and patched in veejay, an open-source real-time video performance tool widely used in live visual art and VJing communities.

The vulnerability lived in veejay-current/veejay-core/libvjnet/packet.c, a file responsible for handling network packet data. The root cause? Memory copy operations that blindly trusted size values supplied by incoming network packets — a classic CWE-120 (Buffer Copy Without Checking Size of Input) scenario.

If you write C or C++ code that handles network data, this post is essential reading. Even if you don't, understanding this class of vulnerability helps you appreciate why memory-safe languages and defensive coding practices matter so much.


The Vulnerability Explained

What Is a Heap Buffer Overflow?

When a program allocates a block of memory on the heap (e.g., via malloc) and then writes more data into that block than it can hold, the excess data spills into adjacent memory regions. This is a heap buffer overflow. Depending on what lives in that adjacent memory, an attacker can:

  • Corrupt heap metadata, causing crashes or undefined behavior
  • Overwrite function pointers or vtables, redirecting code execution
  • Achieve arbitrary code execution (RCE), the most severe outcome

The Vulnerable Code Pattern

In packet.c, the code performed veejay_memcpy operations using CHUNK_SIZE and len values that were derived directly from network packet headers:

// BEFORE (vulnerable pseudocode)
int len = read_packet_header_length(packet);   // attacker-controlled!
int chunk = read_packet_chunk_size(packet);    // attacker-controlled!

// No validation — len or chunk could be larger than dst buffer
veejay_memcpy(dst_buffer, src_data, len);
veejay_memcpy(chunk_buffer, chunk_data, chunk);

The critical flaw here is that len and chunk come from the network — meaning any remote peer can set them to arbitrary values. There is no check asking: "Does this size actually fit within the destination buffer?"

How Could an Attacker Exploit This?

The attack scenario is straightforward:

  1. Attacker identifies a veejay instance listening on the network (default multicast/unicast video streaming ports).
  2. Attacker crafts a malicious packet with an inflated len or CHUNK_SIZE value in the header — for example, claiming the payload is 1,000,000 bytes when the destination buffer is only 4,096 bytes.
  3. veejay processes the packet, calls veejay_memcpy with the attacker-supplied size, and writes far beyond the allocated buffer.
  4. Heap corruption occurs. With careful crafting, the attacker can overwrite adjacent heap objects, manipulate allocator metadata, or redirect execution flow.
  5. Remote code execution becomes possible — the attacker's payload runs with the privileges of the veejay process.

This is especially concerning in live performance environments where veejay instances may be exposed on local area networks, festival networks, or even the public internet.

Real-World Impact

Impact Area Details
Confidentiality Full system compromise possible
Integrity Arbitrary code execution
Availability Process crash / denial of service
Attack Vector Network (remote, no authentication required)
Severity CRITICAL

The vulnerability also affected mcastreceiver.c, the multicast receiver component, broadening the attack surface to multicast network scenarios.


The Fix

What Changed

The fix was applied to two files:
- veejay-current/veejay-core/libvjnet/packet.c
- veejay-current/veejay-core/libvjnet/mcastreceiver.c

The core change introduces explicit buffer-length validation before any veejay_memcpy call that uses network-supplied size values. The pattern looks like this:

// AFTER (fixed pseudocode)
int len = read_packet_header_length(packet);
int chunk = read_packet_chunk_size(packet);

// Validate BEFORE copying
if (len <= 0 || len > MAX_PACKET_SIZE || len > dst_buffer_size) {
    veejay_msg(VEEJAY_MSG_ERROR,
        "Packet length %d exceeds buffer boundary, dropping packet", len);
    return -1;
}

if (chunk <= 0 || chunk > CHUNK_SIZE || chunk > chunk_buffer_size) {
    veejay_msg(VEEJAY_MSG_ERROR,
        "Chunk size %d exceeds buffer boundary, dropping packet", chunk);
    return -1;
}

// Safe to copy — sizes have been validated
veejay_memcpy(dst_buffer, src_data, len);
veejay_memcpy(chunk_buffer, chunk_data, chunk);

Why This Fix Works

The fix enforces a fundamental security principle: never trust input from the network. By checking that:

  1. The size is positive (prevents integer underflow tricks)
  2. The size does not exceed a known maximum (MAX_PACKET_SIZE)
  3. The size does not exceed the actual destination buffer size

...the code ensures that veejay_memcpy can never write beyond the allocated region, regardless of what values an attacker provides in the packet header.

Malformed or oversized packets are now silently dropped with an error log, rather than blindly processed. This is the correct behavior for a network application receiving untrusted data.

Defense in Depth

Beyond the direct fix, a well-hardened version of this code would also benefit from:

// Using safer bounded copy as additional layer
// Instead of: veejay_memcpy(dst, src, attacker_len)
// Prefer:      memcpy(dst, src, MIN(attacker_len, sizeof(dst)))

This "belt and suspenders" approach means even if a future developer accidentally removes the explicit check, the bounded copy limits damage.


Prevention & Best Practices

1. Never Trust Network-Supplied Lengths

Any size, offset, or count value that arrives from the network must be treated as hostile input. Always validate against known-safe bounds before using the value in a memory operation.

// Dangerous pattern
memcpy(buffer, data, network_supplied_length);

// Safe pattern
if (network_supplied_length > sizeof(buffer)) {
    handle_error();
    return;
}
memcpy(buffer, data, network_supplied_length);

2. Use Compiler and OS Mitigations

Modern toolchains offer several protections that raise the bar for exploiting buffer overflows:

Mitigation How to Enable What It Does
Stack Canaries -fstack-protector-strong Detects stack smashing
ASLR OS-level (default on Linux) Randomizes memory layout
PIE -fPIE -pie Position-independent executable
RELRO -Wl,-z,relro,-z,now Hardens GOT/PLT
FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 Adds runtime buffer checks

These don't replace proper input validation, but they significantly increase exploit complexity.

3. Use Static Analysis Tools

Several tools can catch CWE-120 class vulnerabilities automatically:

Integrating these into your CI/CD pipeline means issues like this get caught before they reach production.

4. Adopt Fuzzing for Network Code

Network parsers are prime candidates for fuzz testing. Tools like AFL++ and libFuzzer automatically generate malformed inputs and monitor for crashes — exactly the kind of testing that would have surfaced this vulnerability early.

# Example: running AFL++ against a network parser
afl-fuzz -i inputs/ -o findings/ -- ./veejay_packet_parser @@

5. Prefer Memory-Safe Languages Where Possible

For new networking code, languages like Rust provide memory safety guarantees at compile time, making entire classes of buffer overflow vulnerabilities impossible by construction. If rewriting existing C code isn't feasible, consider wrapping the most dangerous parsing logic in a Rust or Go component.

Security Standards Reference


Conclusion

This vulnerability in veejay's packet.c is a textbook example of why input validation is non-negotiable in network code. A few missing bounds checks turned a routine memory copy into a potential remote code execution vector — the most severe outcome in the security threat model.

The key takeaways from this incident:

Always validate network-supplied sizes before using them in memory operations

Treat every byte from the network as hostile until proven otherwise

Layer your defenses: input validation + compiler mitigations + runtime sanitizers

Automate security scanning in CI/CD to catch issues early and cheaply

Fuzz your network parsers — automated tools find what human review misses

Buffer overflows have been exploited since the Morris Worm of 1988. Decades later, they remain one of the most impactful vulnerability classes in systems software. The good news: with the right tools, practices, and mindset, they are entirely preventable.

If you maintain C or C++ code that processes network data, take this as a prompt to audit your own packet parsing logic. The fix is often just a few lines — but the protection it provides is invaluable.


This vulnerability was identified and patched as part of an automated security review. The fix was verified by build testing and scanner re-scan confirmation.

Have a vulnerability you'd like explained? Reach out to the Fenny Security team.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #383

Related Articles

critical

Heap Buffer Overflow in Audio Ring Buffer: How a Missing Bounds Check Could Crash Your App

A critical heap buffer overflow vulnerability was discovered in `audio_backend.c`, where the audio ring buffer's `memcpy` operations lacked bounds validation before writing PCM data. Without checking that incoming data sizes fell within the allocated buffer's capacity, a maliciously crafted audio file could corrupt adjacent heap memory, potentially enabling arbitrary code execution. The fix adds a concise pre-flight validation guard that rejects out-of-range write requests before any memory oper

critical

Critical Heap Buffer Overflow in SSDP Control Point: How Unbounded String Operations Put Networks at Risk

A critical heap buffer overflow vulnerability was discovered and patched in the SSDP control point implementation (`ssdp_ctrlpt.c`), where multiple unbounded `strcpy` and `strcat` operations constructed HTTP request buffers without any length validation. Network-received SSDP response fields — including service type strings and location URLs — could be crafted by an attacker to exceed buffer boundaries, potentially enabling arbitrary code execution or denial of service. The fix replaces the unsa

critical

Heap Buffer Overflow in OPDS Parser: How a Misplaced Variable Nearly Opened the Door to Remote Code Execution

A critical heap buffer overflow vulnerability was discovered in `lib/OpdsParser/OpdsParser.cpp`, where the buffer allocation size was calculated *after* a fixed chunk size was used to allocate memory, meaning the actual bytes read could exceed the allocated buffer. On embedded devices parsing untrusted OPDS catalog data from the network, this flaw could allow a remote attacker to corrupt heap memory and potentially achieve arbitrary code execution. The fix was elegantly simple: move the `toRead`

critical

Heap Buffer Overflow in BLE MIDI: How a Missing Bounds Check Opens the Door to Remote Exploitation

A critical heap buffer overflow vulnerability was discovered in the BLE MIDI packet assembly code of `blemidi.c`, where attacker-controlled packet length values could trigger writes beyond allocated heap memory. The fix adds an integer overflow guard before the `malloc` call, ensuring that maliciously crafted BLE MIDI packets can no longer corrupt heap memory. This vulnerability is particularly dangerous because it is remotely exploitable by any nearby Bluetooth device — no physical access requi

critical

Heap Overflow in TOML Parser: How Integer Overflow Leads to Memory Corruption

A critical heap buffer overflow vulnerability was discovered and patched in the centitoml TOML parser, where missing integer overflow validation on a `MALLOC(len+1)` call could allow an attacker to trigger memory corruption via a crafted TOML configuration file. The vulnerability (CWE-190) is reachable through community-distributed mod or map files that the game loads from its `config/` directory, making it a realistic attack vector for remote code execution. A targeted one-line guard now preven

critical

Heap Corruption via Unchecked memcpy: How Integer Overflow Bugs Corrupt Memory in Windows File Operations

A critical buffer overflow vulnerability was discovered in `phlib/nativefile.c`, where multiple `memcpy` calls copied filename and extended-attribute data into fixed-size structures without verifying that source lengths didn't exceed destination buffer boundaries. An attacker supplying an oversized filename or EA name could corrupt adjacent heap memory, potentially enabling arbitrary code execution. The fix replaces unchecked arithmetic with Windows' safe integer helpers (`RtlULongAdd`, `RtlULon