diff options
author | Borislav Petkov <bp@suse.de> | 2017-08-25 06:04:56 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-08-29 04:59:28 -0400 |
commit | aa78c1ccfab6018289bc2bfd0092d516d0a49ec5 (patch) | |
tree | e5a03ca7cf4701486be7c2c79c390095849f1537 /arch/x86/kernel/cpu/microcode/intel.c | |
parent | 0e3258753f8183c63bf68bd274d2cc7e71e5f402 (diff) |
x86/microcode/intel: Improve microcode patches saving flow
Avoid potentially dereferencing a NULL pointer when saving a microcode
patch for early loading on the application processors.
While at it, drop the IS_ERR() checking in favor of simpler, NULL-ptr
checks which are sufficient and rename __alloc_microcode_buf() to
memdup_patch() to more precisely denote what it does.
No functionality change.
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: kernel-janitors@vger.kernel.org
Link: http://lkml.kernel.org/r/20170825100456.n236w3jebteokfd6@pd.tnic
Diffstat (limited to 'arch/x86/kernel/cpu/microcode/intel.c')
-rw-r--r-- | arch/x86/kernel/cpu/microcode/intel.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 59edbe9d4ccb..8f7a9bbad514 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c | |||
@@ -146,18 +146,18 @@ static bool microcode_matches(struct microcode_header_intel *mc_header, | |||
146 | return false; | 146 | return false; |
147 | } | 147 | } |
148 | 148 | ||
149 | static struct ucode_patch *__alloc_microcode_buf(void *data, unsigned int size) | 149 | static struct ucode_patch *memdup_patch(void *data, unsigned int size) |
150 | { | 150 | { |
151 | struct ucode_patch *p; | 151 | struct ucode_patch *p; |
152 | 152 | ||
153 | p = kzalloc(sizeof(struct ucode_patch), GFP_KERNEL); | 153 | p = kzalloc(sizeof(struct ucode_patch), GFP_KERNEL); |
154 | if (!p) | 154 | if (!p) |
155 | return ERR_PTR(-ENOMEM); | 155 | return NULL; |
156 | 156 | ||
157 | p->data = kmemdup(data, size, GFP_KERNEL); | 157 | p->data = kmemdup(data, size, GFP_KERNEL); |
158 | if (!p->data) { | 158 | if (!p->data) { |
159 | kfree(p); | 159 | kfree(p); |
160 | return ERR_PTR(-ENOMEM); | 160 | return NULL; |
161 | } | 161 | } |
162 | 162 | ||
163 | return p; | 163 | return p; |
@@ -183,8 +183,8 @@ static void save_microcode_patch(void *data, unsigned int size) | |||
183 | if (mc_hdr->rev <= mc_saved_hdr->rev) | 183 | if (mc_hdr->rev <= mc_saved_hdr->rev) |
184 | continue; | 184 | continue; |
185 | 185 | ||
186 | p = __alloc_microcode_buf(data, size); | 186 | p = memdup_patch(data, size); |
187 | if (IS_ERR(p)) | 187 | if (!p) |
188 | pr_err("Error allocating buffer %p\n", data); | 188 | pr_err("Error allocating buffer %p\n", data); |
189 | else | 189 | else |
190 | list_replace(&iter->plist, &p->plist); | 190 | list_replace(&iter->plist, &p->plist); |
@@ -196,24 +196,25 @@ static void save_microcode_patch(void *data, unsigned int size) | |||
196 | * newly found. | 196 | * newly found. |
197 | */ | 197 | */ |
198 | if (!prev_found) { | 198 | if (!prev_found) { |
199 | p = __alloc_microcode_buf(data, size); | 199 | p = memdup_patch(data, size); |
200 | if (IS_ERR(p)) | 200 | if (!p) |
201 | pr_err("Error allocating buffer for %p\n", data); | 201 | pr_err("Error allocating buffer for %p\n", data); |
202 | else | 202 | else |
203 | list_add_tail(&p->plist, µcode_cache); | 203 | list_add_tail(&p->plist, µcode_cache); |
204 | } | 204 | } |
205 | 205 | ||
206 | if (!p) | ||
207 | return; | ||
208 | |||
206 | /* | 209 | /* |
207 | * Save for early loading. On 32-bit, that needs to be a physical | 210 | * Save for early loading. On 32-bit, that needs to be a physical |
208 | * address as the APs are running from physical addresses, before | 211 | * address as the APs are running from physical addresses, before |
209 | * paging has been enabled. | 212 | * paging has been enabled. |
210 | */ | 213 | */ |
211 | if (p) { | 214 | if (IS_ENABLED(CONFIG_X86_32)) |
212 | if (IS_ENABLED(CONFIG_X86_32)) | 215 | intel_ucode_patch = (struct microcode_intel *)__pa_nodebug(p->data); |
213 | intel_ucode_patch = (struct microcode_intel *)__pa_nodebug(p->data); | 216 | else |
214 | else | 217 | intel_ucode_patch = p->data; |
215 | intel_ucode_patch = p->data; | ||
216 | } | ||
217 | } | 218 | } |
218 | 219 | ||
219 | static int microcode_sanity_check(void *mc, int print_err) | 220 | static int microcode_sanity_check(void *mc, int print_err) |