pit

Owner: IIIlllIIIllI URL: git@github.com:nyangkosense/pit.git

rewrite panic close, to actually force unmount pits, remove unused function

Commit b505e391ed6431ed5815254d524036895617afe9 by IIIlllIIIllI <seb.michalk@gmail.com> on 2024-12-09 10:24:42 +0100
diff --git a/pit.c b/pit.c
index c9a7376..c12b096 100644
--- a/pit.c
+++ b/pit.c
@@ -2,26 +2,27 @@
  * See LICENSE file for copyright and license details. */
 #define _POSIX_C_SOURCE 200809L
 #define _DEFAULT_SOURCE  
+#include <ctype.h>
+#include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <libcryptsetup.h>
 #include <limits.h>
 #include <pwd.h>
 #include <signal.h>
+#include <sodium.h>
 #include <stdarg.h>
 #include <string.h>
+#include <stdio.h>
 #include <sys/mman.h>
+#include <sys/prctl.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
-#include <sys/resource.h>
-#include <sys/prctl.h>
 #include <sys/mount.h>
 #include <termios.h>
 #include <unistd.h>
-#include <dirent.h>
-#include <sodium.h>
-#include <stdio.h>
 
 /* arbitrary sizes */
 #define PIT_BLOCK_SIZE 4096
@@ -33,8 +34,6 @@
 #define MAPPER_PREFIX "pit-"
 #define MOUNTPOINT_PREFIX "/mnt/pit-"
 #define FS_TYPE "ext4"
-//#define MEMORY_LOCK 1
-//#define SECURE_MEMWIPE 1
 
 /* cipher conf */
 #define CIPHER "aes"
@@ -79,7 +78,6 @@ static int open_pit(const char *path, const char *keyfile);
 static int close_pit(const char *path);
 static int list_pits(void); /* this is not used */
 static int find_mounted_pits(char ***paths, int *count);
-static int close_mapper_device(const char *name);
 static int panic_close(void);
 
 /* globals */
@@ -942,31 +940,6 @@ find_mounted_pits(char ***paths, int *count)
     return 0;
 }
 
-static int
-close_mapper_device(const char *name)
-{
-    struct crypt_device *cd;
-    int r;
-
-    r = crypt_init_by_name(&cd, name);
-    if (r < 0) {
-        fprintf(stderr, "pit: cannot init device %s: %s\n", 
-                name, strerror(-r));
-        return -1;
-    }
-
-    r = crypt_deactivate(cd, name);
-    if (r < 0) {
-        fprintf(stderr, "pit: cannot deactivate %s: %s\n", 
-                name, strerror(-r));
-        crypt_free(cd);
-        return -1;
-    }
-
-    crypt_free(cd);
-    return 0;
-}
-
 static int
 panic_close(void)
 {
@@ -981,21 +954,42 @@ panic_close(void)
     }
 
     if (find_mounted_pits(&mounted, &count) == 0 && count > 0) {
-        printf("pit: unmounting %d containers...\n", count);
+        printf("pit: force closing %d containers...\n", count);
         
         for (int i = 0; i < count; i++) {
-            if (mounted[i]) {
-                if (unmount_filesystem(mounted[i]) < 0) {
-                    fprintf(stderr, "pit: forced unmount of %s\n", mounted[i]);
-                    if (umount2(mounted[i], MNT_FORCE) < 0) {
-                        fprintf(stderr, "pit: cannot unmount %s: %s\n", 
-                                mounted[i], strerror(errno));
-                        ret = -1;
+            if (!mounted[i]) continue;
+
+            DIR *proc_dir = opendir("/proc");
+            if (proc_dir) {
+                struct dirent *pid_dir;
+                while ((pid_dir = readdir(proc_dir)) != NULL) {
+                    if (!isdigit(pid_dir->d_name[0])) 
+                        continue;
+
+                    char path[PATH_MAX], link[PATH_MAX];
+                    snprintf(path, sizeof(path), "/proc/%s/cwd", pid_dir->d_name);
+                    
+                    ssize_t len = readlink(path, link, sizeof(link) - 1);
+                    if (len > 0) {
+                        link[len] = '\0';
+                        if (strstr(link, mounted[i])) {
+                            pid_t pid = atoi(pid_dir->d_name);
+                            printf("pit: killing process %d using %s\n", pid, mounted[i]);
+                            kill(pid, SIGKILL);
+                        }
                     }
                 }
-                rmdir(mounted[i]);
-                free(mounted[i]);
+                closedir(proc_dir);
+                usleep(100000);
+            }
+
+            printf("pit: force unmounting %s\n", mounted[i]);
+            if (umount2(mounted[i], MNT_FORCE | MNT_DETACH) < 0) {
+                fprintf(stderr, "pit: cannot unmount %s: %s\n", 
+                        mounted[i], strerror(errno));
             }
+            rmdir(mounted[i]);
+            free(mounted[i]);
         }
         free(mounted);
     }
@@ -1006,27 +1000,18 @@ panic_close(void)
         return -1;
     }
 
-    printf("pit: closing encrypted devices...\n");
-    
     while ((dp = readdir(dir)) != NULL) {
-        /* Skip . and .. entries */
-        if (dp->d_name[0] == '.')
-            continue;
-            
-        /* Skip the control device */
-        if (strcmp(dp->d_name, "control") == 0)
-            continue;
-
-        /* Only handle our pit devices */
         if (strncmp(dp->d_name, MAPPER_PREFIX, strlen(MAPPER_PREFIX)) == 0) {
-            printf("pit: closing %s\n", dp->d_name);
-            if (close_mapper_device(dp->d_name) < 0) {
-                ret = -1;
+            printf("pit: force closing device %s\n", dp->d_name);
+            struct crypt_device *cd;
+            if (crypt_init_by_name(&cd, dp->d_name) == 0) {
+                crypt_deactivate_by_name(cd, dp->d_name, CRYPT_DEACTIVATE_FORCE);
+                crypt_free(cd);
             }
         }
     }
-    
     closedir(dir);
+
     return ret;
 }