Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa78c1cc authored by Borislav Petkov's avatar Borislav Petkov Committed by Thomas Gleixner
Browse files

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: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: kernel-janitors@vger.kernel.org
Link: http://lkml.kernel.org/r/20170825100456.n236w3jebteokfd6@pd.tnic
parent 0e325875
Loading
Loading
Loading
Loading
+14 −13
Original line number Diff line number Diff line
@@ -146,18 +146,18 @@ static bool microcode_matches(struct microcode_header_intel *mc_header,
	return false;
}

static struct ucode_patch *__alloc_microcode_buf(void *data, unsigned int size)
static struct ucode_patch *memdup_patch(void *data, unsigned int size)
{
	struct ucode_patch *p;

	p = kzalloc(sizeof(struct ucode_patch), GFP_KERNEL);
	if (!p)
		return ERR_PTR(-ENOMEM);
		return NULL;

	p->data = kmemdup(data, size, GFP_KERNEL);
	if (!p->data) {
		kfree(p);
		return ERR_PTR(-ENOMEM);
		return NULL;
	}

	return p;
@@ -183,8 +183,8 @@ static void save_microcode_patch(void *data, unsigned int size)
			if (mc_hdr->rev <= mc_saved_hdr->rev)
				continue;

			p = __alloc_microcode_buf(data, size);
			if (IS_ERR(p))
			p = memdup_patch(data, size);
			if (!p)
				pr_err("Error allocating buffer %p\n", data);
			else
				list_replace(&iter->plist, &p->plist);
@@ -196,25 +196,26 @@ static void save_microcode_patch(void *data, unsigned int size)
	 * newly found.
	 */
	if (!prev_found) {
		p = __alloc_microcode_buf(data, size);
		if (IS_ERR(p))
		p = memdup_patch(data, size);
		if (!p)
			pr_err("Error allocating buffer for %p\n", data);
		else
			list_add_tail(&p->plist, &microcode_cache);
	}

	if (!p)
		return;

	/*
	 * Save for early loading. On 32-bit, that needs to be a physical
	 * address as the APs are running from physical addresses, before
	 * paging has been enabled.
	 */
	if (p) {
	if (IS_ENABLED(CONFIG_X86_32))
		intel_ucode_patch = (struct microcode_intel *)__pa_nodebug(p->data);
	else
		intel_ucode_patch = p->data;
}
}

static int microcode_sanity_check(void *mc, int print_err)
{