Skip to content

fix null pointer dereferences found by malloc-error-check cocci - #15552

Closed
kenifor wants to merge 8 commits into
OISF:mainfrom
kenifor:fix-null-deref-malloc-checks
Closed

fix null pointer dereferences found by malloc-error-check cocci#15552
kenifor wants to merge 8 commits into
OISF:mainfrom
kenifor:fix-null-deref-malloc-checks

Conversation

@kenifor

@kenifor kenifor commented Jun 4, 2026

Copy link
Copy Markdown

Summary

Fixed a broken regex in qa/coccinelle/malloc-error-check.cocci that caused the entire script to be a no-op, then addressed all unchecked allocations it surfaced.

cocci fix: identifier func =~ "(SCMalloc|...)" uses PCRE-style syntax, but Coccinelle uses OCaml Str where | and () are literal characters — @malloced never matched anything. Fixed by using SCMalloc\|SCStrdup\|... syntax.

allocation fixes (one commit each):

  • util/log-redis: guard SCCalloc result for redis_setup.stream_format
  • detect/alert: guard SCStrdup result before use
  • detect/flowbits: check SCRealloc result before overwriting the original pointer
  • detect/reference: guard both SCStrdup calls in DetectReferenceParse
  • util/mpm-hs: remove extra parentheses causing a false cocci negative; add guard in SCHSConfigInit
  • decode: make PacketInit return bool and propagate PacketAlertCreate failure through PacketGetFromAlloc instead of using FatalError on the packet path
  • tests/fuzz: guard SCCalloc result in fuzz_decodebase64 to avoid NULL dereference on OOM

Full src/*.c scan is clean after these changes.

This supersedes #15529 (rebased on current main, commits split per reviewer request).

Denis Balashov added 8 commits June 4, 2026 12:30
The identifier regex used PCRE-style '(A|B)' syntax, but Coccinelle
uses OCaml Str where '|' and '()' are literal characters. The
@malloced rule never matched any SC*alloc call, making the entire
script a no-op.

Replace all five identifier =~ patterns with the correct OCaml Str
alternation syntax 'A\|B'.
When Redis output is configured in stream/xadd mode with a positive
stream-maxlen, SCConfLogOpenRedis() allocates redis_setup.stream_format
and immediately passes it to snprintf().

If SCCalloc() fails, snprintf() receives a NULL destination pointer and
the process can crash during Redis output initialization. Handle this
unrecoverable setup failure with FatalError(), matching the surrounding
Redis initialization error handling.

Ticket: 8588
SCStrdup result was stored and immediately used without checking for
NULL, which would cause a NULL dereference if allocation fails.
The original pointer was overwritten with the SCRealloc result before
checking for NULL, causing a memory leak if reallocation fails.
Check the temporary pointer first before assigning.
Two SCStrdup calls that set ref->key had no NULL check. On allocation
failure the pointer would be used immediately, causing a NULL dereference.
Two fixes:
- Remove extra parentheses in existing NULL check: (*ext) -> *ext,
  which was causing the cocci script to miss the check as a false negative.
- Add a NULL check after SCCalloc in SCHSConfigInit; the return value
  was previously unguarded.
PacketAlertCreate is called from PacketInit on the packet allocation
path. Crashing the process on allocation failure is inappropriate here;
the caller should be able to drop the packet gracefully.

Make PacketInit return bool and propagate the NULL result from
PacketAlertCreate up through PacketGetFromAlloc, which already returns
NULL to signal allocation failure to its callers.

Update the four UNITTESTS-only helpers in defrag.c accordingly.
If SCCalloc fails, decoded is NULL and the subsequent SCBase64Decode
call would dereference it. Return early on allocation failure.
@kenifor
kenifor requested review from a team and victorjulien as code owners June 4, 2026 09:33
Comment thread src/util-mpm-hs.c
{
MpmConfig *c = SCCalloc(1, sizeof(MpmConfig));
if (unlikely(c == NULL)) {
FatalError("Failed to allocate MpmConfig");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You can return c, or return NULL, and caller handles it already

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.

You can return c, or return NULL, and caller handles it already

Addressed in #15560: SCHSConfigInit now returns SCCalloc() directly without an intermediate variable, so the caller in detect-engine.c handles the NULL check as it already did.

@catenacyber

Copy link
Copy Markdown
Contributor

Replaced by #15560

@catenacyber catenacyber closed this Jun 4, 2026
@codecov

codecov Bot commented Jun 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 53.57143% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.84%. Comparing base (0eda09f) to head (23bd1df).

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #15552      +/-   ##
==========================================
- Coverage   82.86%   82.84%   -0.03%     
==========================================
  Files         999      999              
  Lines      272627   272644      +17     
==========================================
- Hits       225904   225863      -41     
- Misses      46723    46781      +58     
Flag Coverage Δ
fuzzcorpus 61.47% <40.00%> (-0.01%) ⬇️
livemode 18.43% <26.66%> (+0.03%) ⬆️
netns 22.79% <26.66%> (-0.04%) ⬇️
pcap 45.15% <33.33%> (-0.06%) ⬇️
suricata-verify 66.56% <60.00%> (-0.02%) ⬇️
unittests 58.48% <39.28%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

2 participants