diff options
author | David Teigland <teigland@redhat.com> | 2021-06-29 12:40:03 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2021-07-06 10:10:23 -0500 |
commit | b876dbfc245b8fe0a4c433b39d214652455c3f9e (patch) | |
tree | 25b2ececc0695db6010572f54447b8fa8f627078 /lib/config | |
parent | e035e323508383fdcd9df0ef036d276a9c9909ab (diff) | |
download | lvm2-b876dbfc245b8fe0a4c433b39d214652455c3f9e.tar.gz |
scan: move metadata vgname check
There have been two separate checks for metadata
validity: first that the metadata text begins with
a valid VG name, and second the checksum of the
metadata text. These happen in different places,
which means there have been two separate error paths
for invalid metadata. This also causes large metadata
to be read in multiple parts, the first part is read
just to check the vgname, and then remaining parts are
read later when the full metadata is needed.
This patch moves the vg name verification so it's
done just before the checksum verification, which
results in a single error path for invalid metadata,
and causes the entire metadata to be read together
rather that in parts from different parts of the code.
Diffstat (limited to 'lib/config')
-rw-r--r-- | lib/config/config.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/lib/config/config.c b/lib/config/config.c index 485063a3d..25a87c983 100644 --- a/lib/config/config.c +++ b/lib/config/config.c @@ -501,6 +501,9 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r checksum_fn_t checksum_fn, uint32_t checksum, int checksum_only, int no_dup_node_check) { + char namebuf[NAME_LEN + 1] __attribute__((aligned(8))); + int namelen = 0; + int bad_name = 0; char *fb, *fe; int r = 0; int sz, use_plain_read = 1; @@ -548,6 +551,23 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r fb = buf; + if (!(dev->flags & DEV_REGULAR)) { + memcpy(namebuf, buf, NAME_LEN); + + while (namebuf[namelen] && !isspace(namebuf[namelen]) && namebuf[namelen] != '{' && namelen < (NAME_LEN - 1)) + namelen++; + namebuf[namelen] = '\0'; + + /* + * Check that the text metadata begins with a valid name. + */ + if (!validate_name(namebuf)) { + log_warn("WARNING: Metadata location on %s at offset %llu begins with invalid name.", + dev_name(dev), (unsigned long long)offset); + bad_name = 1; + } + } + /* * The checksum passed in is the checksum from the mda_header * preceding this metadata. They should always match. @@ -557,10 +577,13 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r if (checksum_fn && checksum != (checksum_fn(checksum_fn(INITIAL_CRC, (const uint8_t *)fb, size), (const uint8_t *)(fb + size), size2))) { - log_error("%s: Checksum error at offset %" PRIu64, dev_name(dev), (uint64_t) offset); + log_warn("WARNING: Checksum error on %s at offset %llu.", dev_name(dev), (unsigned long long)offset); goto out; } + if (bad_name) + goto out; + if (!checksum_only) { fe = fb + size + size2; if (no_dup_node_check) { |