rsyslog: fix imjournal ratelimiter data race

imjournal keeps one module-global ratelimiter but runs one reader thread
per journal: every configured input() plus the implicit listener that
activateCnf() unconditionally adds via addListner(NULL, ...). All of
them call ratelimitAddMsg() on that single object, yet the module
never calls ratelimitSetThreadSafe(), so bThreadSafe stays 0 and
every lock in runtime/ratelimit.c is skipped.

With $RepeatedMsgReduction disabled this only races on scalar counters
in withinRatelimit() and merely yields imprecise numbers. Enabling the
directive additionally activates doLastMessageRepeatedNTimes(), which
mutates the shared ratelimit->pMsg pointer: one thread can free that
message in msgDestruct() while another is still dereferencing it in the
duplicate comparison. Message refcounts are atomic, so the count itself
does not tear, but nothing protects the pointer, and the result is a
use-after-free.

This is not fixed upstream: rsyslog master still never calls
ratelimitSetThreadSafe() from imjournal and still gates all locking on
bThreadSafe, so an uprev does not help.

ratelimitSetNoTimeCache() already calls pthread_mutex_init() on the same
mutex, so no extra initialisation is needed. The duplicate init inside
ratelimitSetThreadSafe() is harmless because runInput() runs before any
reader thread is spawned.

Needed before $RepeatedMsgReduction can be enabled; see the
gbmc-internal change enabling it in meta-google-gbmc/.../client.conf.

Tested: built for an armv7l gBMC target and deployed the patched
imjournal.so to a test BMC. The plugin loads cleanly (no undefined
symbols, both in:imjournal threads present) and duplicate suppression
still works -- 6 identical messages are reported as "message repeated
11 times", the expected 2N-1 for two readers sharing one ratelimiter.

Crash reproduction, 6000-message rounds with $RepeatedMsgReduction on:

  unpatched, 24000 messages: 3 SIGSEGV, coredumps, rsyslog.service
      "Main process exited, code=killed, status=11/SEGV"
  unpatched, RMR off, 28000 messages: 0 crashes
  patched, 48000 messages over two runs: 0 crashes, 0 restarts,
      0 coredumps

BMC restored to its original imjournal.so and config after each run
(md5 match, service active).

Fusion-Link: fusion2 N/A
Google-Bug-Id: 561749907
Change-Id: Ibc687516f5fc3fa897ba362eefae034a67c3c97f
Signed-off-by: Eyal Ron <eyalron@google.com>
TAG=agy
CONV=31661fa9-028b-493b-8dec-1c801e2b0023
2 files changed
tree: 1e5573981861e7238bc0e70e56ded08c6b42c60d
  1. classes/
  2. conf/
  3. dynamic-layers/
  4. recipes-benchmark/
  5. recipes-bsp/
  6. recipes-connectivity/
  7. recipes-core/
  8. recipes-devtools/
  9. recipes-extended/
  10. recipes-google/
  11. recipes-kernel/
  12. recipes-phosphor/
  13. recipes-support/
  14. recipes-tpm1/
  15. recipes-tpm2/
  16. recipes-x86/
  17. LICENSE
  18. README.md
README.md

meta-gbmc-staging

This repository contains additions to the openbmc/meta-google layer that are not yet ready for OpenBMC inclusion.

How to use this layer

  1. Clone openbmc/openbmc from GitHub.
  2. Clone this layer from GitHub into a subdirectory of openbmc.