Compare commits
	
		
			2 Commits
		
	
	
		
			4909a35a6a
			...
			91621605b1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						91621605b1
	
				 | 
					
					
						|||
| 
						
						
							
						
						ea2e41693c
	
				 | 
					
					
						
@@ -22,7 +22,7 @@
 | 
			
		||||
 * Stores the root directory information to enable relative path operations.
 | 
			
		||||
 */
 | 
			
		||||
static struct source_files_handle {
 | 
			
		||||
  const char *mountpoint; // Absolute path to the mounted filesystem root
 | 
			
		||||
  char *mountpoint; // Absolute path to the mounted filesystem root
 | 
			
		||||
  int root_fd;      // File descriptor for the root directory (O_PATH)
 | 
			
		||||
} handle;
 | 
			
		||||
 | 
			
		||||
@@ -128,8 +128,7 @@ int source_mkdir(const char *filename, mode_t mode) {
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Remove a file from the filesystem
 | 
			
		||||
 *
 | 
			
		||||
 * Uses unlinkat() with AT_REMOVEDIR flag to safely remove files relative
 | 
			
		||||
 * to the root directory.
 | 
			
		||||
 * Uses unlinkat() to safely remove files relative to the root directory.
 | 
			
		||||
 */
 | 
			
		||||
int source_unlink(const char *filename) {
 | 
			
		||||
  const char *relative_filename = source_filename_translate(filename);
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "access_t.h"
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
@@ -25,6 +26,7 @@
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/un.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <wait.h>
 | 
			
		||||
 | 
			
		||||
// Exit status codes for icfs_dialogue process interaction
 | 
			
		||||
#define DIALOGUE_YES 1
 | 
			
		||||
@@ -96,30 +98,64 @@ void destroy_ui_socket(void) {
 | 
			
		||||
struct dialogue_response ask_access(const char *filename,
 | 
			
		||||
                                    struct process_info proc_info) {
 | 
			
		||||
  FILE *fp = NULL;
 | 
			
		||||
  char *command = NULL;
 | 
			
		||||
  int ret = asprintf(&command, "icfs_dialogue \"%d\" \"%s\" \"%s\" \"%s\"",
 | 
			
		||||
                     proc_info.PID, proc_info.name, get_mountpoint(), filename);
 | 
			
		||||
 | 
			
		||||
  struct dialogue_response response;
 | 
			
		||||
  response.decision = DENY;
 | 
			
		||||
  response.filename = NULL;
 | 
			
		||||
 | 
			
		||||
  if (ret < 0) {
 | 
			
		||||
    // Memory allocation failed - create minimal fallback response
 | 
			
		||||
    fprintf(stderr, "[ICFS] Could not create query on rule insertion");
 | 
			
		||||
    perror("");
 | 
			
		||||
  // instead of popeen --------------
 | 
			
		||||
 | 
			
		||||
  char pid_str[sizeof(pid_t) *
 | 
			
		||||
               8]; // amount of bits should be enough for a decimal
 | 
			
		||||
  snprintf(pid_str, sizeof(pid_str), "%d", proc_info.PID);
 | 
			
		||||
 | 
			
		||||
  int pipefd[2];
 | 
			
		||||
  if (pipe(pipefd) == -1) {
 | 
			
		||||
    perror("[ICFS] pipe returned a error");
 | 
			
		||||
    response.filename = malloc(2);
 | 
			
		||||
    response.filename[0] = '/';
 | 
			
		||||
    response.filename[1] = 0;
 | 
			
		||||
    return response;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Execute permission dialogue
 | 
			
		||||
  fp = popen(command, "r");
 | 
			
		||||
  free(command);
 | 
			
		||||
  pid_t pid = fork();
 | 
			
		||||
  if (pid == -1) {
 | 
			
		||||
    perror("[ICFS] fork returned a error");
 | 
			
		||||
    response.filename = malloc(2);
 | 
			
		||||
    response.filename[0] = '/';
 | 
			
		||||
    response.filename[1] = 0;
 | 
			
		||||
    return response;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (pid == 0) {
 | 
			
		||||
    // Child process
 | 
			
		||||
    close(pipefd[0]);               // Close read end
 | 
			
		||||
    dup2(pipefd[1], STDOUT_FILENO); // Redirect stdout
 | 
			
		||||
    close(pipefd[1]);               // Close original write end
 | 
			
		||||
 | 
			
		||||
    // Prepare command and arguments
 | 
			
		||||
    char *args[] = {"icfs_dialogue", // Command name (looked up in PATH)
 | 
			
		||||
                    pid_str,
 | 
			
		||||
                    (char *)proc_info.name,
 | 
			
		||||
                    (char *)get_mountpoint(),
 | 
			
		||||
                    (char *)filename,
 | 
			
		||||
                    NULL};
 | 
			
		||||
 | 
			
		||||
    // Execute the command using execvp (uses PATH)
 | 
			
		||||
    execvp("icfs_dialogue", args);
 | 
			
		||||
 | 
			
		||||
    // If execvp fails
 | 
			
		||||
    perror("execvp failed");
 | 
			
		||||
    exit(EXIT_FAILURE);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // instead of popen ---------------
 | 
			
		||||
 | 
			
		||||
  close(pipefd[1]); // Close write end
 | 
			
		||||
  fp = fdopen(pipefd[0], "r");
 | 
			
		||||
 | 
			
		||||
  if (fp == NULL) {
 | 
			
		||||
    perror("[ICFS] Pipe returned a error");
 | 
			
		||||
    perror("[ICFS] fdopen returned a error");
 | 
			
		||||
    response.filename = malloc(2);
 | 
			
		||||
    response.filename[0] = '/';
 | 
			
		||||
    response.filename[1] = 0;
 | 
			
		||||
@@ -133,16 +169,42 @@ struct dialogue_response ask_access(const char *filename,
 | 
			
		||||
 | 
			
		||||
  // Read entire command output
 | 
			
		||||
  while (fgets(line, sizeof(line), fp)) {
 | 
			
		||||
    push_fmt(&dialogue_output, line);
 | 
			
		||||
    if (push_fmt(&dialogue_output, line) == NULL) {
 | 
			
		||||
      cleanup(&dialogue_output);
 | 
			
		||||
      perror("[ICFS] not enough memory for dialogue output.");
 | 
			
		||||
      // kill the dialogue if it's still there
 | 
			
		||||
      kill(pid, SIGQUIT);
 | 
			
		||||
      fclose(fp);
 | 
			
		||||
      response.filename = malloc(2);
 | 
			
		||||
      response.filename[0] = '/';
 | 
			
		||||
      response.filename[1] = 0;
 | 
			
		||||
      return response;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int dialogue_exit_code = WEXITSTATUS(pclose(fp));
 | 
			
		||||
  fclose(fp);
 | 
			
		||||
 | 
			
		||||
  // Wait for the child to finish
 | 
			
		||||
  int status;
 | 
			
		||||
  if (waitpid(pid, &status, 0) == -1) {
 | 
			
		||||
    cleanup(&dialogue_output);
 | 
			
		||||
    perror("[ICFS] waitpid error");
 | 
			
		||||
    // kill the dialogue if it is still there
 | 
			
		||||
    kill(pid, SIGQUIT);
 | 
			
		||||
    response.filename = malloc(2);
 | 
			
		||||
    response.filename[0] = '/';
 | 
			
		||||
    response.filename[1] = 0;
 | 
			
		||||
    return response;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int dialogue_exit_code = WEXITSTATUS(status);
 | 
			
		||||
 | 
			
		||||
  fprintf(stderr, "[ICFS] dialogue wrote out %s\n", first(&dialogue_output));
 | 
			
		||||
  fprintf(stderr, "[ICFS] dialogue returned %d\n", dialogue_exit_code);
 | 
			
		||||
 | 
			
		||||
  // Handle empty output case
 | 
			
		||||
  if (size(&dialogue_output) == 0) {
 | 
			
		||||
    perror("[ICFS] empty dialogue output.");
 | 
			
		||||
    push(&dialogue_output, '/');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -54,24 +54,32 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Construct the full path
 | 
			
		||||
    char fullpath[PATH_MAX];
 | 
			
		||||
    snprintf(fullpath, PATH_MAX, "%s/%s", path, entry->d_name);
 | 
			
		||||
    char *fullpath = NULL;
 | 
			
		||||
    if (asprintf(&fullpath, "%s/%s", path, entry->d_name) == -1 ||
 | 
			
		||||
        fullpath == NULL) {
 | 
			
		||||
      perror("asprintf");
 | 
			
		||||
      success = 0;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Stat the entry to check if it's a regular file
 | 
			
		||||
    struct stat entry_stat;
 | 
			
		||||
    if (lstat(fullpath, &entry_stat) == -1) {
 | 
			
		||||
      perror("lstat");
 | 
			
		||||
      success = 0;
 | 
			
		||||
      free(fullpath);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Only process regular files
 | 
			
		||||
    if (!S_ISREG(entry_stat.st_mode)) {
 | 
			
		||||
      free(fullpath);
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Try to open and immediately close the file
 | 
			
		||||
    int fd = open(fullpath, O_RDONLY);
 | 
			
		||||
    free(fullpath);
 | 
			
		||||
    if (fd == -1) {
 | 
			
		||||
      perror("open");
 | 
			
		||||
      success = 0;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user