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 4c7af7d9d1.
This commit is contained in:
Yu Watanabe
2026-08-15 00:11:59 +09:00
parent 918f1462d7
commit 534a73fd3f
4 changed files with 21 additions and 9 deletions
+7 -6
View File
@@ -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;
+2 -1
View File
@@ -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, \
}
+10
View File
@@ -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);
+2 -2
View File
@@ -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));
}