From 0bbe63fc66a7cf47fa0f4b9a0f4579e3d7cf2e1e Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 30 Sep 2024 13:41:26 +0200 Subject: [PATCH] repart: Apply denylist to individual files as well --- src/partition/repart.c | 47 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/partition/repart.c b/src/partition/repart.c index 026b4241697..37d263196c9 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -5446,6 +5446,45 @@ static usec_t epoch_or_infinity(void) { return (cache = USEC_INFINITY); } +static int file_is_denylisted(const char *source, Hashmap *denylist) { + _cleanup_close_ int pfd = -EBADF; + struct stat st, rst; + int r; + + r = chase_and_stat(source, arg_copy_source, CHASE_PREFIX_ROOT, /*ret_path=*/ NULL, &st); + if (r < 0) + return log_error_errno(r, "Failed to stat source file '%s/%s': %m", strempty(arg_copy_source), source); + + if (PTR_TO_INT(hashmap_get(denylist, &st)) == DENY_INODE) + return 1; + + if (stat(arg_copy_source, &rst) < 0) + return log_error_errno(errno, "Failed to stat '%s': %m", arg_copy_source); + + pfd = chase_and_open_parent(source, arg_copy_source, CHASE_PREFIX_ROOT, /*ret_filename=*/ NULL); + if (pfd < 0) + return log_error_errno(pfd, "Failed to chase '%s/%s': %m", strempty(arg_copy_source), source); + + for (;;) { + if (fstat(pfd, &st) < 0) + return log_error_errno(errno, "Failed to stat parent: %m"); + + if (PTR_TO_INT(hashmap_get(denylist, &st)) != DENY_DONT) + return 1; + + if (stat_inode_same(&st, &rst)) + break; + + _cleanup_close_ int new_pfd = openat(pfd, "..", O_DIRECTORY|O_RDONLY); + if (new_pfd < 0) + return log_error_errno(errno, "Failed to open parent directory: %m"); + + close_and_replace(pfd, new_pfd); + } + + return 0; +} + static int do_copy_files(Context *context, Partition *p, const char *root) { _cleanup_strv_free_ char **subvolumes = NULL; _cleanup_free_ char **override_copy_files = NULL; @@ -5563,6 +5602,14 @@ static int do_copy_files(Context *context, Partition *p, const char *root) { /* We are looking at a regular file */ + r = file_is_denylisted(*source, denylist); + if (r < 0) + return r; + if (r > 0) { + log_debug("%s is in the denylist, ignoring", *source); + continue; + } + r = path_extract_filename(*target, &fn); if (r == -EADDRNOTAVAIL || r == O_DIRECTORY) return log_error_errno(SYNTHETIC_ERRNO(EISDIR), -- 2.47.3