Compare commits

...

3 Commits

Author SHA1 Message Date
8e1c325f98
Added mutex to permissions checks to avoid inconsistent permission checking 2025-05-20 09:59:18 +02:00
754a26884c
Changed realpath to readlink
/proc/pid/exe already seems to be a link to the absolute path to the
executable. This fixes bugs related to containerised applications.
2025-05-20 09:57:59 +02:00
2f82ab63ac
Fixed undefined permission check errors 2025-05-20 09:24:07 +02:00
4 changed files with 56 additions and 19 deletions

View File

@ -207,6 +207,9 @@ void destroy_perm_permissions_table(void) { sqlite3_close(perm_database); }
*/
access_t check_perm_access_noparent(const char *filename,
struct process_info pi) {
if (pi.name == NULL)
return NDEF;
access_t ret = NDEF;
sqlite3_stmt *stmt = NULL;
const char *sql = "SELECT mode FROM permissions WHERE executable = ?1 "

View File

@ -8,8 +8,10 @@
#include "proc_operations.h"
#include <linux/limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/**
* @brief Returns the PID of the main thread (i.e., the process ID) of the
@ -54,11 +56,38 @@ char *get_process_name_by_pid(const int pid) {
char path[1024];
sprintf(path, "/proc/%d/exe", pid);
char *name = realpath(path, NULL);
size_t size = 128;
char *name = malloc(size);
if (name == NULL) {
fprintf(stderr, "Could not get process name by pid %d", pid);
perror("");
return NULL;
}
while (1) {
ssize_t len = readlink(path, name, size);
if (len == -1) {
fprintf(stderr, "Could not get process name by pid %d", pid);
perror("");
free(name);
return NULL;
}
if ((size_t)len >= size) {
size *= 2;
char *new_name = realloc(name, size);
if (!new_name) {
free(name);
return NULL;
}
name = new_name;
} else {
// readlink does not set the null character
name[len] = 0;
break;
}
}
return name;
}

View File

@ -254,6 +254,8 @@ access_t check_temp_access(const char *filename, struct process_info pi) {
*/
int set_temp_access(const char *filename, struct process_info pi,
set_mode_t mode) {
if (pi.PID == 0)
return NDEF;
pthread_rwlock_wrlock(&temp_permissions_table_lock);
struct temp_process_permissions *permission_entry =
get(&temp_permissions_table, pi.PID);

View File

@ -30,6 +30,8 @@
#define DIALOGUE_NO 1
#define DIALOGUE_PERM 2
pthread_mutex_t access_check_mutex = PTHREAD_MUTEX_INITIALIZER;
struct dialogue_response {
access_t decision;
char *filename;
@ -127,6 +129,7 @@ struct dialogue_response ask_access(const char *filename,
}
int dialogue_exit_code = WEXITSTATUS(pclose(fp));
fprintf(stderr, "dialogue wrote out %s\n", first(&dialogue_output));
fprintf(stderr, "dialogue returned %d\n", dialogue_exit_code);
@ -172,6 +175,7 @@ struct dialogue_response ask_access(const char *filename,
int interactive_access(const char *filename, struct process_info proc_info,
int opts) {
char *real_path = real_filename(filename);
pthread_mutex_lock(&access_check_mutex);
access_t access = check_temp_access(real_path, proc_info);
if (access == ALLOW) {
@ -180,6 +184,7 @@ int interactive_access(const char *filename, struct process_info proc_info,
"permission table.\n",
proc_info.name);
free(real_path);
pthread_mutex_unlock(&access_check_mutex);
return 1;
}
if (access == DENY) {
@ -188,6 +193,7 @@ int interactive_access(const char *filename, struct process_info proc_info,
"permission table.\n",
proc_info.name);
free(real_path);
pthread_mutex_unlock(&access_check_mutex);
return 0;
}
@ -198,6 +204,7 @@ int interactive_access(const char *filename, struct process_info proc_info,
"permission table.\n",
proc_info.name);
free(real_path);
pthread_mutex_unlock(&access_check_mutex);
return 1;
}
if (access == DENY) {
@ -206,6 +213,7 @@ int interactive_access(const char *filename, struct process_info proc_info,
"permission table.\n",
proc_info.name);
free(real_path);
pthread_mutex_unlock(&access_check_mutex);
return 0;
}
@ -216,12 +224,14 @@ int interactive_access(const char *filename, struct process_info proc_info,
fprintf(stderr, "Permission granted permanently to %s.\n", proc_info.name);
set_perm_access(real_path, proc_info, SET_ALLOW);
free(real_path);
pthread_mutex_unlock(&access_check_mutex);
return 1;
}
if (opts & GRANT_TEMP) {
fprintf(stderr, "Permission granted temporarily to %s.\n", proc_info.name);
set_temp_access(real_path, proc_info, SET_ALLOW);
free(real_path);
pthread_mutex_unlock(&access_check_mutex);
return 1;
}
@ -245,43 +255,36 @@ int interactive_access(const char *filename, struct process_info proc_info,
real_path = real_filename(response.filename);
free(response.filename);
int ret = 0;
if (response.decision == ALLOW) {
fprintf(stderr,
"Permission granted permanently to %s based on zenty response.\n",
proc_info.name);
set_perm_access(real_path, proc_info, SET_ALLOW);
free(real_path);
return 1;
}
if (response.decision == ALLOW_TEMP) {
ret = 1;
} else if (response.decision == ALLOW_TEMP) {
fprintf(stderr,
"Permission granted temporarily to %s based on zenty response.\n",
proc_info.name);
set_temp_access(real_path, proc_info, SET_ALLOW);
free(real_path);
return 1;
}
if (response.decision == DENY_TEMP) {
ret = 1;
} else if (response.decision == DENY_TEMP) {
fprintf(stderr,
"Permission denied temporarily to %s based on zenty response.\n",
proc_info.name);
set_temp_access(real_path, proc_info, SET_DENY);
free(real_path);
return 0;
}
if (response.decision == DENY) {
ret = 0;
} else if (response.decision == DENY) {
fprintf(stderr,
"Permission denied permanently to %s based on zenty response.\n",
proc_info.name);
set_perm_access(real_path, proc_info, SET_DENY);
free(real_path);
return 0;
ret = 0;
}
pthread_mutex_unlock(&access_check_mutex);
free(real_path);
// deny on unknown options.
return 0;
return ret;
}