journald: pin the sending client's context across native message dispatch
manager_process_native_message() looks up the sender's ClientContext with
client_context_get(), which does not pin it.
A native message may carry an OBJECT_PID=, which makes
manager_dispatch_message_real() perform a nested client_context_get() for that
PID. On a cache miss this runs client_context_try_shrink_to(), whose pid-flush
branch frees every unpinned cache entry whose PID has already been reaped,
including the borrowed sender context. manager_dispatch_message_real() then keeps
using it (it reads c->uid, and the built iovecs still alias the context's
fields).
Pin the sender context with client_context_acquire() for the duration of the
dispatch and release it afterwards, mirroring what the stdout stream path
already does.
Follow-up for 22e3a02b9d
This commit is contained in:
@@ -319,7 +319,10 @@ void manager_process_native_message(
|
||||
assert(buffer || buffer_size == 0);
|
||||
|
||||
if (ucred && pid_is_valid(ucred->pid)) {
|
||||
r = client_context_get(m, ucred->pid, ucred, label, /* unit_id= */ NULL, &context);
|
||||
/* Pin the sender's context for the whole dispatch below, as processing an entry may look up
|
||||
* further contexts (e.g. for an OBJECT_PID=), which can flush already reaped entries from
|
||||
* the cache */
|
||||
r = client_context_acquire(m, ucred->pid, ucred, label, /* unit_id= */ NULL, &context);
|
||||
if (r < 0)
|
||||
log_ratelimit_warning_errno(r, JOURNAL_LOG_RATELIMIT,
|
||||
"Failed to retrieve credentials for PID " PID_FMT ", ignoring: %m",
|
||||
@@ -331,6 +334,8 @@ void manager_process_native_message(
|
||||
(const uint8_t*) buffer + (buffer_size - remaining), &remaining,
|
||||
context, ucred, tv, label);
|
||||
} while (r == 0);
|
||||
|
||||
client_context_release(m, context);
|
||||
}
|
||||
|
||||
static size_t entry_size_max_by_ucred(Manager *m, const struct ucred *ucred, const char *label) {
|
||||
|
||||
Reference in New Issue
Block a user