From 7ad4d5a43e7e6098acfc28df7666efeb117d22dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 14 Apr 2020 21:06:23 +0100 Subject: [PATCH] linux-user: fix /proc/self/stat handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the original bug report long files names in Guix caused /proc/self/stat be truncated without the trailing ") " as specified in proc manpage which says: (2) comm %s The filename of the executable, in parentheses. This is visible whether or not the executable is swapped out. In the kernel this is currently done by do_task_stat calling proc_task_name() which uses a structure limited by TASK_COMM_LEN (16). Additionally it should only be reporting the executable name rather than the full path. Fix both these failings while cleaning up the code to use GString to build up the reported values. As the whole function is cleaned up also adjust the white space to the current coding style. Message-ID: Reported-by: Brice Goglin Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20200414200631.12799-10-alex.bennee@linaro.org> --- linux-user/syscall.c | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 6495ddc4cd..674f70e70a 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7295,34 +7295,29 @@ static int open_self_stat(void *cpu_env, int fd) { CPUState *cpu = env_cpu((CPUArchState *)cpu_env); TaskState *ts = cpu->opaque; - abi_ulong start_stack = ts->info->start_stack; + g_autoptr(GString) buf = g_string_new(NULL); int i; for (i = 0; i < 44; i++) { - char buf[128]; - int len; - uint64_t val = 0; + if (i == 0) { + /* pid */ + g_string_printf(buf, FMT_pid " ", getpid()); + } else if (i == 1) { + /* app name */ + gchar *bin = g_strrstr(ts->bprm->argv[0], "/"); + bin = bin ? bin + 1 : ts->bprm->argv[0]; + g_string_printf(buf, "(%.15s) ", bin); + } else if (i == 27) { + /* stack bottom */ + g_string_printf(buf, TARGET_ABI_FMT_ld " ", ts->info->start_stack); + } else { + /* for the rest, there is MasterCard */ + g_string_printf(buf, "0%c", i == 43 ? '\n' : ' '); + } - if (i == 0) { - /* pid */ - val = getpid(); - snprintf(buf, sizeof(buf), "%"PRId64 " ", val); - } else if (i == 1) { - /* app name */ - snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]); - } else if (i == 27) { - /* stack bottom */ - val = start_stack; - snprintf(buf, sizeof(buf), "%"PRId64 " ", val); - } else { - /* for the rest, there is MasterCard */ - snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' '); - } - - len = strlen(buf); - if (write(fd, buf, len) != len) { - return -1; - } + if (write(fd, buf->str, buf->len) != buf->len) { + return -1; + } } return 0;