Browse Source

[pcbios] Inhibit INT 15 memory map hiding on brain-dead BIOSes

Some really moronic BIOSes bring up the PXE stack via the UNDI loader
entry point during POST, and then don't bother to unload it before
overwriting the code and data segments.  If this happens, we really
don't want to leave INT 15 hooked, because that will cause any loaded
OS to die horribly as soon as it attempts to fetch the system memory
map.

We use a heuristic to detect whether or not we are being loaded at the
top of free base memory.  If we determine that we are being loaded at
some other arbitrary location in base memory, then we assume that it's
not safe to hook INT 15.
tags/v0.9.4
Michael Brown 16 years ago
parent
commit
887d77c27a
1 changed files with 27 additions and 0 deletions
  1. 27
    0
      src/arch/i386/firmware/pcbios/hidemem.c

+ 27
- 0
src/arch/i386/firmware/pcbios/hidemem.c View File

64
 /* The linker defines these symbols for us */
64
 /* The linker defines these symbols for us */
65
 extern char _text[];
65
 extern char _text[];
66
 extern char _end[];
66
 extern char _end[];
67
+extern char _text16_size[];
68
+#define _text16_size ( ( unsigned int ) _text16_size )
69
+extern char _data16_size[];
70
+#define _data16_size ( ( unsigned int ) _data16_size )
67
 
71
 
68
 /**
72
 /**
69
  * Hide region of memory from system memory map
73
  * Hide region of memory from system memory map
123
  */
127
  */
124
 static void hide_etherboot ( void ) {
128
 static void hide_etherboot ( void ) {
125
 	struct memory_map memmap;
129
 	struct memory_map memmap;
130
+	unsigned int rm_ds_top;
131
+	unsigned int rm_cs_top;
132
+	unsigned int fbms;
126
 
133
 
127
 	/* Dump memory map before mangling */
134
 	/* Dump memory map before mangling */
128
 	DBG ( "Hiding gPXE from system memory map\n" );
135
 	DBG ( "Hiding gPXE from system memory map\n" );
133
 	hide_umalloc ( virt_to_phys ( _text ), virt_to_phys ( _text ) );
140
 	hide_umalloc ( virt_to_phys ( _text ), virt_to_phys ( _text ) );
134
 	hide_text();
141
 	hide_text();
135
 
142
 
143
+	/* Some really moronic BIOSes bring up the PXE stack via the
144
+	 * UNDI loader entry point and then don't bother to unload it
145
+	 * before overwriting the code and data segments.  If this
146
+	 * happens, we really don't want to leave INT 15 hooked,
147
+	 * because that will cause any loaded OS to die horribly as
148
+	 * soon as it attempts to fetch the system memory map.
149
+	 *
150
+	 * We use a heuristic to guess whether or not we are being
151
+	 * loaded sensibly.
152
+	 */
153
+	rm_cs_top = ( ( ( rm_cs << 4 ) + _text16_size + 1024 - 1 ) >> 10 );
154
+	rm_ds_top = ( ( ( rm_ds << 4 ) + _data16_size + 1024 - 1 ) >> 10 );
155
+	fbms = get_fbms();
156
+	if ( ( rm_cs_top < fbms ) && ( rm_ds_top < fbms ) ) {
157
+		DBG ( "Detected potentially unsafe UNDI load at CS=%04x "
158
+		      "DS=%04x FBMS=%dkB\n", rm_cs, rm_ds, fbms );
159
+		DBG ( "Disabling INT 15 memory hiding\n" );
160
+		return;
161
+	}
162
+
136
 	/* Hook INT 15 */
163
 	/* Hook INT 15 */
137
 	hook_bios_interrupt ( 0x15, ( unsigned int ) int15,
164
 	hook_bios_interrupt ( 0x15, ( unsigned int ) int15,
138
 			      &int15_vector );
165
 			      &int15_vector );

Loading…
Cancel
Save