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:
@@ -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;
|
||||
|
||||
@@ -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, \
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user