From 402a5d109ff6e6946955608a027c4247003c64dd Mon Sep 17 00:00:00 2001 From: BritishTeapot Date: Sat, 12 Apr 2025 18:44:20 +0200 Subject: [PATCH] Fixed incorrect executable path problem. Previously, process name was grabbed from `/proc/pid/cmdline`. This was revealed to be faulty, since the path to the executable might be relative, and thus would change the result depending on how the program was called. Also, it made executable renaming a viable bypass of the entire access control. I still don't fully undestand how I managed to not think of this before :) --- src/fuse_operations.c | 63 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/src/fuse_operations.c b/src/fuse_operations.c index 0df92d6..6d29052 100644 --- a/src/fuse_operations.c +++ b/src/fuse_operations.c @@ -11,6 +11,7 @@ See the file LICENSE. */ +#include #define FUSE_USE_VERSION 31 #define _GNU_SOURCE @@ -40,22 +41,57 @@ #include "ui-socket.h" const char *get_process_name_by_pid(const int pid) { - char *name = (char *)calloc(1024, sizeof(char)); - if (name) { - sprintf(name, "/proc/%d/cmdline", pid); - FILE *file = fopen(name, "r"); - if (file) { - size_t size = 0; - size = fread(name, sizeof(char), 1024, file); - if (size > 0) { - if ('\n' == name[size - 1]) { - name[size - 1] = '\0'; - } - } - fclose(file); + char path[1024]; + sprintf(path, "/proc/%d/exe", pid); + + char *name = realpath(path, NULL); + if (name == NULL) { + fprintf(stderr, "Could not get process name by pid %d", pid); + perror(""); + } + + /* + size_t namelen = 32; + ssize_t readret = 0; + char *name = NULL; + while (namelen >= (size_t)readret && readret > 0) { + namelen *= 2; + name = calloc(namelen, sizeof(char)); + if (name == NULL) { + free(path); + fprintf(stderr, "Could not get get process name by pid %d", pid); + perror(""); + return NULL; + } + readret = readlink(path, name, namelen); + if (readret < 0) { + free(name); + free(path); + fprintf(stderr, "Couldn't get process name by pid %d", pid); + perror(""); + return NULL; + } + if (namelen >= (size_t)readret) { + free(name); } } + */ + return name; + + /* + FILE *file = fopen(path, "r"); + if (file) { + size_t size = 0; + size = fread(path, sizeof(char), 1024, file); + if (size > 0) { + if ('\n' == path[size - 1]) { + path[size - 1] = '\0'; + } + } + fclose(file); + } + */ } // TODO: move this somewhere else @@ -83,6 +119,7 @@ static void *xmp_init(struct fuse_conn_info *conn, struct fuse_config *cfg) { cfg->entry_timeout = 0; cfg->attr_timeout = 0; cfg->negative_timeout = 0; + fprintf(stderr, "%d\n", getpid()); return NULL; }