Skip to content

redis: guard stream format allocation - #15423

Closed
kenifor wants to merge 4 commits into
OISF:mainfrom
kenifor:fix-redis-stream-format-alloc
Closed

redis: guard stream format allocation#15423
kenifor wants to merge 4 commits into
OISF:mainfrom
kenifor:fix-redis-stream-format-alloc

Conversation

@kenifor

@kenifor kenifor commented May 20, 2026

Copy link
Copy Markdown

Ticket: 8588

Make sure these boxes are checked accordingly before submitting your Pull Request -- thank you.

Contribution style:

Our Contribution agreements:

Changes (if applicable):

Link to ticket: https://redmine.openinfosecfoundation.org/issues/8588

Describe changes:

  • Check the Redis stream format allocation before passing it to snprintf().
  • Use FatalError() for this unrecoverable Redis output initialization failure, matching the existing Redis setup error handling style.
  • Prevent a NULL pointer dereference when Redis stream/xadd mode is configured with a positive stream-maxlen and memory allocation fails.

Provide values to any of the below to override the defaults.

  • To use a Suricata-Verify or Suricata-Update pull request,
    link to the pull request in the respective _BRANCH variable.
  • Leave unused overrides blank or remove.

SV_REPO=
SV_BRANCH=
SU_REPO=
SU_BRANCH=

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
@kenifor
kenifor requested a review from victorjulien as a code owner May 20, 2026 09:08
@victorjulien victorjulien added the cla required The author has not yet signed the CLA or CLA signing is pending verification label May 20, 2026
@codecov

codecov Bot commented May 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.76%. Comparing base (bb4e79c) to head (3ca8259).
⚠️ Report is 189 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #15423      +/-   ##
==========================================
+ Coverage   82.65%   82.76%   +0.11%     
==========================================
  Files         996      999       +3     
  Lines      271109   272666    +1557     
==========================================
+ Hits       224076   225674    +1598     
+ Misses      47033    46992      -41     
Flag Coverage Δ
fuzzcorpus 61.43% <ø> (+0.40%) ⬆️
livemode 18.31% <ø> (-0.06%) ⬇️
netns 22.70% <ø> (+0.09%) ⬆️
pcap 44.93% <ø> (-0.29%) ⬇️
suricata-verify 66.40% <ø> (-0.01%) ⬇️
unittests 58.41% <ø> (-0.15%) ⬇️

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.

Comment thread src/util-log-redis.c
format string, whose length is limited by the length of the
maxlen integer formatted as a string */
log_ctx->redis_setup.stream_format = SCCalloc(100, sizeof(char));
if (unlikely(log_ctx->redis_setup.stream_format == NULL)) {

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.

Why was this not caught by cocci ? ./qa/coccinelle/malloc-error-check.cocci

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.

Good catch. The script missed it because of how ... when != x works
in Coccinelle: it excludes statements that assign to x, but not
statements that use x as an argument — so snprintf(x, ...) and
format = x both pass through the ... without triggering the
constraint. Combined with the exists semantics and the allocation
being inside a nested if (maxlen > 0), Coccinelle does not flag the
missing NULL check.

The fix we applied (adding the if (unlikely(...)) guard before the
snprintf) matches the @istested pattern and would be caught
correctly going forward. Let us know if you'd like us to also add a
test case to the cocci script to prevent similar gaps.

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.

Could we fix the cocci script then ?

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.

Could we fix the cocci script then ?

Fixed in 4111d98. The root cause: ... when != x in @istested only
excludes statements that reassign x, not statements that use x
as a function argument. So snprintf(x, ...) passed through the ...
undetected.

Added when != callee(..., x, ...) to the constraint so that any use
of the allocated pointer as a function argument before a NULL check
prevents @istested from matching — causing the script to correctly
flag the violation.

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.

Thanks, checking with #15508 that this cocci change is good

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.

@catenacyber

Copy link
Copy Markdown
Contributor

Also, we need you yo sign the CLA https://suricata.io/about/contribution-agreement/ to be able to accept your contribution

…unction args

The @istested rule's '... when != x' only excluded reassignments of x,
not statements that passed x as a function argument. Add
'when != callee(..., x, ...)' so that any use of the allocated pointer
as a function argument before a NULL check is no longer treated as
tested and is correctly flagged.
@kenifor
kenifor requested a review from a team as a code owner May 28, 2026 14:11
@kenifor

kenifor commented May 28, 2026

Copy link
Copy Markdown
Author

Also, we need you yo sign the CLA https://suricata.io/about/contribution-agreement/ to be able to accept your contribution

yes, I signed it now

@github-actions

Copy link
Copy Markdown

NOTE: This PR may contain new authors.

@catenacyber catenacyber left a comment

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.

The identifier regex used PCRE-style '(A|B)' syntax, but Coccinelle
uses OCaml Str where '|' is a literal character. Replace with 'A\|B'
so the pattern correctly matches all SC*alloc functions.
@kenifor

kenifor commented Jun 2, 2026

Copy link
Copy Markdown
Author

The cocci commit does not work : see https://github.com/OISF/suricata/actions/runs/26811739736/job/79043416837?pr=15508 from #15508

Fixed in 3ca8259. The root cause was deeper: the entire script was a no-op because identifier =~ "(SCMalloc|SCCalloc|...)" uses PCRE-style syntax, but Coccinelle uses OCaml Str where | and () are literal characters — so @malloced never matched anything.

Fixed by replacing all (A|B) patterns with A\|B (OCaml Str alternation). After this fix the script correctly catches the missing null check: exit 1 on the buggy code, exit 0 on the fixed version.

@catenacyber

Copy link
Copy Markdown
Contributor

Cool, but now we see more reports like

Structure malloced at ../../src/detect-reference.c:155 but error is not checked.

Could you fix them also ?

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

NOTE: This PR may contain new authors.

- decode: replace DEBUG_VALIDATE_BUG_ON with FatalError in PacketAlertCreate
- detect-engine-alert: guard SCStrdup result before use
- detect-flowbits: check SCRealloc result before overwriting original pointer
- detect-reference: guard SCStrdup results in DetectReferenceParse
- util-mpm-hs: fix false cocci negative (remove extra parens), add
  FatalError in SCHSConfigInit
@kenifor

kenifor commented Jun 3, 2026

Copy link
Copy Markdown
Author

Cool, but now we see more reports like

Structure malloced at ../../src/detect-reference.c:155 but error is not checked.

Could you fix them also ?

Fixed in 207594e. The repaired cocci script surfaced 6 unchecked allocations across 5 files:

  • decode.c: replaced DEBUG_VALIDATE_BUG_ON with FatalError in PacketAlertCreate
  • detect-engine-alert.c: guard SCStrdup result before use
  • detect-flowbits.c: check SCRealloc result before overwriting the original pointer
  • detect-reference.c: guard both SCStrdup calls in DetectReferenceParse
  • util-mpm-hs.c: remove extra parentheses in existing check (false negative), add FatalError in SCHSConfigInit

Full scan of src/*.c is now clean.

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

Closing this pull request: its branch was updated after the pull
request was opened.

Per our workflow, a new pull request is required when changes are made
to an existing one. Please open a new pull request with the updated
changes.

If you wish to create an in progress pull request that you can push to,
please create a draft pull request.

Please see our GitHub Pull Request Workflow.

@kenifor

kenifor commented Jun 3, 2026

Copy link
Copy Markdown
Author

Cool, but now we see more reports like

Structure malloced at ../../src/detect-reference.c:155 but error is not checked.

Could you fix them also ?

Continued in #15529 (PR was auto-closed after branch update per the workflow policy).

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

Labels

cla required The author has not yet signed the CLA or CLA signing is pending verification

Development

Successfully merging this pull request may close these issues.

3 participants