From: Frantisek Sumsal Date: Sat, 6 Jan 2024 15:07:42 +0000 (+0100) Subject: repart: don't crash when looping over dropped partitions X-Git-Tag: v256-rc1~1246 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f569dc6af2dbdd762b24ad7a2aa1e3b42705dd97;p=thirdparty%2Fsystemd.git repart: don't crash when looping over dropped partitions Properly skip over dropped partitions and make sure they don't affect the final graphical output (for example by leaving empty "spaces" where their definition file name would otherwise be). Resolves: #30742 --- diff --git a/src/partition/repart.c b/src/partition/repart.c index b241f9bc61a..2fee79f33ef 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -2908,12 +2908,13 @@ static int context_dump_partitions(Context *context) { return table_print_with_pager(t, arg_json_format_flags, arg_pager_flags, arg_legend); } -static void context_bar_char_process_partition( +static int context_bar_char_process_partition( Context *context, Partition *bar[], size_t n, Partition *p, - size_t *ret_start) { + size_t **start_array, + size_t *n_start_array) { uint64_t from, to, total; size_t x, y; @@ -2922,9 +2923,11 @@ static void context_bar_char_process_partition( assert(bar); assert(n > 0); assert(p); + assert(start_array); + assert(n_start_array); if (p->dropped) - return; + return 0; assert(p->offset != UINT64_MAX); assert(p->new_size != UINT64_MAX); @@ -2947,7 +2950,10 @@ static void context_bar_char_process_partition( for (size_t i = x; i < y; i++) bar[i] = p; - *ret_start = x; + if (!GREEDY_REALLOC_APPEND(*start_array, *n_start_array, &x, 1)) + return log_oom(); + + return 1; } static int partition_hint(const Partition *p, const char *node, char **ret) { @@ -2991,9 +2997,11 @@ done: static int context_dump_partition_bar(Context *context) { _cleanup_free_ Partition **bar = NULL; _cleanup_free_ size_t *start_array = NULL; + size_t n_start_array = 0; Partition *last = NULL; bool z = false; size_t c, j = 0; + int r; assert_se((c = columns()) >= 2); c -= 2; /* We do not use the leftmost and rightmost character cell */ @@ -3002,12 +3010,11 @@ static int context_dump_partition_bar(Context *context) { if (!bar) return log_oom(); - start_array = new(size_t, context->n_partitions); - if (!start_array) - return log_oom(); - - LIST_FOREACH(partitions, p, context->partitions) - context_bar_char_process_partition(context, bar, c, p, start_array + j++); + LIST_FOREACH(partitions, p, context->partitions) { + r = context_bar_char_process_partition(context, bar, c, p, &start_array, &n_start_array); + if (r < 0) + return r; + } putc(' ', stdout); @@ -3029,7 +3036,7 @@ static int context_dump_partition_bar(Context *context) { fputs(ansi_normal(), stdout); putc('\n', stdout); - for (size_t i = 0; i < context->n_partitions; i++) { + for (size_t i = 0; i < n_start_array; i++) { _cleanup_free_ char **line = NULL; line = new0(char*, c); @@ -3039,9 +3046,13 @@ static int context_dump_partition_bar(Context *context) { j = 0; LIST_FOREACH(partitions, p, context->partitions) { _cleanup_free_ char *d = NULL; + + if (p->dropped) + continue; + j++; - if (i < context->n_partitions - j) { + if (i < n_start_array - j) { if (line[start_array[j-1]]) { const char *e; @@ -3061,7 +3072,7 @@ static int context_dump_partition_bar(Context *context) { return log_oom(); } - } else if (i == context->n_partitions - j) { + } else if (i == n_start_array - j) { _cleanup_free_ char *hint = NULL; (void) partition_hint(p, context->node, &hint); diff --git a/test/units/testsuite-58.sh b/test/units/testsuite-58.sh index 0c4e3205eb8..c64b2039f30 100755 --- a/test/units/testsuite-58.sh +++ b/test/units/testsuite-58.sh @@ -1264,6 +1264,29 @@ EOF assert_in "${loop}p3 : start= *${start}, size= *${size}, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=DB081670-07AE-48CA-9F5E-813D5E40B976, name=\"linux-generic-2\"" "$output" } +testcase_dropped_partitions() { + local workdir image defs + + workdir="$(mktemp --directory "/tmp/test-repart.dropped-partitions.XXXXXXXXXX")" + # shellcheck disable=SC2064 + trap "rm -rf '${workdir:?}'" RETURN + + image="$workdir/image.img" + truncate -s 32M "$image" + + defs="$workdir/defs" + mkdir "$defs" + echo -ne "[Partition]\nType=root\n" >"$defs/10-part1.conf" + echo -ne "[Partition]\nType=root\nSizeMinBytes=1T\nPriority=1\n" >"$defs/11-dropped-first.conf" + echo -ne "[Partition]\nType=root\n" >"$defs/12-part2.conf" + echo -ne "[Partition]\nType=root\nSizeMinBytes=1T\nPriority=2\n" >"$defs/13-dropped-second.conf" + + systemd-repart --empty=allow --pretty=yes --dry-run=no --definitions="$defs" "$image" + + sfdisk -q -l "$image" + [[ "$(sfdisk -q -l "$image" | grep -c "$image")" -eq 2 ]] +} + OFFLINE="yes" run_testcases