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;
}