1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
/* SPDX-License-Identifier: MIT */
/* SPDX-FileCopyrightText: (c) Copyright 2024 Andrew Bower <andrew@bower.uk> */
/* xchpst: eXtended Change Process State
* A tool that is backwards compatible with chpst(8) from runit(8),
* offering additional options to harden process with namespace isolation
* and more. */
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/dir.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include "xchpst.h"
#include "options.h"
#include "mount.h"
#include "compat/mount_setattr.h"
int special_mount(char *path, char *fs, char *desc, char *options) {
const char *op = "mkdirat";
int rc;
rc = mkdirat(AT_FDCWD, path, 0777);
if (rc == 0 || errno == EEXIST) {
umount2(path, MNT_DETACH);
op = "mount";
rc = mount(NULL, path, fs,
MS_NODEV | MS_NOEXEC | MS_NOSUID, options);
if (rc == -1)
fprintf(stderr, "error mounting special: %s (%s) to %s, %s\n",
path, fs, desc, strerror(errno));
} else
if (rc == -1)
fprintf(stderr, "error creating %s mount: %s: %s, %s\n",
desc, path, op, strerror(errno));
return rc;
}
int private_mount(char *path) {
return special_mount(path, "tmpfs", "private", "mode=0755");
}
int remount_ro(const char *path) {
struct stat statbuf;
int rc;
struct mount_attr attr = {
.attr_set = MOUNT_ATTR_RDONLY,
.propagation = MS_PRIVATE,
};
if ((rc = stat(path, &statbuf)) == -1 && errno == ENOENT)
return ENOENT;
/* Try remount first, in case we don't need a bind mount. */
rc = mount_setattr(AT_FDCWD, path, AT_RECURSIVE, &attr, sizeof attr);
if (rc == -1) {
/* we hope errno == EINVAL but no need to check as will find out later */
rc = mount(path, path, NULL,
MS_REC | MS_BIND | MS_PRIVATE, NULL);
if (rc == -1)
fprintf(stderr, "error recursive bind mounting %s: %s\n", path, strerror(errno));
rc = mount_setattr(AT_FDCWD, path, AT_RECURSIVE, &attr, sizeof attr);
if (rc == -1) {
fprintf(stderr, "error remounting bind mount for %s read-only: %s\n", path, strerror(errno));
} else if (is_verbose()) {
fprintf(stderr, "was able to bind mount %s read-only\n", path);
}
} else if (is_verbose()) {
fprintf(stderr, "was able to remount %s read-only\n", path);
}
return rc ? -1 : 0;
}
int remount_sys_ro(void) {
int rc;
return (((rc = remount_ro("/usr")) && rc != ENOENT) ||
((rc = remount_ro("/boot/efi")) && rc != ENOENT) ||
((rc = remount_ro("/boot")) && rc != ENOENT)) ? -1 : 0;
}
|