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)); }