Fix use-after-free in acpi_map_lsapic
PATCH 1/1 Fix use-after-free in acpi_map_lsapic
From: Petr Vandrovec <[email protected]>
When processor is being hot-added to the system, acpi_map_lsapic invokes ACPI _MAT method to find APIC ID and flags, verifies that returned structure is indeed ACPI's local APIC structure, and that flags contain MADT_ENABLED bit. Then saves APIC ID, frees structure - and accesses structure when computing arguments for acpi_register_lapic call. Which sometime leads to acpi_register_lapic call being made with second argument zero, failing to bring processor online with error 'Unable to map lapic to logical cpu number'.
As lapic->lapic_flags & ACPI_MADT_ENABLED was already confirmed to be non-zero few lines above, we can just pass unconditional ACPI_MADT_ENABLED to the acpi_register_lapic.
Thanks, Petr
arch/x86/kernel/acpi/boot.c +1 -1
@@ -650,7 +650,7 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) goto free_tmp_map;cpumask_copy (tmp_map, cpu_present_mask); -acpi_register_lapic (physid, lapic->lapic_flags &ACPI_MADT_ENABLED ); +acpi_register_lapic (physid,ACPI_MADT_ENABLED );/* * If mp_register_lapic successfully generates a new logical cpu
Len, anyone else,
Any comments on this one ? This fixes a important bug during cpu hotadd where the kernel fails to recognize all the newly added cpus.
Thanks,
Alok
Quoted 34 lines · Petr Vandrovec
From: Petr Vandrovec <[email protected]>
When processor is being hot-added to the system,
acpi_map_lsapicinvokes ACPI_MATmethod to find APIC ID and flags, verifies that returned structure is indeed ACPI's local APIC structure, and that flags containMADT_ENABLEDbit. Then saves APIC ID, frees structure - and accesses structure when computing arguments foracpi_register_lapiccall. Which sometime leads toacpi_register_lapiccall being made with second argument zero, failing to bring processor online with error 'Unable to map lapic to logical cpu number'.As
lapic->lapic_flags&ACPI_MADT_ENABLEDwas already confirmed to be non-zero few lines above, we can just pass unconditionalACPI_MADT_ENABLEDto theacpi_register_lapic.Thanks, Petr
Signed-off-by Petr Vandrovec <[email protected]>Signed-off-by Alok Kataria <[email protected]>arch/x86/kernel/acpi/boot.c +1
-1@@ -650,7 +650,7 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) goto free_tmp_map;cpumask_copy (tmp_map, cpu_present_mask); -acpi_register_lapic (physid, lapic->lapic_flags &ACPI_MADT_ENABLED ); +acpi_register_lapic (physid,ACPI_MADT_ENABLED );/* * If mp_register_lapic successfully generates a new logical cpu
Quoted 38 lines · Alok Kataria
Len, anyone else,
Any comments on this one ? This fixes a important bug during cpu hotadd where the kernel fails to recognize all the newly added cpus.
Thanks,
AlokQuoted 28 lines · Petr Vandrovec
From: Petr Vandrovec <[email protected]>
When processor is being hot-added to the system,
acpi_map_lsapicinvokes ACPI_MATmethod to find APIC ID and flags, verifies that returned structure is indeed ACPI's local APIC structure, and that flags containMADT_ENABLEDbit. Then saves APIC ID, frees structure - and accesses structure when computing arguments foracpi_register_lapiccall. Which sometime leads toacpi_register_lapiccall being made with second argument zero, failing to bring processor online with error 'Unable to map lapic to logical cpu number'.As
lapic->lapic_flags&ACPI_MADT_ENABLEDwas already confirmed to be non-zero few lines above, we can just pass unconditionalACPI_MADT_ENABLEDto theacpi_register_lapic.Thanks, Petr
Signed-off-by Petr Vandrovec <[email protected]>Signed-off-by Alok Kataria <[email protected]>arch/x86/kernel/acpi/boot.c +0
-0@@ -650,7 +650,7 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) goto free_tmp_map;
Quoted 3 lines
arch/x86/kernel/acpi/boot.c static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) · line 653
Quoted 3 lines
arch/x86/kernel/acpi/boot.c +1
-1cpumask_copy (tmp_map, cpu_present_mask); -acpi_register_lapic (physid, lapic->lapic_flags &ACPI_MADT_ENABLED ); +acpi_register_lapic (physid,ACPI_MADT_ENABLED );
The change looks good. I suggest you also add the following line to prevent such bug in future.
kfree(buffer.pointer);
buffer.length = ACPI_ALLOCATE_BUFFER;
buffer.pointer = NULL;+ lapic = NULL;
Thanks,
-Toshi
Quoted 8 lines
arch/x86/kernel/acpi/boot.c static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) · line 656
Quoted 3 lines
arch/x86/kernel/acpi/boot.c +0
-0/* * If mp_register_lapic successfully generates a new logical cpu --
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Toshi,
Quoted 46 lines · Toshi Kani
Quoted 38 lines · Alok Kataria
Len, anyone else,
Any comments on this one ? This fixes a important bug during cpu hotadd where the kernel fails to recognize all the newly added cpus.
Thanks,
AlokQuoted 28 lines · Petr Vandrovec
From: Petr Vandrovec <[email protected]>
When processor is being hot-added to the system,
acpi_map_lsapicinvokes ACPI_MATmethod to find APIC ID and flags, verifies that returned structure is indeed ACPI's local APIC structure, and that flags containMADT_ENABLEDbit. Then saves APIC ID, frees structure - and accesses structure when computing arguments foracpi_register_lapiccall. Which sometime leads toacpi_register_lapiccall being made with second argument zero, failing to bring processor online with error 'Unable to map lapic to logical cpu number'.As
lapic->lapic_flags&ACPI_MADT_ENABLEDwas already confirmed to be non-zero few lines above, we can just pass unconditionalACPI_MADT_ENABLEDto theacpi_register_lapic.Thanks, Petr
Signed-off-by Petr Vandrovec <[email protected]>Signed-off-by Alok Kataria <[email protected]>arch/x86/kernel/acpi/boot.c +0
-0@@ -650,7 +650,7 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) goto free_tmp_map;Quoted 3 lines
arch/x86/kernel/acpi/boot.c static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) · line 653
Quoted 3 lines
arch/x86/kernel/acpi/boot.c +1
-1cpumask_copy (tmp_map, cpu_present_mask); -acpi_register_lapic (physid, lapic->lapic_flags &ACPI_MADT_ENABLED ); +acpi_register_lapic (physid,ACPI_MADT_ENABLED );The change looks good. I suggest you also add the following line to prevent such bug in future.
Quoted 4 lines
kfree(buffer.pointer); buffer.length = ACPI_ALLOCATE_BUFFER; buffer.pointer = NULL;+ lapic = NULL;
That's a good suggestion, below is the updated patch. Thanks !! --
From: Petr Vandrovec <[email protected]>
When processor is being hot-added to the system, acpi_map_lsapic invokes ACPI _MAT method to find APIC ID and flags, verifies that returned structure is indeed ACPI's local APIC structure, and that flags contain MADT_ENABLED bit. Then saves APIC ID, frees structure - and accesses structure when computing arguments for acpi_register_lapic call. Which sometime leads to acpi_register_lapic call being made with second argument zero, failing to bring processor online with error 'Unable to map lapic to logical cpu number'.
As lapic->lapic_flags & ACPI_MADT_ENABLED was already confirmed to be non-zero few lines above, we can just pass unconditional ACPI_MADT_ENABLED to the acpi_register_lapic.
arch/x86/kernel/acpi/boot.c +2 -1
@@ -642,6 +642,7 @@ static int __cpuinit _acpi_map_lsapic(ackfree (buffer.pointer); buffer.length =ACPI_ALLOCATE_BUFFER ; buffer.pointer =NULL ; + lapic =NULL ;if (!alloc_cpumask_var (&tmp_map,GFP_KERNEL )) goto out;
@@ -650,7 +651,7 @@ static int __cpuinit _acpi_map_lsapic(ac goto free_tmp_map;cpumask_copy (tmp_map, cpu_present_mask); -acpi_register_lapic (physid, lapic->lapic_flags &ACPI_MADT_ENABLED ); +acpi_register_lapic (physid,ACPI_MADT_ENABLED );/* * If mp_register_lapic successfully generates a new logical cpu
Hi Alok,
Quoted 7 lines · Alok Kataria
Hi Toshi,
Quoted 4 lines
The change looks good. I suggest you also add the following line to prevent such bug in future.
Quoted 6 lines
Quoted 4 lines
kfree(buffer.pointer); buffer.length = ACPI_ALLOCATE_BUFFER; buffer.pointer = NULL;+ lapic = NULL;
That's a good suggestion, below is the updated patch. Thanks !!
Looks good. Thanks for the update.
-Toshi
Quoted 47 lines
--
From: Petr Vandrovec <[email protected]>
When processor is being hot-added to the system,
acpi_map_lsapicinvokes ACPI_MATmethod to find APIC ID and flags, verifies that returned structure is indeed ACPI's local APIC structure, and that flags containMADT_ENABLEDbit. Then saves APIC ID, frees structure - and accesses structure when computing arguments foracpi_register_lapiccall. Which sometime leads toacpi_register_lapiccall being made with second argument zero, failing to bring processor online with error 'Unable to map lapic to logical cpu number'.As
lapic->lapic_flags&ACPI_MADT_ENABLEDwas already confirmed to be non-zero few lines above, we can just pass unconditionalACPI_MADT_ENABLEDto theacpi_register_lapic.Signed-off-by Petr Vandrovec <[email protected]>Signed-off-by Alok N Kataria <[email protected]>Cc Toshi Kani <[email protected]>Index:
linux-2.6/arch/x86/kernel/acpi/boot.c
===================================================================arch/x86/kernel/acpi/boot.c +2
-1@@ -642,6 +642,7 @@ static int __cpuinit _acpi_map_lsapic(ackfree (buffer.pointer); buffer.length =ACPI_ALLOCATE_BUFFER ; buffer.pointer =NULL ; + lapic =NULL ;if (!alloc_cpumask_var (&tmp_map,GFP_KERNEL )) goto out;@@ -650,7 +651,7 @@ static int __cpuinit _acpi_map_lsapic(ac goto free_tmp_map;cpumask_copy (tmp_map, cpu_present_mask); -acpi_register_lapic (physid, lapic->lapic_flags &ACPI_MADT_ENABLED ); +acpi_register_lapic (physid,ACPI_MADT_ENABLED );/* * If mp_register_lapic successfully generates a new logical cpu