]> git.ipfire.org Git - thirdparty/kernel/stable.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>
Mon, 24 Oct 2022 07:57:12 +0000 (09:57 +0200)
[ Upstream commit 712f210a457d9c32414df246a72781550bc23ef6 ]

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: 757885e94a22 ("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 0c3d3440fe27876c0438d16d9dead603498ea3e8..aa675783412f84e6d5c241844b46977204daabcf 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 8b2fcdfa6d316816d0db2b1f46cd1f9cc8120ff4..615bc6efa1dd42c7fe39f6c9713190541f317faf 100644 (file)
@@ -788,6 +788,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;
@@ -869,7 +870,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;
 }