Compare commits

..

6 Commits

Author SHA1 Message Date
Yu Watanabe 6f191822cf
Merge c5a35d3ea9 into f6793bbcf0 2024-11-20 20:01:18 +01:00
Lennart Poettering f6793bbcf0 killall: gracefully handle processes inserted into containers via nsenter -a
"nsenter -a" doesn't migrate the specified process into the target
cgroup (it really should). Thus the cgroup will remain in a cgroup
that is (due to cgroup ns) outside our visibility. The kernel will
report the cgroup path of such cgroups as starting with "/../". Detect
that and print a reasonably error message instead of trying to resolve
that.
2024-11-20 18:11:38 +00:00
Mike Yuan f87863a8ff process-util: refuse to operate on remote PidRef
Follow-up for 7e3e540b88
2024-11-20 18:10:26 +00:00
Antonio Alvarez Feijoo 58c3c2886d cryptenroll: fix typo 2024-11-20 18:03:44 +00:00
Daan De Meyer dbbe895807 test-audit-util: Migrate to new assertion macros 2024-11-20 16:48:55 +00:00
Yu Watanabe c5a35d3ea9 journalctl: do not override explicitly specified -b or -n with -e or -k
Fixes #35248.
2024-11-20 23:16:37 +09:00
7 changed files with 52 additions and 19 deletions

View File

@ -475,9 +475,7 @@
<term><option>--dmesg</option></term> <term><option>--dmesg</option></term>
<listitem><para>Show only kernel messages. This adds the match <literal>_TRANSPORT=kernel</literal>. <listitem><para>Show only kernel messages. This adds the match <literal>_TRANSPORT=kernel</literal>.
This implies <option>--boot=0</option>, while the implication is overridden by specifying This implies <option>--boot=0</option> unless explicitly specified otherwise.</para>
<option>--boot=</option> with some boot specification, especially <option>--boot=all</option> will
disables the implication.</para>
<xi:include href="version-info.xml" xpointer="v205"/></listitem> <xi:include href="version-info.xml" xpointer="v205"/></listitem>
</varlistentry> </varlistentry>
@ -811,11 +809,9 @@
<term><option>--pager-end</option></term> <term><option>--pager-end</option></term>
<listitem><para>Immediately jump to the end of the journal inside the implied pager tool. This <listitem><para>Immediately jump to the end of the journal inside the implied pager tool. This
implies <option>--lines=1000</option> and <option>--boot=0</option> to guarantee that the pager will implies <option>--lines=1000</option> and <option>--boot=0</option> unless explicitly specified
not buffer logs of unbounded size. This may be overridden with an explicit <option>--lines=</option> otherwise, to guarantee that the pager will not buffer logs of unbounded size. Note that this option
with some other numeric value and/or <option>--boot=</option> with some specific boot specification, is only supported for the
while <option>--lines=all</option> and <option>--boot=all</option> will disable the implications.
Note that this option is only supported for the
<citerefentry project='man-pages'><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry> <citerefentry project='man-pages'><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry>
pager.</para> pager.</para>

View File

@ -803,6 +803,10 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **ret_path) {
if (!path) if (!path)
return -ENOMEM; return -ENOMEM;
/* Refuse cgroup paths from outside our cgroup namespace */
if (startswith(path, "/../"))
return -EUNATCH;
/* Truncate suffix indicating the process is a zombie */ /* Truncate suffix indicating the process is a zombie */
e = endswith(path, " (deleted)"); e = endswith(path, " (deleted)");
if (e) if (e)

View File

@ -102,8 +102,8 @@ int pid_get_comm(pid_t pid, char **ret) {
_cleanup_free_ char *escaped = NULL, *comm = NULL; _cleanup_free_ char *escaped = NULL, *comm = NULL;
int r; int r;
assert(ret);
assert(pid >= 0); assert(pid >= 0);
assert(ret);
if (pid == 0 || pid == getpid_cached()) { if (pid == 0 || pid == getpid_cached()) {
comm = new0(char, TASK_COMM_LEN + 1); /* Must fit in 16 byte according to prctl(2) */ comm = new0(char, TASK_COMM_LEN + 1); /* Must fit in 16 byte according to prctl(2) */
@ -143,6 +143,9 @@ int pidref_get_comm(const PidRef *pid, char **ret) {
if (!pidref_is_set(pid)) if (!pidref_is_set(pid))
return -ESRCH; return -ESRCH;
if (pidref_is_remote(pid))
return -EREMOTE;
r = pid_get_comm(pid->pid, &comm); r = pid_get_comm(pid->pid, &comm);
if (r < 0) if (r < 0)
return r; return r;
@ -289,6 +292,9 @@ int pidref_get_cmdline(const PidRef *pid, size_t max_columns, ProcessCmdlineFlag
if (!pidref_is_set(pid)) if (!pidref_is_set(pid))
return -ESRCH; return -ESRCH;
if (pidref_is_remote(pid))
return -EREMOTE;
r = pid_get_cmdline(pid->pid, max_columns, flags, &s); r = pid_get_cmdline(pid->pid, max_columns, flags, &s);
if (r < 0) if (r < 0)
return r; return r;
@ -331,6 +337,9 @@ int pidref_get_cmdline_strv(const PidRef *pid, ProcessCmdlineFlags flags, char *
if (!pidref_is_set(pid)) if (!pidref_is_set(pid))
return -ESRCH; return -ESRCH;
if (pidref_is_remote(pid))
return -EREMOTE;
r = pid_get_cmdline_strv(pid->pid, flags, &args); r = pid_get_cmdline_strv(pid->pid, flags, &args);
if (r < 0) if (r < 0)
return r; return r;
@ -477,6 +486,9 @@ int pidref_is_kernel_thread(const PidRef *pid) {
if (!pidref_is_set(pid)) if (!pidref_is_set(pid))
return -ESRCH; return -ESRCH;
if (pidref_is_remote(pid))
return -EREMOTE;
result = pid_is_kernel_thread(pid->pid); result = pid_is_kernel_thread(pid->pid);
if (result < 0) if (result < 0)
return result; return result;
@ -594,6 +606,9 @@ int pidref_get_uid(const PidRef *pid, uid_t *ret) {
if (!pidref_is_set(pid)) if (!pidref_is_set(pid))
return -ESRCH; return -ESRCH;
if (pidref_is_remote(pid))
return -EREMOTE;
r = pid_get_uid(pid->pid, &uid); r = pid_get_uid(pid->pid, &uid);
if (r < 0) if (r < 0)
return r; return r;
@ -794,6 +809,9 @@ int pidref_get_start_time(const PidRef *pid, usec_t *ret) {
if (!pidref_is_set(pid)) if (!pidref_is_set(pid))
return -ESRCH; return -ESRCH;
if (pidref_is_remote(pid))
return -EREMOTE;
r = pid_get_start_time(pid->pid, ret ? &t : NULL); r = pid_get_start_time(pid->pid, ret ? &t : NULL);
if (r < 0) if (r < 0)
return r; return r;
@ -1093,6 +1111,9 @@ int pidref_is_my_child(const PidRef *pid) {
if (!pidref_is_set(pid)) if (!pidref_is_set(pid))
return -ESRCH; return -ESRCH;
if (pidref_is_remote(pid))
return -EREMOTE;
result = pid_is_my_child(pid->pid); result = pid_is_my_child(pid->pid);
if (result < 0) if (result < 0)
return result; return result;
@ -1128,6 +1149,9 @@ int pidref_is_unwaited(const PidRef *pid) {
if (!pidref_is_set(pid)) if (!pidref_is_set(pid))
return -ESRCH; return -ESRCH;
if (pidref_is_remote(pid))
return -EREMOTE;
if (pid->pid == 1 || pidref_is_self(pid)) if (pid->pid == 1 || pidref_is_self(pid))
return true; return true;
@ -1169,6 +1193,9 @@ int pidref_is_alive(const PidRef *pidref) {
if (!pidref_is_set(pidref)) if (!pidref_is_set(pidref))
return -ESRCH; return -ESRCH;
if (pidref_is_remote(pidref))
return -EREMOTE;
result = pid_is_alive(pidref->pid); result = pid_is_alive(pidref->pid);
if (result < 0) { if (result < 0) {
assert(result != -ESRCH); assert(result != -ESRCH);

View File

@ -193,7 +193,7 @@ int enroll_fido2(
fflush(stdout); fflush(stdout);
fprintf(stderr, fprintf(stderr,
"\nPlease save this FIDO2 credential ID. It is required when unloocking the volume\n" "\nPlease save this FIDO2 credential ID. It is required when unlocking the volume\n"
"using the associated FIDO2 keyslot which we just created. To configure automatic\n" "using the associated FIDO2 keyslot which we just created. To configure automatic\n"
"unlocking using this FIDO2 token, add an appropriate entry to your /etc/crypttab\n" "unlocking using this FIDO2 token, add an appropriate entry to your /etc/crypttab\n"
"file, see %s for details.\n", link); "file, see %s for details.\n", link);

View File

@ -990,7 +990,7 @@ static int parse_argv(int argc, char *argv[]) {
if (arg_boot < 0) if (arg_boot < 0)
/* Show the current boot if -f/--follow, -k/--dmesg, or -e/--pager-end is specified unless /* Show the current boot if -f/--follow, -k/--dmesg, or -e/--pager-end is specified unless
* -m/--merge is unspecified. */ * -m/--merge is specified. */
arg_boot = !arg_merge && (arg_follow || arg_dmesg || FLAGS_SET(arg_pager_flags, PAGER_JUMP_TO_END)); arg_boot = !arg_merge && (arg_follow || arg_dmesg || FLAGS_SET(arg_pager_flags, PAGER_JUMP_TO_END));
if (!arg_boot) { if (!arg_boot) {
/* Clear the boot ID and offset if -b/--boot is unspecified for safety. */ /* Clear the boot ID and offset if -b/--boot is unspecified for safety. */

View File

@ -46,13 +46,17 @@ static bool argv_has_at(pid_t pid) {
return c == '@'; return c == '@';
} }
static bool is_survivor_cgroup(const PidRef *pid) { static bool is_in_survivor_cgroup(const PidRef *pid) {
_cleanup_free_ char *cgroup_path = NULL; _cleanup_free_ char *cgroup_path = NULL;
int r; int r;
assert(pidref_is_set(pid)); assert(pidref_is_set(pid));
r = cg_pidref_get_path(/* root= */ NULL, pid, &cgroup_path); r = cg_pidref_get_path(/* root= */ NULL, pid, &cgroup_path);
if (r == -EUNATCH) {
log_warning_errno(r, "Process " PID_FMT " appears to originate in foreign namespace, ignoring.", pid->pid);
return true;
}
if (r < 0) { if (r < 0) {
log_warning_errno(r, "Failed to get cgroup path of process " PID_FMT ", ignoring: %m", pid->pid); log_warning_errno(r, "Failed to get cgroup path of process " PID_FMT ", ignoring: %m", pid->pid);
return false; return false;
@ -86,7 +90,7 @@ static bool ignore_proc(const PidRef *pid, bool warn_rootfs) {
return true; /* also ignore processes where we can't determine this */ return true; /* also ignore processes where we can't determine this */
/* Ignore processes that are part of a cgroup marked with the user.survive_final_kill_signal xattr */ /* Ignore processes that are part of a cgroup marked with the user.survive_final_kill_signal xattr */
if (is_survivor_cgroup(pid)) if (is_in_survivor_cgroup(pid))
return true; return true;
r = pidref_get_uid(pid, &uid); r = pidref_get_uid(pid, &uid);

View File

@ -7,24 +7,26 @@ TEST(audit_loginuid_from_pid) {
_cleanup_(pidref_done) PidRef self = PIDREF_NULL, pid1 = PIDREF_NULL; _cleanup_(pidref_done) PidRef self = PIDREF_NULL, pid1 = PIDREF_NULL;
int r; int r;
assert_se(pidref_set_self(&self) >= 0); ASSERT_OK(pidref_set_self(&self));
assert_se(pidref_set_pid(&pid1, 1) >= 0); ASSERT_OK(pidref_set_pid(&pid1, 1));
uid_t uid; uid_t uid;
r = audit_loginuid_from_pid(&self, &uid); r = audit_loginuid_from_pid(&self, &uid);
assert_se(r >= 0 || r == -ENODATA); if (r != -ENODATA)
ASSERT_OK(r);
if (r >= 0) if (r >= 0)
log_info("self audit login uid: " UID_FMT, uid); log_info("self audit login uid: " UID_FMT, uid);
assert_se(audit_loginuid_from_pid(&pid1, &uid) == -ENODATA); ASSERT_ERROR(audit_loginuid_from_pid(&pid1, &uid), ENODATA);
uint32_t sessionid; uint32_t sessionid;
r = audit_session_from_pid(&self, &sessionid); r = audit_session_from_pid(&self, &sessionid);
assert_se(r >= 0 || r == -ENODATA); if (r != -ENODATA)
ASSERT_OK(r);
if (r >= 0) if (r >= 0)
log_info("self audit session id: %" PRIu32, sessionid); log_info("self audit session id: %" PRIu32, sessionid);
assert_se(audit_session_from_pid(&pid1, &sessionid) == -ENODATA); ASSERT_ERROR(audit_session_from_pid(&pid1, &sessionid), ENODATA);
} }
static int intro(void) { static int intro(void) {