|
@@ -64,6 +64,10 @@ extern struct segoff __text16 ( int15_vector );
|
64
|
64
|
/* The linker defines these symbols for us */
|
65
|
65
|
extern char _text[];
|
66
|
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
|
73
|
* Hide region of memory from system memory map
|
|
@@ -123,6 +127,9 @@ void hide_text ( void ) {
|
123
|
127
|
*/
|
124
|
128
|
static void hide_etherboot ( void ) {
|
125
|
129
|
struct memory_map memmap;
|
|
130
|
+ unsigned int rm_ds_top;
|
|
131
|
+ unsigned int rm_cs_top;
|
|
132
|
+ unsigned int fbms;
|
126
|
133
|
|
127
|
134
|
/* Dump memory map before mangling */
|
128
|
135
|
DBG ( "Hiding gPXE from system memory map\n" );
|
|
@@ -133,6 +140,26 @@ static void hide_etherboot ( void ) {
|
133
|
140
|
hide_umalloc ( virt_to_phys ( _text ), virt_to_phys ( _text ) );
|
134
|
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
|
163
|
/* Hook INT 15 */
|
137
|
164
|
hook_bios_interrupt ( 0x15, ( unsigned int ) int15,
|
138
|
165
|
&int15_vector );
|