diff --git a/src/temp_permissions_table.c b/src/temp_permissions_table.c index 2701614..261ccda 100644 --- a/src/temp_permissions_table.c +++ b/src/temp_permissions_table.c @@ -38,7 +38,7 @@ unsigned long long get_process_creation_time(pid_t pid) { unsigned long long creation_time = 0; // Construct the path to the process's status file - snprintf(path, sizeof(path), "/proc/%d/stat", pid); + snprintf(path, sizeof(path), "/proc/%u/stat", pid); // Open the status file fp = fopen(path, "r"); @@ -49,8 +49,8 @@ unsigned long long get_process_creation_time(pid_t pid) { // Read the creation time (the 22nd field in the stat file) for (int i = 1; i < 22; i++) { - if (fscanf(fp, "%*s") != 1) { - fprintf(stderr, "Error reading process stat file\n"); + if (fscanf(fp, "%*s") == EOF) { + fprintf(stderr, "Error reading process stat file on the number %d\n", i); fclose(fp); return 0; } @@ -96,17 +96,17 @@ void destroy_temp_permissions_table() { * Checks if the process has a temporary access to the file. * * @param filename: The file that the process is trying to access - * @pram pi: The process information + * @pram pid: PID of the process * @return: 0 if access is denied, 1 if access is allowed */ -int check_temp_access(const char *filename, struct process_info pi) { + +int check_temp_access_noparent(const char *filename, pid_t pid) { // TODO: more efficient locking pthread_mutex_lock(&temp_permissions_table_lock); struct temp_process_permissions *permission_entry = - get(&temp_permissions_table, pi.PID); + get(&temp_permissions_table, pid); if (permission_entry != NULL) { - unsigned long long process_creation_time = - get_process_creation_time(pi.PID); + unsigned long long process_creation_time = get_process_creation_time(pid); if (process_creation_time == 0) { perror("Could not retrieve process creation time"); pthread_mutex_unlock(&temp_permissions_table_lock); @@ -128,6 +128,59 @@ int check_temp_access(const char *filename, struct process_info pi) { return 0; } +/** + * 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. + * + * @param filename: The file that the process is trying to access + * @pram pi: The process information + * @return: 0 if access is denied, 1 if access is allowed + * @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. + */ +int check_temp_access(const char *filename, struct process_info pi) { + pid_t current_pid = pi.PID; + while (current_pid != 0) { + if (check_temp_access_noparent(filename, current_pid)) { + return 1; + } + current_pid = get_parent_pid(current_pid); + } + + return 0; +} + /** * Gives temporary access to the process to the file. * @@ -172,6 +225,7 @@ int give_temp_access(const char *filename, struct process_info pi) { push(&new_permission_entry.allowed_files, strdup(filename)); insert(&temp_permissions_table, pi.PID, new_permission_entry); + printf("temp_permissions_table size: %ld\n", size(&temp_permissions_table)); pthread_mutex_unlock(&temp_permissions_table_lock); return 0;