Browse Source

[int13con] Avoid overwriting random portions of SAN boot disks

The INT13 console type (CONSOLE_INT13) autodetects at initialisation
time a magic partition to be used for logging iPXE console output.  If
the INT13 drive number mapping is subsequently changed (e.g. because
iPXE was used to perform a SAN boot), then the console logging output
will be written to the incorrect disk.

Fix by recording the INT13 vector at initialisation time, and using
this original vector to emulate INT13 calls for all subsequent
accesses.  This should be robust against drive remapping performed
either by ourselves or by another bootloader (e.g. a chainloaded
undionly.kpxe which then performs a SAN boot).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 7 years ago
parent
commit
c73af29fe2
1 changed files with 17 additions and 2 deletions
  1. 17
    2
      src/arch/x86/interface/pcbios/int13con.c

+ 17
- 2
src/arch/x86/interface/pcbios/int13con.c View File

@@ -62,6 +62,10 @@ struct int13con_header {
62 62
 /** Log partition magic signature */
63 63
 #define INT13CON_MAGIC "iPXE LOG\n\n"
64 64
 
65
+/** Original INT13 vector */
66
+static struct segoff __bss16 ( int13con_vector );
67
+#define int13con_vector __use_data16 ( int13con_vector )
68
+
65 69
 /** Sector buffer */
66 70
 static uint8_t __bss16_array ( int13con_buffer, [INT13_BLKSIZE] );
67 71
 #define int13con_buffer __use_data16 ( int13con_buffer )
@@ -101,8 +105,13 @@ static int int13con_rw ( unsigned int op, uint64_t lba ) {
101 105
 	int13con_address.buffer.offset = __from_data16 ( int13con_buffer );
102 106
 	int13con_address.lba = lba;
103 107
 
104
-	/* Issue INT13 */
105
-	__asm__ ( REAL_CODE ( "int $0x13\n\t" )
108
+	/* Emulate INT13 via original vector.  We do this since iPXE
109
+	 * (or another subsequent bootloader) may hook INT13 and remap
110
+	 * drive numbers.
111
+	 */
112
+	__asm__ ( REAL_CODE ( "pushfw\n\t"
113
+			      "cli\n\t"
114
+			      "lcall *int13con_vector\n\t" )
106 115
 		  : "=a" ( error )
107 116
 		  : "0" ( op << 8 ), "d" ( INT13CON_DRIVE ),
108 117
 		    "S" ( __from_data16 ( &int13con_address ) ) );
@@ -261,6 +270,12 @@ static void int13con_init ( void ) {
261 270
 		return;
262 271
 	}
263 272
 
273
+	/* Store original INT13 vector */
274
+	copy_from_real ( &int13con_vector, 0, ( 0x13 * 4 ),
275
+			 sizeof ( int13con_vector ) );
276
+	DBG ( "INT13CON using original INT13 vector %04x:%04x\n",
277
+	      int13con_vector.segment, int13con_vector.offset );
278
+
264 279
 	/* Locate log partition */
265 280
 	if ( ( rc = int13con_find() ) != 0)
266 281
 		return;

Loading…
Cancel
Save