mirror of
https://github.com/systemd/systemd.git
synced 2025-03-31 14:50:15 +03:00
util-lib: do not truncate kernel comm names
It turns out that the kernel allows comm names higher than our expected limit of 16. $ wc -c /proc/*/comm|sort -g|tail -n3 35 /proc/1292317/comm 35 /proc/1293610/comm 36 /proc/1287112/comm $ cat /proc/1287112/comm kworker/u9:3-kcryptd/253:0
This commit is contained in:
parent
bc28751ed2
commit
0e85cbcfc3
@ -46,6 +46,11 @@
|
||||
#include "user-util.h"
|
||||
#include "utf8.h"
|
||||
|
||||
/* The kernel limits userspace processes to TASK_COMM_LEN (16 bytes), but allows higher values for its own
|
||||
* workers, e.g. "kworker/u9:3-kcryptd/253:0". Let's pick a fixed smallish limit that will work for the kernel.
|
||||
*/
|
||||
#define COMM_MAX_LEN 128
|
||||
|
||||
static int get_process_state(pid_t pid) {
|
||||
const char *p;
|
||||
char state;
|
||||
@ -82,7 +87,7 @@ int get_process_comm(pid_t pid, char **ret) {
|
||||
assert(ret);
|
||||
assert(pid >= 0);
|
||||
|
||||
escaped = new(char, TASK_COMM_LEN);
|
||||
escaped = new(char, COMM_MAX_LEN);
|
||||
if (!escaped)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -95,7 +100,7 @@ int get_process_comm(pid_t pid, char **ret) {
|
||||
return r;
|
||||
|
||||
/* Escape unprintable characters, just in case, but don't grow the string beyond the underlying size */
|
||||
cellescape(escaped, TASK_COMM_LEN, comm);
|
||||
cellescape(escaped, COMM_MAX_LEN, comm);
|
||||
|
||||
*ret = TAKE_PTR(escaped);
|
||||
return 0;
|
||||
@ -209,7 +214,7 @@ int rename_process(const char name[]) {
|
||||
* can use PR_SET_NAME, which sets the thread name for the calling thread. */
|
||||
if (prctl(PR_SET_NAME, name) < 0)
|
||||
log_debug_errno(errno, "PR_SET_NAME failed: %m");
|
||||
if (l >= TASK_COMM_LEN) /* Linux process names can be 15 chars at max */
|
||||
if (l >= TASK_COMM_LEN) /* Linux userspace process names can be 15 chars at max */
|
||||
truncated = true;
|
||||
|
||||
/* Second step, change glibc's ID of the process name. */
|
||||
|
@ -107,12 +107,12 @@ static void test_get_process_comm_escape(void) {
|
||||
test_get_process_comm_escape_one("foo", "foo");
|
||||
test_get_process_comm_escape_one("012345678901234", "012345678901234");
|
||||
test_get_process_comm_escape_one("0123456789012345", "012345678901234");
|
||||
test_get_process_comm_escape_one("äöüß", "\\303\\244\\303…");
|
||||
test_get_process_comm_escape_one("xäöüß", "x\\303\\244…");
|
||||
test_get_process_comm_escape_one("xxäöüß", "xx\\303\\244…");
|
||||
test_get_process_comm_escape_one("xxxäöüß", "xxx\\303\\244…");
|
||||
test_get_process_comm_escape_one("xxxxäöüß", "xxxx\\303\\244…");
|
||||
test_get_process_comm_escape_one("xxxxxäöüß", "xxxxx\\303…");
|
||||
test_get_process_comm_escape_one("äöüß", "\\303\\244\\303\\266\\303\\274\\303\\237");
|
||||
test_get_process_comm_escape_one("xäöüß", "x\\303\\244\\303\\266\\303\\274\\303\\237");
|
||||
test_get_process_comm_escape_one("xxäöüß", "xx\\303\\244\\303\\266\\303\\274\\303\\237");
|
||||
test_get_process_comm_escape_one("xxxäöüß", "xxx\\303\\244\\303\\266\\303\\274\\303\\237");
|
||||
test_get_process_comm_escape_one("xxxxäöüß", "xxxx\\303\\244\\303\\266\\303\\274\\303\\237");
|
||||
test_get_process_comm_escape_one("xxxxxäöüß", "xxxxx\\303\\244\\303\\266\\303\\274\\303\\237");
|
||||
|
||||
assert_se(prctl(PR_SET_NAME, saved) >= 0);
|
||||
}
|
||||
@ -407,6 +407,8 @@ static void test_rename_process_now(const char *p, int ret) {
|
||||
assert_se(get_process_comm(0, &comm) >= 0);
|
||||
log_info("comm = <%s>", comm);
|
||||
assert_se(strneq(comm, p, TASK_COMM_LEN-1));
|
||||
/* We expect comm to be at most 16 bytes (TASK_COMM_LEN). The kernel may raise this limit in the
|
||||
* future. We'd only check the initial part, at least until we recompile, but this will still pass. */
|
||||
|
||||
r = get_process_cmdline(0, SIZE_MAX, false, &cmdline);
|
||||
assert_se(r >= 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user