Re: [PATCH v2 10/14] platform/x86/intel/ifs: Add metadata validation

Borislav Petkov
2022-11-11T18:42:36Z

On Mon, Nov 07, 2022 at 02:53:19PM -0800, Jithu Joseph wrote:
> diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/intel/ifs/load.c
> index 7c0d8602817b..f361fd42a320 100644
> --- a/drivers/platform/x86/intel/ifs/load.c
> +++ b/drivers/platform/x86/intel/ifs/load.c
> @@ -8,7 +8,23 @@
>
> #include "ifs.h"
>
> +struct meta_data {
> + unsigned int meta_type; // metadata type
> + unsigned int meta_size; // size of this entire struct including hdrs.
> + unsigned int test_type; // IFS test type
> + unsigned int fusa_info; // Fusa info
> + unsigned int total_images; // Total number of images
> + unsigned int current_image; // Current Image #
> + unsigned int total_chunks; // Total number of chunks in this image
> + unsigned int starting_chunk; // Starting chunk number in this image
> + unsigned int size_per_chunk; // size of each chunk
> + unsigned int chunks_per_stride; // number of chunks in a stride
> + unsigned int reserved[54]; // Align to 256 bytes for chunk alignment.

That looks weird.

__packed and __aligned doesn't work?

> #define IFS_HEADER_SIZE (sizeof(struct microcode_header_intel))
> +#define META_TYPE_IFS 1
> +#define IFS_CHUNK_ALIGNMENT 256
> static struct microcode_header_intel *ifs_header_ptr; /* pointer to the ifs image header */
> static u64 ifs_hash_ptr; /* Address of ifs metadata (hash) */
> static u64 ifs_test_image_ptr; /* 256B aligned address of test pattern */
> @@ -129,6 +145,40 @@ static void copy_hashes_authenticate_chunks(struct work_struct *work)
> complete(&ifs_done);
> }
>
> +static int validate_ifs_metadata(struct device *dev)
> +{
> + struct ifs_data *ifsd = ifs_get_data(dev);
> + struct meta_data *ifs_meta;
> + char test_file[64];
> + int ret = -EINVAL;
> +
> + snprintf(test_file, sizeof(test_file), "%02x-%02x-%02x-%02x.scan",
> + boot_cpu_data.x86, boot_cpu_data.x86_model,
> + boot_cpu_data.x86_stepping, ifsd->cur_batch);
> +
> + ifs_meta = (struct meta_data *)ifs_find_meta_data(ifs_header_ptr, META_TYPE_IFS);
> + if (!ifs_meta) {
> + dev_err(dev, "IFS Metadata missing in file %s\n", test_file);
> + return ret;
> + }
> +
> + ifs_test_image_ptr = (u64)ifs_meta + sizeof(struct meta_data);
> +
> + /* Scan chunk start must be 256 byte aligned */
> + if (!IS_ALIGNED(ifs_test_image_ptr, IFS_CHUNK_ALIGNMENT)) {
> + dev_err(dev, "Scan pattern offset is not 256 byte aligned in %s\n", test_file);

" ... is not aligned on %d bytes...\n", test_file, IFS_CHUNK_ALIGNMENT);

> + return ret;
> + }
> +
> + if (ifs_meta->current_image != ifsd->cur_batch) {
> + dev_warn(dev, "Mismatch between filename %s and batch metadata 0x%02x\n",
> + test_file, ifs_meta->current_image);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> /*
> * IFS requires scan chunks authenticated per each socket in the platform.
> * Once the test chunk is authenticated, it is automatically copied to secured memory
> @@ -145,6 +195,9 @@ static int scan_chunks_sanity_check(struct device *dev)
> if (!package_authenticated)
> return ret;
>
> + ret = validate_ifs_metadata(dev);
> + if (ret)
> + return ret;

Right, if you return here because validate_ifs_metadata() failed for
whatever reason, you leak package_authenticated. That's why, as I said
earlier, you should just use a stack variable where you simply set a
bit. A bitmask or so.

--
Regards/Gruss,
Boris.