diff options
| author | Borislav Petkov <bp@suse.de> | 2015-02-05 14:11:41 -0500 |
|---|---|---|
| committer | Borislav Petkov <bp@suse.de> | 2015-03-02 14:31:11 -0500 |
| commit | f9524e6f5447277e238b419afc3d0712941fa2a5 (patch) | |
| tree | b29d83d16599c077b541bf941d594e628cba3611 /arch/x86/kernel/cpu/microcode | |
| parent | 776d3cdc93d83808bf5929d716a56c69bbe01d2f (diff) | |
x86/microcode/intel: Do the mc_saved_src NULL check first
... and only then deref it. Also, shorten some variable names and rename
others so as to diminish the ubiquitous presence of the "mc_" prefix
everywhere and make it a bit more readable.
Use kcalloc so that we don't kfree() uninitialized memory on the unwind
path, as suggested by Quentin.
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Quentin Casasnovas <quentin.casasnovas@oracle.com>
Diffstat (limited to 'arch/x86/kernel/cpu/microcode')
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/intel_early.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/arch/x86/kernel/cpu/microcode/intel_early.c b/arch/x86/kernel/cpu/microcode/intel_early.c index d515ff3feb8b..95516006958d 100644 --- a/arch/x86/kernel/cpu/microcode/intel_early.c +++ b/arch/x86/kernel/cpu/microcode/intel_early.c | |||
| @@ -203,7 +203,7 @@ save_microcode(struct mc_saved_data *mc_saved_data, | |||
| 203 | unsigned int mc_saved_count) | 203 | unsigned int mc_saved_count) |
| 204 | { | 204 | { |
| 205 | int i, j; | 205 | int i, j; |
| 206 | struct microcode_intel **mc_saved_p; | 206 | struct microcode_intel **saved_ptr; |
| 207 | int ret; | 207 | int ret; |
| 208 | 208 | ||
| 209 | if (!mc_saved_count) | 209 | if (!mc_saved_count) |
| @@ -212,39 +212,45 @@ save_microcode(struct mc_saved_data *mc_saved_data, | |||
| 212 | /* | 212 | /* |
| 213 | * Copy new microcode data. | 213 | * Copy new microcode data. |
| 214 | */ | 214 | */ |
| 215 | mc_saved_p = kmalloc(mc_saved_count*sizeof(struct microcode_intel *), | 215 | saved_ptr = kcalloc(mc_saved_count, sizeof(struct microcode_intel *), GFP_KERNEL); |
| 216 | GFP_KERNEL); | 216 | if (!saved_ptr) |
| 217 | if (!mc_saved_p) | ||
| 218 | return -ENOMEM; | 217 | return -ENOMEM; |
| 219 | 218 | ||
| 220 | for (i = 0; i < mc_saved_count; i++) { | 219 | for (i = 0; i < mc_saved_count; i++) { |
| 221 | struct microcode_intel *mc = mc_saved_src[i]; | 220 | struct microcode_header_intel *mc_hdr; |
| 222 | struct microcode_header_intel *mc_header = &mc->hdr; | 221 | struct microcode_intel *mc; |
| 223 | unsigned long mc_size = get_totalsize(mc_header); | 222 | unsigned long size; |
| 224 | mc_saved_p[i] = kmalloc(mc_size, GFP_KERNEL); | 223 | |
| 225 | if (!mc_saved_p[i]) { | ||
| 226 | ret = -ENOMEM; | ||
| 227 | goto err; | ||
| 228 | } | ||
| 229 | if (!mc_saved_src[i]) { | 224 | if (!mc_saved_src[i]) { |
| 230 | ret = -EINVAL; | 225 | ret = -EINVAL; |
| 231 | goto err; | 226 | goto err; |
| 232 | } | 227 | } |
| 233 | memcpy(mc_saved_p[i], mc, mc_size); | 228 | |
| 229 | mc = mc_saved_src[i]; | ||
| 230 | mc_hdr = &mc->hdr; | ||
| 231 | size = get_totalsize(mc_hdr); | ||
| 232 | |||
| 233 | saved_ptr[i] = kmalloc(size, GFP_KERNEL); | ||
| 234 | if (!saved_ptr[i]) { | ||
| 235 | ret = -ENOMEM; | ||
| 236 | goto err; | ||
| 237 | } | ||
| 238 | |||
| 239 | memcpy(saved_ptr[i], mc, size); | ||
| 234 | } | 240 | } |
| 235 | 241 | ||
| 236 | /* | 242 | /* |
| 237 | * Point to newly saved microcode. | 243 | * Point to newly saved microcode. |
| 238 | */ | 244 | */ |
| 239 | mc_saved_data->mc_saved = mc_saved_p; | 245 | mc_saved_data->mc_saved = saved_ptr; |
| 240 | mc_saved_data->mc_saved_count = mc_saved_count; | 246 | mc_saved_data->mc_saved_count = mc_saved_count; |
| 241 | 247 | ||
| 242 | return 0; | 248 | return 0; |
| 243 | 249 | ||
| 244 | err: | 250 | err: |
| 245 | for (j = 0; j <= i; j++) | 251 | for (j = 0; j <= i; j++) |
| 246 | kfree(mc_saved_p[j]); | 252 | kfree(saved_ptr[j]); |
| 247 | kfree(mc_saved_p); | 253 | kfree(saved_ptr); |
| 248 | 254 | ||
| 249 | return ret; | 255 | return ret; |
| 250 | } | 256 | } |
