#include <unistd.h>
#include "alloc-util.h"
-#include "blockdev-util.h"
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
return fd;
}
-static int blockdev_is_encrypted(const char *sysfs_path, unsigned depth_left) {
- _cleanup_free_ char *p = NULL, *uuids = NULL;
- _cleanup_closedir_ DIR *d = NULL;
- int r, found_encrypted = false;
-
- assert(sysfs_path);
-
- if (depth_left == 0)
- return -EINVAL;
-
- p = path_join(sysfs_path, "dm/uuid");
- if (!p)
- return -ENOMEM;
-
- r = read_one_line_file(p, &uuids);
- if (r != -ENOENT) {
- if (r < 0)
- return r;
-
- /* The DM device's uuid attribute is prefixed with "CRYPT-" if this is a dm-crypt device. */
- if (startswith(uuids, "CRYPT-"))
- return true;
- }
-
- /* Not a dm-crypt device itself. But maybe it is on top of one? Follow the links in the "slaves/"
- * subdir. */
-
- p = mfree(p);
- p = path_join(sysfs_path, "slaves");
- if (!p)
- return -ENOMEM;
-
- d = opendir(p);
- if (!d) {
- if (errno == ENOENT) /* Doesn't have underlying devices */
- return false;
-
- return -errno;
- }
-
- for (;;) {
- _cleanup_free_ char *q = NULL;
- struct dirent *de;
-
- errno = 0;
- de = readdir_no_dot(d);
- if (!de) {
- if (errno != 0)
- return -errno;
-
- break; /* No more underlying devices */
- }
-
- q = path_join(p, de->d_name);
- if (!q)
- return -ENOMEM;
-
- r = blockdev_is_encrypted(q, depth_left - 1);
- if (r < 0)
- return r;
- if (r == 0) /* we found one that is not encrypted? then propagate that immediately */
- return false;
-
- found_encrypted = true;
- }
-
- return found_encrypted;
-}
-
-int path_is_encrypted(const char *path) {
- char p[SYS_BLOCK_PATH_MAX(NULL)];
- dev_t devt;
- int r;
-
- r = get_block_device(path, &devt);
- if (r < 0)
- return r;
- if (r == 0) /* doesn't have a block device */
- return false;
-
- xsprintf_sys_block_path(p, NULL, devt);
-
- return blockdev_is_encrypted(p, 10 /* safety net: maximum recursion depth */);
-}
-
int conservative_renameat(
int olddirfd, const char *oldpath,
int newdirfd, const char *newpath) {
int open_parent(const char *path, int flags, mode_t mode);
-int path_is_encrypted(const char *path);
-
int conservative_renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
static inline int conservative_rename(const char *oldpath, const char *newpath) {
return conservative_renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath);
async.h
audit-util.c
audit-util.h
- blockdev-util.c
- blockdev-util.h
- btrfs-util.c
- btrfs-util.h
build.c
build.h
bus-label.c
chattr-util.h
conf-files.c
conf-files.h
- copy.c
- copy.h
creds-util.c
creds-util.h
- data-fd-util.c
- data-fd-util.h
def.h
dirent-util.c
dirent-util.h
ioprio.h
khash.c
khash.h
- label.c
- label.h
limits-util.c
limits-util.h
linux/btrfs.h
missing_syscall.h
missing_timerfd.h
missing_type.h
- mkdir-label.c
mkdir.c
mkdir.h
mountpoint-util.c
replace-var.h
rlimit-util.c
rlimit-util.h
- rm-rf.c
- rm-rf.h
- selinux-util.c
- selinux-util.h
set.h
sigbus.c
sigbus.h
signal-util.h
siphash24.c
siphash24.h
- smack-util.c
- smack-util.h
- socket-label.c
socket-util.c
socket-util.h
sort-util.c
#include <stddef.h>
#include <sys/mount.h>
+#include "blockdev-util.h"
#include "chown-recursive.h"
#include "copy.h"
#include "fd-util.h"
#include "path-util.h"
#include "process-util.h"
#include "rlimit-util.h"
-#include "selinux-util.h"
#include "signal-util.h"
#include "stdio-util.h"
#include "string-util.h"
return !FLAGS_SET(ull, GENHD_FL_NO_PART_SCAN);
}
+
+static int blockdev_is_encrypted(const char *sysfs_path, unsigned depth_left) {
+ _cleanup_free_ char *p = NULL, *uuids = NULL;
+ _cleanup_closedir_ DIR *d = NULL;
+ int r, found_encrypted = false;
+
+ assert(sysfs_path);
+
+ if (depth_left == 0)
+ return -EINVAL;
+
+ p = path_join(sysfs_path, "dm/uuid");
+ if (!p)
+ return -ENOMEM;
+
+ r = read_one_line_file(p, &uuids);
+ if (r != -ENOENT) {
+ if (r < 0)
+ return r;
+
+ /* The DM device's uuid attribute is prefixed with "CRYPT-" if this is a dm-crypt device. */
+ if (startswith(uuids, "CRYPT-"))
+ return true;
+ }
+
+ /* Not a dm-crypt device itself. But maybe it is on top of one? Follow the links in the "slaves/"
+ * subdir. */
+
+ p = mfree(p);
+ p = path_join(sysfs_path, "slaves");
+ if (!p)
+ return -ENOMEM;
+
+ d = opendir(p);
+ if (!d) {
+ if (errno == ENOENT) /* Doesn't have underlying devices */
+ return false;
+
+ return -errno;
+ }
+
+ for (;;) {
+ _cleanup_free_ char *q = NULL;
+ struct dirent *de;
+
+ errno = 0;
+ de = readdir_no_dot(d);
+ if (!de) {
+ if (errno != 0)
+ return -errno;
+
+ break; /* No more underlying devices */
+ }
+
+ q = path_join(p, de->d_name);
+ if (!q)
+ return -ENOMEM;
+
+ r = blockdev_is_encrypted(q, depth_left - 1);
+ if (r < 0)
+ return r;
+ if (r == 0) /* we found one that is not encrypted? then propagate that immediately */
+ return false;
+
+ found_encrypted = true;
+ }
+
+ return found_encrypted;
+}
+
+int path_is_encrypted(const char *path) {
+ char p[SYS_BLOCK_PATH_MAX(NULL)];
+ dev_t devt;
+ int r;
+
+ r = get_block_device(path, &devt);
+ if (r < 0)
+ return r;
+ if (r == 0) /* doesn't have a block device */
+ return false;
+
+ xsprintf_sys_block_path(p, NULL, devt);
+
+ return blockdev_is_encrypted(p, 10 /* safety net: maximum recursion depth */);
+}
int lock_whole_block_device(dev_t devt, int operation);
int blockdev_partscan_enabled(int fd);
+
+int path_is_encrypted(const char *path);
#include "apparmor-util.h"
#include "architecture.h"
#include "audit-util.h"
+#include "blockdev-util.h"
#include "cap-list.h"
#include "cgroup-util.h"
#include "condition.h"
bitmap.c
bitmap.h
blkid-util.h
+ blockdev-util.c
+ blockdev-util.h
bond-util.c
bond-util.h
boot-timestamps.c
bpf-program.h
bridge-util.c
bridge-util.h
+ btrfs-util.c
+ btrfs-util.h
bus-get-properties.c
bus-get-properties.h
bus-locator.c
condition.h
conf-parser.c
conf-parser.h
+ copy.c
+ copy.h
coredump-util.c
coredump-util.h
cpu-set-util.c
cryptsetup-util.c
cryptsetup-util.h
daemon-util.h
+ data-fd-util.c
+ data-fd-util.h
dev-setup.c
dev-setup.h
device-nodes.c
kbd-util.h
killall.c
killall.h
+ label.c
+ label.h
libcrypt-util.c
libcrypt-util.h
libfido2-util.c
macvlan-util.c
macvlan-util.h
main-func.h
+ mkdir-label.c
mkfs-util.c
mkfs-util.h
module-util.h
resize-fs.h
resolve-util.c
resolve-util.h
+ rm-rf.c
+ rm-rf.h
seccomp-util.h
securebits-util.c
securebits-util.h
+ selinux-util.c
+ selinux-util.h
serialize.c
serialize.h
service-util.c
service-util.h
sleep-config.c
sleep-config.h
+ smack-util.c
+ smack-util.h
+ socket-label.c
socket-netlink.c
socket-netlink.h
spawn-ask-password-agent.c
[['src/test/test-utf8.c']],
+ [['src/test/test-blockdev-util.c']],
+
[['src/test/test-dev-setup.c']],
[['src/test/test-capability.c'],
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "blockdev-util.h"
+#include "errno-util.h"
+#include "tests.h"
+
+static void test_path_is_encrypted_one(const char *p, int expect) {
+ int r;
+
+ r = path_is_encrypted(p);
+ if (r == -ENOENT || ERRNO_IS_PRIVILEGE(r)) /* This might fail, if btrfs is used and we run in a
+ * container. In that case we cannot resolve the device node paths that
+ * BTRFS_IOC_DEV_INFO returns, because the device nodes are unlikely to exist in
+ * the container. But if we can't stat() them we cannot determine the dev_t of
+ * them, and thus cannot figure out if they are enrypted. Hence let's just ignore
+ * ENOENT here. Also skip the test if we lack privileges. */
+ return;
+ assert_se(r >= 0);
+
+ log_info("%s encrypted: %s", p, yes_no(r));
+
+ assert_se(expect < 0 || ((r > 0) == (expect > 0)));
+}
+
+static void test_path_is_encrypted(void) {
+ int booted = sd_booted(); /* If this is run in build environments such as koji, /dev might be a
+ * reguar fs. Don't assume too much if not running under systemd. */
+
+ log_info("/* %s (sd_booted=%d) */", __func__, booted);
+
+ test_path_is_encrypted_one("/home", -1);
+ test_path_is_encrypted_one("/var", -1);
+ test_path_is_encrypted_one("/", -1);
+ test_path_is_encrypted_one("/proc", false);
+ test_path_is_encrypted_one("/sys", false);
+ test_path_is_encrypted_one("/dev", booted > 0 ? false : -1);
+}
+
+int main(int argc, char **argv) {
+ test_setup_logging(LOG_INFO);
+
+ test_path_is_encrypted();
+}
assert_se(S_ISLNK(st.st_mode));
}
-static void test_path_is_encrypted_one(const char *p, int expect) {
- int r;
-
- r = path_is_encrypted(p);
- if (r == -ENOENT || ERRNO_IS_PRIVILEGE(r)) /* This might fail, if btrfs is used and we run in a
- * container. In that case we cannot resolve the device node paths that
- * BTRFS_IOC_DEV_INFO returns, because the device nodes are unlikely to exist in
- * the container. But if we can't stat() them we cannot determine the dev_t of
- * them, and thus cannot figure out if they are enrypted. Hence let's just ignore
- * ENOENT here. Also skip the test if we lack privileges. */
- return;
- assert_se(r >= 0);
-
- log_info("%s encrypted: %s", p, yes_no(r));
-
- assert_se(expect < 0 || ((r > 0) == (expect > 0)));
-}
-
-static void test_path_is_encrypted(void) {
- int booted = sd_booted(); /* If this is run in build environments such as koji, /dev might be a
- * reguar fs. Don't assume too much if not running under systemd. */
-
- log_info("/* %s (sd_booted=%d) */", __func__, booted);
-
- test_path_is_encrypted_one("/home", -1);
- test_path_is_encrypted_one("/var", -1);
- test_path_is_encrypted_one("/", -1);
- test_path_is_encrypted_one("/proc", false);
- test_path_is_encrypted_one("/sys", false);
- test_path_is_encrypted_one("/dev", booted > 0 ? false : -1);
-}
-
static void create_binary_file(const char *p, const void *data, size_t l) {
_cleanup_close_ int fd = -1;
test_fsync_directory_of_file();
test_rename_noreplace();
test_chmod_and_chown();
- test_path_is_encrypted();
test_conservative_rename();
return 0;