From 534a73fd3ffe11e4eb9df05be83c61de651e4fb7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 9 Aug 2026 06:47:31 +0900 Subject: [PATCH] coredump: do not leak TID in the host to container PID, UID, and GID are converted by sending struct ucred, however, TID was not converted. Let's convert TID if corresponding pidfd exists, and discards TID otherwise. Fixes 4c7af7d9d1cd40e2f36a87787ce2fab32400bf89. --- src/coredump/coredump-context.c | 13 +++++++------ src/coredump/coredump-context.h | 3 ++- src/coredump/coredump-send.c | 10 ++++++++++ src/coredump/coredump-submit.c | 4 ++-- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/coredump/coredump-context.c b/src/coredump/coredump-context.c index 24d273499a..f7e978bbfc 100644 --- a/src/coredump/coredump-context.c +++ b/src/coredump/coredump-context.c @@ -48,6 +48,7 @@ void coredump_context_done(CoredumpContext *context) { assert(context); pidref_done(&context->pidref); + pidref_done(&context->tidref); free(context->hostname); free(context->comm); free(context->exe); @@ -266,8 +267,8 @@ int coredump_context_build_iovw(CoredumpContext *context) { if (r < 0) return log_error_errno(r, "Failed to add COREDUMP_COMM= field: %m"); - if (context->tid > 0) - (void) iovw_put_string_fieldf(&context->iovw, "COREDUMP_TID=", PID_FMT, context->tid); + if (pidref_is_set(&context->tidref)) + (void) iovw_put_string_fieldf(&context->iovw, "COREDUMP_TID=", PID_FMT, context->tidref.pid); if (context->thread_name) (void) iovw_put_string_field(&context->iovw, "COREDUMP_THREAD_NAME=", context->thread_name); @@ -383,10 +384,10 @@ static int coredump_context_parse_from_procfs(CoredumpContext *context) { if (r < 0) return log_error_errno(r, "Failed to get COMM: %m"); - if (context->tid > 0) { - r = pid_get_comm(context->tid, &context->thread_name); + if (pidref_is_set(&context->tidref)) { + r = pidref_get_comm(&context->tidref, &context->thread_name); if (r < 0) - log_warning_errno(r, "Failed to get comm for thread "PID_FMT", ignoring: %m", context->tid); + log_warning_errno(r, "Failed to get comm for thread "PID_FMT", ignoring: %m", context->tidref.pid); } r = get_process_exe(pid, &context->exe); @@ -518,7 +519,7 @@ static int context_parse_one(CoredumpContext *context, MetadataField meta, bool return 0; } case META_ARGV_TID: - r = parse_pid(s, &context->tid); + r = pidref_set_pidstr_full(&context->tidref, s, PIDFD_THREAD); if (r < 0) log_warning_errno(r, "Failed to parse TID \"%s\", ignoring: %m", s); return 0; diff --git a/src/coredump/coredump-context.h b/src/coredump/coredump-context.h index a2ce16b853..ee4334dce2 100644 --- a/src/coredump/coredump-context.h +++ b/src/coredump/coredump-context.h @@ -57,7 +57,7 @@ struct CoredumpContext { uint64_t rlimit; /* META_ARGV_RLIMIT */ char *hostname; /* META_ARGV_HOSTNAME */ unsigned dumpable; /* META_ARGV_DUMPABLE */ - pid_t tid; /* META_ARGV_TID */ + PidRef tidref; /* META_ARGV_TID */ char *comm; /* META_COMM */ char *exe; /* META_EXE */ char *unit; /* META_UNIT */ @@ -78,6 +78,7 @@ struct CoredumpContext { .pidref = PIDREF_NULL, \ .uid = UID_INVALID, \ .gid = GID_INVALID, \ + .tidref = PIDREF_NULL, \ .mount_tree_fd = -EBADF, \ .input_fd = -EBADF, \ } diff --git a/src/coredump/coredump-send.c b/src/coredump/coredump-send.c index 4817d82611..5b77301206 100644 --- a/src/coredump/coredump-send.c +++ b/src/coredump/coredump-send.c @@ -301,6 +301,16 @@ int coredump_send_to_container(CoredumpContext *context) { context->uid = ucred.uid; context->gid = ucred.gid; + /* Do not leak the TID in the initial PID namespace. */ + int tidfd = TAKE_FD(context->tidref.fd); + pid_t tid = context->tidref.pid; + context->tidref = PIDREF_NULL; + if (tidfd >= 0) { + r = pidref_set_pidfd_consume(&context->tidref, tidfd); + if (r < 0) + log_warning_errno(r, "Failed to acquire PidRef of TID ["PID_FMT"], ignoring: %m", tid); + } + r = coredump_context_build_iovw(context); if (r < 0) _exit(EXIT_FAILURE); diff --git a/src/coredump/coredump-submit.c b/src/coredump/coredump-submit.c index fe1042ce4a..55f8b6e9e1 100644 --- a/src/coredump/coredump-submit.c +++ b/src/coredump/coredump-submit.c @@ -201,8 +201,8 @@ static int fix_xattr(int fd, const CoredumpContext *context) { RET_GATHER(r, fix_xattr_one(fd, "user.coredump.hostname", context->hostname)); RET_GATHER(r, fix_xattr_one(fd, "user.coredump.comm", context->comm)); RET_GATHER(r, fix_xattr_one(fd, "user.coredump.exe", context->exe)); - if (context->tid > 0) { - RET_GATHER(r, fix_xattr_format(fd, "user.coredump.tid", PID_FMT, context->tid)); + if (pidref_is_set(&context->tidref)) { + RET_GATHER(r, fix_xattr_format(fd, "user.coredump.tid", PID_FMT, context->tidref.pid)); RET_GATHER(r, fix_xattr_one(fd, "user.coredump.thread_name", context->thread_name)); }