diff options
author | Andreas Herrmann <andreas.herrmann3@amd.com> | 2012-07-31 09:41:45 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-08-22 19:10:41 -0400 |
commit | 36bf50d7697be18c6bfd0401e037df10bff1e573 (patch) | |
tree | e32aeb6e6077c3eecc569f9f2ad4f393ba8b63d8 /arch/x86 | |
parent | cb09cad44f07044d9810f18f6f9a6a6f3771f979 (diff) |
x86, microcode, AMD: Fix broken ucode patch size check
This issue was recently observed on an AMD C-50 CPU where a patch of
maximum size was applied.
Commit be62adb49294 ("x86, microcode, AMD: Simplify ucode verification")
added current_size in get_matching_microcode(). This is calculated as
size of the ucode patch + 8 (ie. size of the header). Later this is
compared against the maximum possible ucode patch size for a CPU family.
And of course this fails if the patch has already maximum size.
Cc: <stable@vger.kernel.org> [3.3+]
Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Link: http://lkml.kernel.org/r/1344361461-10076-1-git-send-email-bp@amd64.org
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/microcode_amd.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 8a2ce8fd41c0..82746f942cd8 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c | |||
@@ -143,11 +143,12 @@ static int get_matching_microcode(int cpu, const u8 *ucode_ptr, | |||
143 | unsigned int *current_size) | 143 | unsigned int *current_size) |
144 | { | 144 | { |
145 | struct microcode_header_amd *mc_hdr; | 145 | struct microcode_header_amd *mc_hdr; |
146 | unsigned int actual_size; | 146 | unsigned int actual_size, patch_size; |
147 | u16 equiv_cpu_id; | 147 | u16 equiv_cpu_id; |
148 | 148 | ||
149 | /* size of the current patch we're staring at */ | 149 | /* size of the current patch we're staring at */ |
150 | *current_size = *(u32 *)(ucode_ptr + 4) + SECTION_HDR_SIZE; | 150 | patch_size = *(u32 *)(ucode_ptr + 4); |
151 | *current_size = patch_size + SECTION_HDR_SIZE; | ||
151 | 152 | ||
152 | equiv_cpu_id = find_equiv_id(); | 153 | equiv_cpu_id = find_equiv_id(); |
153 | if (!equiv_cpu_id) | 154 | if (!equiv_cpu_id) |
@@ -174,7 +175,7 @@ static int get_matching_microcode(int cpu, const u8 *ucode_ptr, | |||
174 | /* | 175 | /* |
175 | * now that the header looks sane, verify its size | 176 | * now that the header looks sane, verify its size |
176 | */ | 177 | */ |
177 | actual_size = verify_ucode_size(cpu, *current_size, leftover_size); | 178 | actual_size = verify_ucode_size(cpu, patch_size, leftover_size); |
178 | if (!actual_size) | 179 | if (!actual_size) |
179 | return 0; | 180 | return 0; |
180 | 181 | ||