bcd, id128, sysupdate: tighten edge-case handling (#43018)
This commit is contained in:
+9
-7
@@ -93,15 +93,17 @@ assert_cc(offsetof(KeyValue, data_offset) == 8);
|
||||
assert_cc(offsetof(KeyValue, data_type) == 12);
|
||||
assert_cc(offsetof(KeyValue, name) == 20);
|
||||
|
||||
#define BAD_OFFSET(offset, len, max) \
|
||||
((uint64_t) (offset) + (len) >= (max))
|
||||
static bool bad_offset(uint64_t offset, uint64_t len, uint64_t max) {
|
||||
return offset > max || len > max - offset;
|
||||
}
|
||||
|
||||
#define BAD_STRUCT(type, offset, max) \
|
||||
((uint64_t) (offset) + sizeof(type) >= (max))
|
||||
bad_offset(offset, sizeof(type), max)
|
||||
|
||||
#define BAD_ARRAY(type, array, offset, array_len, max) \
|
||||
((uint64_t) (offset) + offsetof(type, array) + \
|
||||
sizeof((type){}.array[0]) * (uint64_t) (array_len) >= (max))
|
||||
bad_offset(offset, \
|
||||
offsetof(type, array) + sizeof((type){}.array[0]) * (uint64_t) (array_len), \
|
||||
max)
|
||||
|
||||
static const Key *get_key(const uint8_t *bcd, uint32_t bcd_len, uint32_t offset, const char *name);
|
||||
|
||||
@@ -167,7 +169,7 @@ static const KeyValue *get_key_value(const uint8_t *bcd, uint32_t bcd_len, const
|
||||
if (key->n_key_values == 0)
|
||||
return NULL;
|
||||
|
||||
if (BAD_OFFSET(key->key_values_offset, sizeof(uint32_t) * (uint64_t) key->n_key_values, bcd_len) ||
|
||||
if (bad_offset(key->key_values_offset, sizeof(uint32_t) * (uint64_t) key->n_key_values, bcd_len) ||
|
||||
(uintptr_t) (bcd + key->key_values_offset) % alignof(uint32_t) != 0)
|
||||
return NULL;
|
||||
|
||||
@@ -191,7 +193,7 @@ static const KeyValue *get_key_value(const uint8_t *bcd, uint32_t bcd_len, const
|
||||
if (FLAGS_SET(kv->data_size, UINT32_C(1) << 31))
|
||||
continue;
|
||||
|
||||
if (BAD_OFFSET(kv->data_offset, kv->data_size, bcd_len))
|
||||
if (bad_offset(kv->data_offset, kv->data_size, bcd_len))
|
||||
continue;
|
||||
|
||||
if (strncaseeq8(name, kv->name, kv->name_len) && strlen8(name) == kv->name_len)
|
||||
|
||||
@@ -90,6 +90,15 @@ TEST(base_block) {
|
||||
*bcd = backup;
|
||||
}
|
||||
|
||||
TEST(offset_bounds) {
|
||||
assert_se(!bad_offset(0, sizeof(Key), sizeof(Key)));
|
||||
assert_se(!BAD_STRUCT(Key, 0, sizeof(Key)));
|
||||
assert_se(!BAD_ARRAY(Key, key_name, 0, 0, sizeof(Key)));
|
||||
|
||||
assert_se(bad_offset(0, sizeof(Key) + 1, sizeof(Key)));
|
||||
assert_se(bad_offset(UINT32_MAX, 2, UINT32_MAX));
|
||||
}
|
||||
|
||||
TEST(bad_bcd) {
|
||||
size_t len;
|
||||
uint8_t *hbins;
|
||||
|
||||
+43
-6
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sd-json.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "build.h"
|
||||
#include "format-table.h"
|
||||
@@ -24,9 +26,37 @@ static PagerFlags arg_pager_flags = 0;
|
||||
static bool arg_legend = true;
|
||||
static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF;
|
||||
|
||||
static int print_id(sd_id128_t id) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *json = NULL;
|
||||
int r;
|
||||
|
||||
if (!sd_json_format_enabled(arg_json_format_flags))
|
||||
return id128_pretty_print(id, arg_mode);
|
||||
|
||||
if (arg_mode == ID128_PRINT_ID128)
|
||||
r = sd_json_buildo(&json, SD_JSON_BUILD_PAIR_ID128("id", id));
|
||||
else
|
||||
r = sd_json_buildo(&json, SD_JSON_BUILD_PAIR_UUID("id", id));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create JSON: %m");
|
||||
|
||||
r = sd_json_variant_dump(json, arg_json_format_flags, stdout, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to print JSON: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VERB_NOARG(verb_new, "new", "Generate a new ID");
|
||||
static int verb_new(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
return id128_print_new(arg_mode);
|
||||
sd_id128_t id;
|
||||
int r;
|
||||
|
||||
r = sd_id128_randomize(&id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate ID: %m");
|
||||
|
||||
return print_id(id);
|
||||
}
|
||||
|
||||
VERB_NOARG(verb_machine_id, "machine-id", "Print the ID of current machine");
|
||||
@@ -42,7 +72,7 @@ static int verb_machine_id(int argc, char *argv[], uintptr_t _data, void *userda
|
||||
return log_error_errno(r, "Failed to get %smachine-ID: %m",
|
||||
sd_id128_is_null(arg_app) ? "" : "app-specific ");
|
||||
|
||||
return id128_pretty_print(id, arg_mode);
|
||||
return print_id(id);
|
||||
}
|
||||
|
||||
VERB_NOARG(verb_boot_id, "boot-id", "Print the ID of current boot");
|
||||
@@ -58,7 +88,7 @@ static int verb_boot_id(int argc, char *argv[], uintptr_t _data, void *userdata)
|
||||
return log_error_errno(r, "Failed to get %sboot-ID: %m",
|
||||
sd_id128_is_null(arg_app) ? "" : "app-specific ");
|
||||
|
||||
return id128_pretty_print(id, arg_mode);
|
||||
return print_id(id);
|
||||
}
|
||||
|
||||
VERB_NOARG(verb_invocation_id, "invocation-id", "Print the ID of current invocation");
|
||||
@@ -74,7 +104,7 @@ static int verb_invocation_id(int argc, char *argv[], uintptr_t _data, void *use
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get invocation-ID: %m");
|
||||
|
||||
return id128_pretty_print(id, arg_mode);
|
||||
return print_id(id);
|
||||
}
|
||||
|
||||
VERB_NOARG(verb_var_uuid, "var-partition-uuid", "Print the UUID for the /var/ partition");
|
||||
@@ -91,7 +121,7 @@ static int verb_var_uuid(int argc, char *argv[], uintptr_t _data, void *userdata
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate machine-specific /var/ UUID: %m");
|
||||
|
||||
return id128_pretty_print(id, arg_mode);
|
||||
return print_id(id);
|
||||
}
|
||||
|
||||
static int show_one(Table **table, const char *name, sd_id128_t uuid, bool first) {
|
||||
@@ -120,7 +150,7 @@ static int show_one(Table **table, const char *name, sd_id128_t uuid, bool first
|
||||
}
|
||||
|
||||
if (arg_value)
|
||||
return id128_pretty_print(uuid, arg_mode);
|
||||
return print_id(uuid);
|
||||
|
||||
if (!*table) {
|
||||
*table = table_new("name", "id");
|
||||
@@ -141,6 +171,10 @@ static int verb_show(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
int r;
|
||||
|
||||
argv = strv_skip(argv, 1);
|
||||
if (arg_value && sd_json_format_enabled(arg_json_format_flags) && strv_length(argv) != 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"'show --value --json=' requires exactly one argument.");
|
||||
|
||||
if (argv)
|
||||
STRV_FOREACH(p, argv) {
|
||||
sd_id128_t uuid;
|
||||
@@ -290,6 +324,9 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (arg_mode == ID128_PRINT_PRETTY && sd_json_format_enabled(arg_json_format_flags))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--pretty cannot be combined with --json=.");
|
||||
|
||||
*ret_args = option_parser_get_args(&opts);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -814,21 +814,6 @@ static int context_show_version(Context *c, const char *version) {
|
||||
if (arg_json_format_flags & (SD_JSON_FORMAT_OFF|SD_JSON_FORMAT_PRETTY|SD_JSON_FORMAT_PRETTY_AUTO))
|
||||
pager_open(arg_pager_flags);
|
||||
|
||||
if (!sd_json_format_enabled(arg_json_format_flags))
|
||||
printf("%s%s%s Version: %s\n"
|
||||
" State: %s%s%s\n"
|
||||
"Installed: %s%s%s%s\n"
|
||||
"Available: %s%s\n"
|
||||
"Protected: %s%s%s\n"
|
||||
" Obsolete: %s%s%s\n\n",
|
||||
strempty(update_set_flags_to_color(us->flags)), update_set_flags_to_glyph(us->flags), ansi_normal(), us->version,
|
||||
strempty(update_set_flags_to_color(us->flags)), update_set_flags_to_string(us->flags), ansi_normal(),
|
||||
yes_no(us->flags & UPDATE_INSTALLED), FLAGS_SET(us->flags, UPDATE_INSTALLED|UPDATE_NEWEST) ? " (newest)" : "",
|
||||
FLAGS_SET(us->flags, UPDATE_INSTALLED|UPDATE_PENDING) ? " (pending)" : "", FLAGS_SET(us->flags, UPDATE_INSTALLED|UPDATE_PARTIAL) ? " (partial)" : "",
|
||||
yes_no(us->flags & UPDATE_AVAILABLE), (us->flags & (UPDATE_INSTALLED|UPDATE_AVAILABLE|UPDATE_NEWEST)) == (UPDATE_AVAILABLE|UPDATE_NEWEST) ? " (newest)" : "",
|
||||
FLAGS_SET(us->flags, UPDATE_INSTALLED|UPDATE_PROTECTED) ? ansi_highlight() : "", yes_no(FLAGS_SET(us->flags, UPDATE_INSTALLED|UPDATE_PROTECTED)), ansi_normal(),
|
||||
us->flags & UPDATE_OBSOLETE ? ansi_highlight_red() : "", yes_no(us->flags & UPDATE_OBSOLETE), ansi_normal());
|
||||
|
||||
t = table_new("type", "path", "ptuuid", "ptflags", "mtime", "mode", "size", "tries-done", "tries-left", "noauto", "ro", "growfs", "sha256");
|
||||
if (!t)
|
||||
return log_oom();
|
||||
|
||||
@@ -1233,6 +1233,7 @@ InstancesMax=1
|
||||
EOF
|
||||
"$SYSUPDATE" --verify=no update
|
||||
cmp "$WORKDIR/source/sub/blob-v11.bin" "$WORKDIR/blobs/blob-v11.bin"
|
||||
[[ "$("$SYSUPDATE" --verify=no list v11 | grep -c "Version: v11")" == "1" ]]
|
||||
rm "$CONFIGDIR/01-basename-dir.transfer"
|
||||
|
||||
# A url-file source pulled via file:// using SHA256SUMS with "sub/blob-v1x.bin" entries
|
||||
|
||||
@@ -28,21 +28,25 @@ systemd-id128 show --json=short
|
||||
systemd-id128 show --no-legend
|
||||
systemd-id128 show --no-pager --no-legend
|
||||
systemd-id128 show root -P -u
|
||||
systemd-id128 show root --value --json=short | jq -e '.id | type == "string"'
|
||||
[[ -n "$(systemd-id128 var-partition-uuid)" ]]
|
||||
[[ "$(systemd-id128 var-partition-uuid)" != "4d21b016b53445c2a9fb5c16e091fd2d" ]]
|
||||
|
||||
[[ "$(systemd-id128 new | wc -c)" -eq 33 ]]
|
||||
systemd-id128 --json=short new | jq -e '.id | type == "string"'
|
||||
systemd-id128 new -p
|
||||
systemd-id128 new -u
|
||||
systemd-id128 new -a 4f68bce3e8cd4db196e7fbcaf984b709
|
||||
|
||||
systemd-id128 machine-id
|
||||
assert_eq "$(systemd-id128 --json=short machine-id | jq --raw-output .id)" "$(</etc/machine-id)"
|
||||
systemd-id128 machine-id --pretty
|
||||
systemd-id128 machine-id --uuid
|
||||
systemd-id128 machine-id --app-specific=4f68bce3e8cd4db196e7fbcaf984b709
|
||||
assert_eq "$(systemd-id128 machine-id)" "$(</etc/machine-id)"
|
||||
|
||||
systemd-id128 boot-id
|
||||
assert_eq "$(systemd-id128 --json=short boot-id --uuid | jq --raw-output .id)" "$(</proc/sys/kernel/random/boot_id)"
|
||||
systemd-id128 boot-id --pretty
|
||||
systemd-id128 boot-id --uuid
|
||||
systemd-id128 boot-id --app-specific=4f68bce3e8cd4db196e7fbcaf984b709
|
||||
@@ -57,3 +61,5 @@ systemd-run --wait --pipe bash -euxc '[[ $INVOCATION_ID == "$(systemd-id128 invo
|
||||
(! systemd-id128 invocation-id -a 4f68bce3e8cd4db196e7fbcaf984b709)
|
||||
(! systemd-id128 show '')
|
||||
(! systemd-id128 show "$(set +x; printf '%0.s0' {0..64})")
|
||||
(! systemd-id128 show root --pretty --json=short)
|
||||
(! systemd-id128 show root usr --value --json=short)
|
||||
|
||||
Reference in New Issue
Block a user