From 925878476213d927d5b24c15a80edd5440934479 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Thu, 1 Feb 2024 13:56:37 +0100 Subject: [PATCH 1/2] vpick: make a working copy of the current dname Since we might edit the string later on by inserting NULs, which then leads up to using an invalid dname when opening the potential chosen directory: [ 4316.957536] testsuite-74.sh[99]: make_choice: entry: mytree_37.0_arm64+2-3 [ 4316.957536] testsuite-74.sh[99]: make_choice: best_version: 37.0 [ 4316.957536] testsuite-74.sh[99]: make_choice: best_filename: mytree_37.0 [ 4316.957536] testsuite-74.sh[99]: Failed to open '//var/lib/machines/mytree.v/mytree_37.0': No such file or directory Uncovered by vpick tests from TEST-74-AUX-UTILS when run on aarch64. --- src/shared/vpick.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/shared/vpick.c b/src/shared/vpick.c index ab1f4289fc..614708133b 100644 --- a/src/shared/vpick.c +++ b/src/shared/vpick.c @@ -334,12 +334,16 @@ static int make_choice( FOREACH_ARRAY(entry, de->entries, de->n_entries) { unsigned found_tries_done = UINT_MAX, found_tries_left = UINT_MAX; - _cleanup_free_ char *chopped = NULL; + _cleanup_free_ char *dname = NULL; size_t found_architecture_index = SIZE_MAX; const char *e; + dname = strdup((*entry)->d_name); + if (!dname) + return log_oom_debug(); + if (!isempty(filter->basename)) { - e = startswith((*entry)->d_name, filter->basename); + e = startswith(dname, filter->basename); if (!e) continue; @@ -348,20 +352,14 @@ static int make_choice( e++; } else - e = (*entry)->d_name; + e = dname; if (!isempty(filter->suffix)) { - const char *sfx; - - sfx = endswith(e, filter->suffix); + char *sfx = endswith(e, filter->suffix); if (!sfx) continue; - chopped = strndup(e, sfx - e); - if (!chopped) - return log_oom_debug(); - - e = chopped; + *sfx = 0; } if (FLAGS_SET(flags, PICK_TRIES)) { From d049bffc50bf68aef4e12add1877e5fccfda5cca Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Thu, 1 Feb 2024 14:00:48 +0100 Subject: [PATCH 2/2] vpick: use prefix_roota() to avoid double slash in log messages If the toplevel_path is empty we end up with doubled leading slash, which looks weird: [ 4737.028985] testsuite-74.sh[102]: Inode '//var/lib/machines/mytree.v/mytree_37.0_arm64+2-3' has wrong type, found 'dir'. [ 4737.028985] testsuite-74.sh[102]: Failed to pick version for '/var/lib/machines/mytree.v': Is a directory ... [ 4316.957536] testsuite-74.sh[99]: Failed to open '//var/lib/machines/mytree.v/mytree_37.0': No such file or directory ... --- src/shared/vpick.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/shared/vpick.c b/src/shared/vpick.c index 614708133b..6f15a7070d 100644 --- a/src/shared/vpick.c +++ b/src/shared/vpick.c @@ -159,14 +159,14 @@ static int pin_choice( struct stat st; if (fstat(inode_fd, &st) < 0) - return log_debug_errno(errno, "Failed to stat discovered inode '%s/%s': %m", toplevel_path, inode_path); + return log_debug_errno(errno, "Failed to stat discovered inode '%s': %m", prefix_roota(toplevel_path, inode_path)); if (filter->type_mask != 0 && !FLAGS_SET(filter->type_mask, UINT32_C(1) << IFTODT(st.st_mode))) return log_debug_errno( SYNTHETIC_ERRNO(errno_from_mode(filter->type_mask, st.st_mode)), - "Inode '%s/%s' has wrong type, found '%s'.", - toplevel_path, inode_path, + "Inode '%s' has wrong type, found '%s'.", + prefix_roota(toplevel_path, inode_path), inode_type_to_string(st.st_mode)); _cleanup_(pick_result_done) PickResult result = { @@ -293,7 +293,7 @@ static int make_choice( r = chaseat(toplevel_fd, p, CHASE_AT_RESOLVE_IN_ROOT, &object_path, &object_fd); if (r < 0) { if (r != -ENOENT) - return log_debug_errno(r, "Failed to open '%s/%s': %m", toplevel_path, p); + return log_debug_errno(r, "Failed to open '%s': %m", prefix_roota(toplevel_path, p)); *ret = PICK_RESULT_NULL; return 0; @@ -318,11 +318,11 @@ static int make_choice( /* Convert O_PATH to a regular directory fd */ dir_fd = fd_reopen(inode_fd, O_DIRECTORY|O_RDONLY|O_CLOEXEC); if (dir_fd < 0) - return log_debug_errno(dir_fd, "Failed to reopen '%s/%s' as directory: %m", toplevel_path, inode_path); + return log_debug_errno(dir_fd, "Failed to reopen '%s' as directory: %m", prefix_roota(toplevel_path, inode_path)); r = readdir_all(dir_fd, 0, &de); if (r < 0) - return log_debug_errno(r, "Failed to read directory '%s/%s': %m", toplevel_path, inode_path); + return log_debug_errno(r, "Failed to read directory '%s': %m", prefix_roota(toplevel_path, inode_path)); if (filter->architecture < 0) { architectures = local_architectures; @@ -466,7 +466,7 @@ static int make_choice( object_fd = openat(dir_fd, best_filename, O_CLOEXEC|O_PATH); if (object_fd < 0) - return log_debug_errno(errno, "Failed to open '%s/%s': %m", toplevel_path, p); + return log_debug_errno(errno, "Failed to open '%s': %m", prefix_roota(toplevel_path, p)); return pin_choice( toplevel_path,