diff --git a/Makefile b/Makefile index 0c8386f..b934d76 100644 --- a/Makefile +++ b/Makefile @@ -70,7 +70,7 @@ default: $(TARGETS) $(BUILD_DIR)/icfs_dialogue: make -C $(SOURCES_DIR)/gui TEST=$(TEST) DEBUG=$(shell realpath $(DEBUG)) SOURCES_DIR=$(shell realpath $(SOURCES_DIR)/gui) BUILD_DIR=$(shell realpath $(BUILD_DIR)) TESTS_DIR=$(shell realpath $(TESTS_DIR)) -$(BUILD_DIR)/icfs: $(BUILD_DIR)/main.o $(BUILD_DIR)/fuse_operations.o $(BUILD_DIR)/sourcefs.o $(BUILD_DIR)/ui-socket.o $(BUILD_DIR)/temp_permissions_table.o $(BUILD_DIR)/perm_permissions_table.o +$(BUILD_DIR)/icfs: $(BUILD_DIR)/main.o $(BUILD_DIR)/fuse_operations.o $(BUILD_DIR)/sourcefs.o $(BUILD_DIR)/ui-socket.o $(BUILD_DIR)/temp_permissions_table.o $(BUILD_DIR)/perm_permissions_table.o $(BUILD_DIR)/proc_operations.o $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $(BUILD_DIR)/icfs icfs_test: $(BUILD_DIR)/icfs @@ -97,6 +97,9 @@ $(BUILD_DIR)/temp_permissions_table.o: $(SOURCES_DIR)/temp_permissions_table.c $ $(BUILD_DIR)/perm_permissions_table.o: $(SOURCES_DIR)/perm_permissions_table.c $(SOURCES_DIR)/perm_permissions_table.h $(CC) $(CFLAGS) -c $< $(LDFLAGS) -o $@ +$(BUILD_DIR)/proc_operations.o: $(SOURCES_DIR)/proc_operations.c $(SOURCES_DIR)/proc_operations.h + $(CC) $(CFLAGS) -c $< $(LDFLAGS) -o $@ + CLEAN_TARGETS=clean-icfs ifneq ($(DIALOGUE), 0) diff --git a/src/fuse_operations.c b/src/fuse_operations.c index 269a6b7..02a16f0 100644 --- a/src/fuse_operations.c +++ b/src/fuse_operations.c @@ -39,63 +39,10 @@ #include /* flock(2) */ #include "fuse_operations.h" +#include "proc_operations.h" #include "sourcefs.h" #include "ui-socket.h" -char *get_process_name_by_pid(const int pid) { - 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); - } - */ -} - static void *xmp_init(struct fuse_conn_info *conn, struct fuse_config *cfg) { (void)conn; cfg->use_ino = 1; diff --git a/src/perm_permissions_table.c b/src/perm_permissions_table.c index 58dfec7..d6b4b5c 100644 --- a/src/perm_permissions_table.c +++ b/src/perm_permissions_table.c @@ -8,6 +8,7 @@ #include "perm_permissions_table.h" #include "access_t.h" +#include "proc_operations.h" #include "process_info.h" #include "set_mode_t.h" #include @@ -204,13 +205,16 @@ void destroy_perm_permissions_table(void) { sqlite3_close(perm_database); } * @return: access status - ALLOW, DENY or NDEF in case if no information was * found */ -access_t check_perm_access(const char *filename, struct process_info pi) { +access_t check_perm_access_noparent(const char *filename, + struct process_info pi) { char *query = NULL; int ret = asprintf(&query, "SELECT * FROM %s WHERE executable = \'%s\' " - "AND filename = \'%s\';", - table_name, pi.name, filename); + "AND ((\'%s\' LIKE CONCAT(filename, \'%%\') AND filename " + "GLOB \'*/\') OR filename = \'%s\');", + table_name, pi.name, filename, filename); + fprintf(stderr, "query: %s\n", query); if (ret < 0) { // If asprintf fails, the contents of query are undefined (see man @@ -241,6 +245,45 @@ access_t check_perm_access(const char *filename, struct process_info pi) { return NDEF; } +/** + * Checks if the process or any of it's parents have permanent access to the + * file. + * + * @param filename: The file that the process is trying to access + * @pram pi: The process information + * @return: access status - ALLOW, DENY or NDEF in case if no information was + * found. Does not return ALLOW_TEMP or DENY_TEMP. + * @note: In case one of the parent processes is killed while this function + * execution the result is not guranteed to be correct. It should only lead to + * false negatives, though. + */ +access_t check_perm_access(const char *filename, struct process_info pi) { + if (pi.PID == 0) { + return NDEF; + } + + struct process_info current_pi = pi; + current_pi.name = strdup(current_pi.name); + while (current_pi.PID != 0) { + access_t access = check_perm_access_noparent(filename, current_pi); + free(current_pi.name); + if (access != NDEF) { + return access; + } + current_pi.name = NULL; + while (current_pi.name == NULL) { + current_pi.PID = get_parent_pid(current_pi.PID); + if (current_pi.PID != 0) { + current_pi.name = get_process_name_by_pid(current_pi.PID); + } else { + break; + } + } + } + + return NDEF; +} + /** * Gives permanent access to the process to the file. * diff --git a/src/proc_operations.c b/src/proc_operations.c new file mode 100644 index 0000000..90bbb80 --- /dev/null +++ b/src/proc_operations.c @@ -0,0 +1,45 @@ +#include "proc_operations.h" +#include +#include + +char *get_process_name_by_pid(const int pid) { + 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(""); + } + return name; +} + +/** + * Finds the parent process ID of a given process. + * + * @param pid: The process ID of the process to find the parent of + * @return: The parent process ID, or 0 if the parent process ID could not be + * found + */ +pid_t get_parent_pid(pid_t pid) { + pid_t ppid = 0; + char path[256]; + snprintf(path, sizeof(path), "/proc/%u/status", pid); + + FILE *file = fopen(path, "r"); + if (file == NULL) { + perror("Failed to open /proc//status"); + return 0; + } + + char line[256]; + while (fgets(line, sizeof(line), file)) { + if (sscanf(line, "PPid:\t%d", &ppid) == 1) { + fclose(file); + return ppid; + } + } + + fclose(file); + return 0; // Parent PID not found +} diff --git a/src/proc_operations.h b/src/proc_operations.h new file mode 100644 index 0000000..e39b7c0 --- /dev/null +++ b/src/proc_operations.h @@ -0,0 +1,17 @@ +#ifndef PROC_OPERATIONS +#define PROC_OPERATIONS + +#include + +char *get_process_name_by_pid(const int pid); + +/** + * Finds the parent process ID of a given process. + * + * @param pid: The process ID of the process to find the parent of + * @return: The parent process ID, or 0 if the parent process ID could not be + * found + */ +pid_t get_parent_pid(pid_t pid); + +#endif // !PROC_OPERATIONS diff --git a/src/temp_permissions_table.c b/src/temp_permissions_table.c index e3c8e47..efe894c 100644 --- a/src/temp_permissions_table.c +++ b/src/temp_permissions_table.c @@ -9,6 +9,7 @@ #include "temp_permissions_table.h" #include "access_t.h" #include "cc.h" +#include "proc_operations.h" #include "process_info.h" #include #include @@ -144,36 +145,6 @@ access_t check_temp_access_noparent(const char *filename, pid_t pid) { return NDEF; } -/** - * Finds the parent process ID of a given process. - * - * @param pid: The process ID of the process to find the parent of - * @return: The parent process ID, or 0 if the parent process ID could not be - * found - */ -pid_t get_parent_pid(pid_t pid) { - pid_t ppid = 0; - char path[256]; - snprintf(path, sizeof(path), "/proc/%u/status", pid); - - FILE *file = fopen(path, "r"); - if (file == NULL) { - perror("Failed to open /proc//status"); - return 0; - } - - char line[256]; - while (fgets(line, sizeof(line), file)) { - if (sscanf(line, "PPid:\t%d", &ppid) == 1) { - fclose(file); - return ppid; - } - } - - fclose(file); - return 0; // Parent PID not found -} - /** * Checks if the process or any of it's parents have temporary access to the * file.