]> git.baikalelectronics.ru Git - kernel.git/commitdiff
x86/microcode/AMD: Track patch allocation size explicitly
authorKees Cook <keescook@chromium.org>
Thu, 22 Sep 2022 03:10:10 +0000 (20:10 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 26 Oct 2022 11:22:24 +0000 (13:22 +0200)
[ Upstream commit a0ea8b804aa69e8e5a6aa3e26c646aaa51727b45 ]

In preparation for reducing the use of ksize(), record the actual
allocation size for later memcpy(). This avoids copying extra
(uninitialized!) bytes into the patch buffer when the requested
allocation size isn't exactly the size of a kmalloc bucket.
Additionally, fix potential future issues where runtime bounds checking
will notice that the buffer was allocated to a smaller value than
returned by ksize().

Fixes: 4487451a80f5 ("x86, microcode, amd: Early microcode patch loading support for AMD")
Suggested-by: Daniel Micay <danielmicay@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/lkml/CA+DvKQ+bp7Y7gmaVhacjv9uF6Ar-o4tet872h4Q8RPYPJjcJQA@mail.gmail.com/
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/x86/include/asm/microcode.h
arch/x86/kernel/cpu/microcode/amd.c

index 91a06cef50c1b85bd3628b93fe13ef54db06ff73..f73327397b898a3b0ec7cb801bd16070324b6894 100644 (file)
@@ -9,6 +9,7 @@
 struct ucode_patch {
        struct list_head plist;
        void *data;             /* Intel uses only this one */
+       unsigned int size;
        u32 patch_id;
        u16 equiv_cpu;
 };
index a0e52bd00ecceeaed98f61b36fd51de6543f140d..3b82d022dcd43acbc861f306db0ecacc62e9c181 100644 (file)
@@ -783,6 +783,7 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover,
                kfree(patch);
                return -EINVAL;
        }
+       patch->size = *patch_size;
 
        mc_hdr      = (struct microcode_header_amd *)(fw + SECTION_HDR_SIZE);
        proc_id     = mc_hdr->processor_rev_id;
@@ -864,7 +865,7 @@ load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
                return ret;
 
        memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
-       memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), PATCH_MAX_SIZE));
+       memcpy(amd_ucode_patch, p->data, min_t(u32, p->size, PATCH_MAX_SIZE));
 
        return ret;
 }