Skip to contentSkip to conversation

acpi: Fix potential call to a freed memory section.

PATCH In review Aaron Durbin 2 participants 3 messages May 16, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 acpi: Fix potential call to a freed memory section.

Strip __cpuinit[data] from Node <-> PXM routines and supporting data structures. Also make pxm_to_node_map and node_to_pxm_map local to the numa acpi module.

This fixes a bug triggered by the following conditions:
- boot on a machine with a SLIT table defined
- kernel is configured w/ CONFIG_HOTPLUG_CPU=n
- cat /sys/devices/system/node/node*/distance
This will cause an oops by calling into a freed memory section.

In particular, on x86_64, __node_distance calls node_to_pxm().

---

drivers/acpi/numa.c +4 -4
index 8fcd6a1..a2efae8 100644
@@ -40,19 +40,19 @@ #define PXM_INVAL	-1
 #define NID_INVAL	-1
 
 /* maps to convert between proximity domain and logical node ID */
-int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS]
+static int pxm_to_node_map[MAX_PXM_DOMAINS]
 				= { [0 ... MAX_PXM_DOMAINS - 1] = NID_INVAL };
-int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]
+static int node_to_pxm_map[MAX_NUMNODES]
 				= { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
 
-int __cpuinit pxm_to_node(int pxm)
+int pxm_to_node(int pxm)
 {
 	if (pxm < 0)
 		return NID_INVAL;
 	return pxm_to_node_map[pxm];
 }
 
-int __cpuinit node_to_pxm(int node)
+int node_to_pxm(int node)
 {
 	if (node < 0)
 		return PXM_INVAL;
include/acpi/acpi_numa.h +2 -5
index f9d2bde..b62cd36 100644
@@ -11,11 +11,8 @@ #else
 #define MAX_PXM_DOMAINS (256)	/* Old pxm spec is defined 8 bit */
 #endif
 
-extern int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS];
-extern int __cpuinitdata node_to_pxm_map[MAX_NUMNODES];
-
-extern int __cpuinit pxm_to_node(int);
-extern int __cpuinit node_to_pxm(int);
+extern int pxm_to_node(int);
+extern int node_to_pxm(int);
 extern int __cpuinit acpi_map_pxm_to_node(int);
 extern void __cpuinit acpi_unmap_pxm_to_node(int);
 
#1 lore raw
Quoted 11 lines · On Wed, 16 May 2007 09:09:11 -0700 Aaron Durbin <[email protected]> wrote:

Strip __cpuinit[data] from Node <-> PXM routines and supporting data structures. Also make pxm_to_node_map and node_to_pxm_map local to the numa acpi module.

This fixes a bug triggered by the following conditions:
- boot on a machine with a SLIT table defined
- kernel is configured w/ CONFIG_HOTPLUG_CPU=n
- cat /sys/devices/system/node/node*/distance
This will cause an oops by calling into a freed memory section.

In particular, on x86_64, __node_distance calls node_to_pxm().

Yeah, those section warnings we get aren't just noise.

I think this patch is also needed in 2.6.21.x, yes?

Quoted 38 lines

---

drivers/acpi/numa.c +4 -4
index 8fcd6a1..a2efae8 100644
@@ -40,19 +40,19 @@ #define PXM_INVAL	-1
 #define NID_INVAL	-1
 
 /* maps to convert between proximity domain and logical node ID */
-int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS]
+static int pxm_to_node_map[MAX_PXM_DOMAINS]
 				= { [0 ... MAX_PXM_DOMAINS - 1] = NID_INVAL };
-int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]
+static int node_to_pxm_map[MAX_NUMNODES]
 				= { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
 
-int __cpuinit pxm_to_node(int pxm)
+int pxm_to_node(int pxm)
 {
 	if (pxm < 0)
 		return NID_INVAL;
 	return pxm_to_node_map[pxm];
 }
 
-int __cpuinit node_to_pxm(int node)
+int node_to_pxm(int node)
 {
 	if (node < 0)
 		return PXM_INVAL;
include/acpi/acpi_numa.h +0 -0
index f9d2bde..b62cd36 100644
@@ -11,11 +11,8 @@ #else
 #define MAX_PXM_DOMAINS (256)	/* Old pxm spec is defined 8 bit */
 #endif
 

include/acpi/acpi_numa.h #else · line 18

Quoted 10 lines
include/acpi/acpi_numa.h +2 -5
-extern int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS];
-extern int __cpuinitdata node_to_pxm_map[MAX_NUMNODES];
-
-extern int __cpuinit pxm_to_node(int);
-extern int __cpuinit node_to_pxm(int);
+extern int pxm_to_node(int);
+extern int node_to_pxm(int);
 extern int __cpuinit acpi_map_pxm_to_node(int);
 extern void __cpuinit acpi_unmap_pxm_to_node(int);
 

Moving from __fooinit into .text is always safe. Len, do you want me to merge this up?

#2 lore raw
Quoted 11 lines · Andrew Morton
Quoted 9 lines · On Wed, 16 May 2007 09:09:11 -0700 Aaron Durbin <[email protected]> wrote:

Strip __cpuinit[data] from Node <-> PXM routines and supporting data structures. Also make pxm_to_node_map and node_to_pxm_map local to the numa acpi module.

This fixes a bug triggered by the following conditions:
- boot on a machine with a SLIT table defined
- kernel is configured w/ CONFIG_HOTPLUG_CPU=n
- cat /sys/devices/system/node/node*/distance
This will cause an oops by calling into a freed memory section.

Quoted 6 lines
Quoted 2 lines

In particular, on x86_64, __node_distance calls node_to_pxm().

Yeah, those section warnings we get aren't just noise.

I think this patch is also needed in 2.6.21.x, yes?

Yes, this bug exists in 2.6.21 as well.

Quoted 54 lines
Quoted 39 lines

---

drivers/acpi/numa.c +4 -4
index 8fcd6a1..a2efae8 100644
@@ -40,19 +40,19 @@ #define PXM_INVAL -1
 #define NID_INVAL    -1
 
 /* maps to convert between proximity domain and logical node ID */
-int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS]
+static int pxm_to_node_map[MAX_PXM_DOMAINS]
                              = { [0 ... MAX_PXM_DOMAINS - 1] = NID_INVAL };
-int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]
+static int node_to_pxm_map[MAX_NUMNODES]
                              = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
 
-int __cpuinit pxm_to_node(int pxm)
+int pxm_to_node(int pxm)
 {
      if (pxm < 0)
              return NID_INVAL;
      return pxm_to_node_map[pxm];
 }
 
-int __cpuinit node_to_pxm(int node)
+int node_to_pxm(int node)
 {
      if (node < 0)
              return PXM_INVAL;
include/acpi/acpi_numa.h +0 -0
index f9d2bde..b62cd36 100644
@@ -11,11 +11,8 @@ #else
 #define MAX_PXM_DOMAINS (256)        /* Old pxm spec is defined 8 bit */
 #endif
 

include/acpi/acpi_numa.h #else · line 18

Quoted 10 lines
include/acpi/acpi_numa.h +2 -5
-extern int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS];
-extern int __cpuinitdata node_to_pxm_map[MAX_NUMNODES];
-
-extern int __cpuinit pxm_to_node(int);
-extern int __cpuinit node_to_pxm(int);
+extern int pxm_to_node(int);
+extern int node_to_pxm(int);
 extern int __cpuinit acpi_map_pxm_to_node(int);
 extern void __cpuinit acpi_unmap_pxm_to_node(int);
 

Moving from __fooinit into .text is always safe. Len, do you want me to merge this up?