linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Intel CPU Microcode Update Driver: Fix double vfree() and remove redundant pointer checks before vfree()
@ 2010-12-25 18:57 Jesper Juhl
       [not found] ` <AANLkTimPTSwpyj-uNJ9TpDwGjWaodAupr_7VA_Oe1=m4@mail.gmail.com>
  2010-12-27 14:16 ` [tip:x86/urgent] x86/microcode: " tip-bot for Jesper Juhl
  0 siblings, 2 replies; 4+ messages in thread
From: Jesper Juhl @ 2010-12-25 18:57 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, H. Peter Anvin, Ingo Molnar, Thomas Gleixner,
	Tigran Aivazian, Shaohua Li, Tigran Aivazian

Hi,

In arch/x86/kernel/microcode_intel.c::generic_load_microcode() we have 
this:

	while (leftover) {
		...
		if (get_ucode_data(mc, ucode_ptr, mc_size) ||
		    microcode_sanity_check(mc) < 0) {
			vfree(mc);
			break;
		}
		...
	}

	if (mc)
		vfree(mc);

This will cause a double free of 'mc'. This patch fixes that by just 
removing the vfree() call in the loop since 'mc' will be freed nicely just 
after we break out of the loop.

There's also a second change in the patch. I noticed a lot of checks for 
pointers being NULL before passing them to vfree(). That's completely 
redundant since vfree() deals gracefully with being passed a NULL pointer. 
Removing the redundant checks yields a nice size decrease for the object 
file.

Size before the patch:
   text    data     bss     dec     hex filename
   4578     240    1032    5850    16da arch/x86/kernel/microcode_intel.o
Size after the patch:
   text    data     bss     dec     hex filename
   4489     240     984    5713    1651 arch/x86/kernel/microcode_intel.o


Signed-off-by: Jesper Juhl <jj@chaosbits.net>
---
 microcode_intel.c |   16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index dcb65cc..1a1b606 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -364,8 +364,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
 
 		/* For performance reasons, reuse mc area when possible */
 		if (!mc || mc_size > curr_mc_size) {
-			if (mc)
-				vfree(mc);
+			vfree(mc);
 			mc = vmalloc(mc_size);
 			if (!mc)
 				break;
@@ -374,13 +373,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
 
 		if (get_ucode_data(mc, ucode_ptr, mc_size) ||
 		    microcode_sanity_check(mc) < 0) {
-			vfree(mc);
 			break;
 		}
 
 		if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) {
-			if (new_mc)
-				vfree(new_mc);
+			vfree(new_mc);
 			new_rev = mc_header.rev;
 			new_mc  = mc;
 			mc = NULL;	/* trigger new vmalloc */
@@ -390,12 +387,10 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
 		leftover  -= mc_size;
 	}
 
-	if (mc)
-		vfree(mc);
+	vfree(mc);
 
 	if (leftover) {
-		if (new_mc)
-			vfree(new_mc);
+		vfree(new_mc);
 		state = UCODE_ERROR;
 		goto out;
 	}
@@ -405,8 +400,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
 		goto out;
 	}
 
-	if (uci->mc)
-		vfree(uci->mc);
+	vfree(uci->mc);
 	uci->mc = (struct microcode_intel *)new_mc;
 
 	pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",



-- 
Jesper Juhl <jj@chaosbits.net>            http://www.chaosbits.net/
Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
Plain text mails only, please.


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] Intel CPU Microcode Update Driver: Fix double vfree() and remove redundant pointer checks before vfree()
       [not found] ` <AANLkTimPTSwpyj-uNJ9TpDwGjWaodAupr_7VA_Oe1=m4@mail.gmail.com>
@ 2010-12-27 13:30   ` Ingo Molnar
  0 siblings, 0 replies; 4+ messages in thread
From: Ingo Molnar @ 2010-12-27 13:30 UTC (permalink / raw)
  To: Tigran Aivazian
  Cc: Jesper Juhl, linux-kernel, x86, H. Peter Anvin, Ingo Molnar,
	Thomas Gleixner, Shaohua Li


* Tigran Aivazian <tigran@bibles.org.uk> wrote:

> Hi Jesper,
> 
> Your patch looks fine to me.

Thanks - i'll add that as a:

Acked-by: Tigran Aivazian <tigran@aivazian.fsnet.co.uk>

ok?

	Ingo

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [tip:x86/urgent] x86/microcode: Fix double vfree() and remove redundant pointer checks before vfree()
  2010-12-25 18:57 [PATCH] Intel CPU Microcode Update Driver: Fix double vfree() and remove redundant pointer checks before vfree() Jesper Juhl
       [not found] ` <AANLkTimPTSwpyj-uNJ9TpDwGjWaodAupr_7VA_Oe1=m4@mail.gmail.com>
@ 2010-12-27 14:16 ` tip-bot for Jesper Juhl
  2010-12-28  2:28   ` Henrique de Moraes Holschuh
  1 sibling, 1 reply; 4+ messages in thread
From: tip-bot for Jesper Juhl @ 2010-12-27 14:16 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, jj, tigran, shaohua.li, tglx, mingo

Commit-ID:  5cdd2de0a76d0ac47f107c8a7b32d75d25768dc1
Gitweb:     http://git.kernel.org/tip/5cdd2de0a76d0ac47f107c8a7b32d75d25768dc1
Author:     Jesper Juhl <jj@chaosbits.net>
AuthorDate: Sat, 25 Dec 2010 19:57:41 +0100
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Mon, 27 Dec 2010 14:33:30 +0100

x86/microcode: Fix double vfree() and remove redundant pointer checks before vfree()

In arch/x86/kernel/microcode_intel.c::generic_load_microcode()
we have  this:

	while (leftover) {
		...
		if (get_ucode_data(mc, ucode_ptr, mc_size) ||
		    microcode_sanity_check(mc) < 0) {
			vfree(mc);
			break;
		}
		...
	}

	if (mc)
		vfree(mc);

This will cause a double free of 'mc'. This patch fixes that by
just  removing the vfree() call in the loop since 'mc' will be
freed nicely just  after we break out of the loop.

There's also a second change in the patch. I noticed a lot of
checks for  pointers being NULL before passing them to vfree().
That's completely  redundant since vfree() deals gracefully with
being passed a NULL pointer.  Removing the redundant checks
yields a nice size decrease for the object  file.

Size before the patch:
   text    data     bss     dec     hex filename
   4578     240    1032    5850    16da arch/x86/kernel/microcode_intel.o
Size after the patch:
   text    data     bss     dec     hex filename
   4489     240     984    5713    1651 arch/x86/kernel/microcode_intel.o

Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Acked-by: Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
Cc: Shaohua Li <shaohua.li@intel.com>
LKML-Reference: <alpine.LNX.2.00.1012251946100.10759@swampdragon.chaosbits.net>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 arch/x86/kernel/microcode_intel.c |   16 +++++-----------
 1 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index dcb65cc..1a1b606 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -364,8 +364,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
 
 		/* For performance reasons, reuse mc area when possible */
 		if (!mc || mc_size > curr_mc_size) {
-			if (mc)
-				vfree(mc);
+			vfree(mc);
 			mc = vmalloc(mc_size);
 			if (!mc)
 				break;
@@ -374,13 +373,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
 
 		if (get_ucode_data(mc, ucode_ptr, mc_size) ||
 		    microcode_sanity_check(mc) < 0) {
-			vfree(mc);
 			break;
 		}
 
 		if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) {
-			if (new_mc)
-				vfree(new_mc);
+			vfree(new_mc);
 			new_rev = mc_header.rev;
 			new_mc  = mc;
 			mc = NULL;	/* trigger new vmalloc */
@@ -390,12 +387,10 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
 		leftover  -= mc_size;
 	}
 
-	if (mc)
-		vfree(mc);
+	vfree(mc);
 
 	if (leftover) {
-		if (new_mc)
-			vfree(new_mc);
+		vfree(new_mc);
 		state = UCODE_ERROR;
 		goto out;
 	}
@@ -405,8 +400,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
 		goto out;
 	}
 
-	if (uci->mc)
-		vfree(uci->mc);
+	vfree(uci->mc);
 	uci->mc = (struct microcode_intel *)new_mc;
 
 	pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [tip:x86/urgent] x86/microcode: Fix double vfree() and remove redundant pointer checks before vfree()
  2010-12-27 14:16 ` [tip:x86/urgent] x86/microcode: " tip-bot for Jesper Juhl
@ 2010-12-28  2:28   ` Henrique de Moraes Holschuh
  0 siblings, 0 replies; 4+ messages in thread
From: Henrique de Moraes Holschuh @ 2010-12-28  2:28 UTC (permalink / raw)
  To: mingo, hpa, linux-kernel, jj, tigran, tglx, shaohua.li, mingo

On Mon, 27 Dec 2010, tip-bot for Jesper Juhl wrote:
> In arch/x86/kernel/microcode_intel.c::generic_load_microcode()
> we have  this:
> 
> 	while (leftover) {
> 		...
> 		if (get_ucode_data(mc, ucode_ptr, mc_size) ||
> 		    microcode_sanity_check(mc) < 0) {
> 			vfree(mc);
> 			break;
> 		}
> 		...
> 	}
> 
> 	if (mc)
> 		vfree(mc);

Which is trivial to trigger from userspace, fortunately limited to root in
any sane distro (and by default).

Please send it to -stable after it gets merged in mainline and is deemed
safe...

The Intel microcode driver will also accept a bogus microcode which has a
valid header, but all zeros for the cyphertext.  This is a design defect on
the current Intel microcode format, but can be worked around by the driver
if one assumes such a cyphertext will never be valid (seems like a safe
assumption).  I sure hope the processors will reject that kind of bogosity
even if the kernel doesn't and tries to upload it, though...  I was not
crazy enough to try.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2010-12-28  2:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-25 18:57 [PATCH] Intel CPU Microcode Update Driver: Fix double vfree() and remove redundant pointer checks before vfree() Jesper Juhl
     [not found] ` <AANLkTimPTSwpyj-uNJ9TpDwGjWaodAupr_7VA_Oe1=m4@mail.gmail.com>
2010-12-27 13:30   ` Ingo Molnar
2010-12-27 14:16 ` [tip:x86/urgent] x86/microcode: " tip-bot for Jesper Juhl
2010-12-28  2:28   ` Henrique de Moraes Holschuh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).