Skip to content

Hardening: Fix memory leak in pcapng fail path and secure realloc logic#1665

Open
Noamismach wants to merge 1 commit intothe-tcpdump-group:masterfrom
Noamismach:c99-pcapng-hardening
Open

Hardening: Fix memory leak in pcapng fail path and secure realloc logic#1665
Noamismach wants to merge 1 commit intothe-tcpdump-group:masterfrom
Noamismach:c99-pcapng-hardening

Conversation

@Noamismach
Copy link
Copy Markdown

This is a pure C99 follow-up to the discussions in PR #1664, isolating the parser hardening and memory leak fixes as recommended by @guyharris and @mcr.

What this PR changes:

  • Fixes Memory Leaks in pcap_ng_check_header: Reroutes early error returns (such as unknown timestamp precision or p->buffer allocation failures) through the goto fail path. This ensures that ps->ifaces and p->buffer are properly freed before returning NULL.
  • Hardens realloc state in read_block: Ensures that when p->buffer is successfully expanded via realloc into a temporary pointer, the metadata (p->bufsize) is correctly updated to track the new capacity. This prevents stale size tracking and repeated, unnecessary reallocation attempts.

This patch strictly adheres to the project's C99 requirements and introduces no changes to the build systems.

Comment thread sf-pcapng.c
free(p);
*err = 1;
return (NULL);
goto fail;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure there's a leak there, as nothing other than the pcap_t-plus-private-data was allocated, and it's freed, but this is good practice anyway in case the code changes - the resource deallocation is, at least, centralized.

(This is not one of C's strengths.)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Even if the secondary allocations havent occurred yet at this specific point, funneling everything through a centralized goto fail block removes a major footgun for future modifications. And yes, definitely not one of C's strengths!

Comment thread sf-pcapng.c
free(p);
*err = 1;
return (NULL);
goto fail;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

@infrastation
Copy link
Copy Markdown
Member

Please make the commit message describe, using the conventional 72-column formatting, the problem(s) the commit fixes.

@guyharris
Copy link
Copy Markdown
Member

Ensures that when p->buffer is successfully expanded via realloc into a temporary pointer, the metadata (p->bufsize) is correctly updated to track the new capacity. This prevents stale size tracking and repeated, unnecessary reallocation attempts.

Wireshark has a data structure called a Buffer that includes a buffer pointer and a size, and has routines to expand a buffer to a certain size, so reallocating the data and updating the size are centralized. We should probably have something similar to that (but simpler, with only the buffer pointer and size - libpcap doesn't need the other stuff).

I'll look at that after this is merged.

We should probably backport this.

Reroute early error returns in pcap_ng_check_header() (e.g., unknown
timestamp precision or buffer allocation failures) through the
centralized 'goto fail' path. This ensures that ps->ifaces and
p->buffer are properly freed before returning NULL, preventing leaks.

In read_block(), ensure that when p->buffer is successfully expanded
via realloc() into a temporary pointer, the metadata (p->bufsize) is
correctly updated to track the new capacity. This prevents stale
size tracking and repeated, unnecessary reallocation attempts.
@Noamismach Noamismach force-pushed the c99-pcapng-hardening branch from 70a6aa2 to c6e5f63 Compare April 2, 2026 17:12
@Noamismach
Copy link
Copy Markdown
Author

@infrastation - Done. I've amended the commit message to include a detailed explanation of the fixes, wrapped at 72 columns, and force-pushed the update.

@guyharris - That makes total sense. Having a unified struct for the buffer and its capacity would definitely eliminate this entire class of state-tracking bugs natively. Glad this patch helps secure things in the meantime, and honored to hear it might be backported!

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants