Bug#502544: INT13 handler misbehaviour

Hodek Roman roman.aud at siemens.com
Fri Oct 17 15:38:54 UTC 2008


Package: grub
Version: 0.97-47
Severity: normal
Tags: patch

Hello!

For a rather special application, I tried to use grub's "map" command
in a creative way, something like:

  map (hd0) (hd1)
  map (hd1) (hd2)
  map (hd2) (hd3)
  map (hd3) (hd4)
  chainloader (hd1)+1

The idea was to "shift" the BIOS numbering of disks and then to jump
to the MBR code of the next disk. This worked partially, but only
partially... it ended with either "read error" when loading stage1.5,
or (if done twice) by a mixup of files from the 2nd and 3rd disk.

After a day of debugging I found out the cause of this misbehaviour:

The map command installs an INT13 handler that does the remapping of
device numbers. After calling the previous handler, it tries to
restore register %dl (drive number) to the original value, because
it's traditionally a called-saved register (and grub itself relies on
that). However, there are two functions (08h and 15h) that return
something in %dl/%dx, so in their case the restauration should not
happen. Therefore the code tries to catch these, but the conditions
are horribly wrong ;) (see patch below: wrong condition tests, and
also comparing %ax instead %ah), with the effect that %dl was never
restored. So grub started to read one sector from 0x80, the rest
coming from 0x81 (or, in the double case, from 0x82)...

I guess nobody noticed that until now, because the normal usage of
"map" is to swap (hd0) and (hd1) to boot DOS/Win from the second disk.
And those two insist on booting from device 0x80 (otherwise you
wouldn't need the swap...), so I guess it the device number is
hardcoded in their boot loaders.

Anyway, the patch below fixes the handler to restore %dl exactly in
the cases when it should be.

As upstream doesn't maintain "GRUB Legacy" anymore, I want to submit
this patch at least here. GRUB2 doesn't contain the map command
(yet?), nor the INT13 handler at all, so the fix doesn't apply there.

Roman


--- grub/stage2/asm.S~	2004-03-11 13:00:30.000000000 +0100
+++ grub/stage2/asm.S	2008-10-17 16:13:04.000000000 +0200
@@ -713,10 +713,10 @@
 	movw	%ax, 0xc(%bp)
 	/* check if should map the drive number */
 	movw	6(%bp), %ax
-	cmpw	$0x8, %ax
-	jne	3f
-	cmpw	$0x15, %ax
-	jne	3f
+	cmpb	$0x8, %ah
+	je	3f
+	cmpb	$0x15, %ah
+	je	3f
 	/* check if the mapping was performed */
 	movw	2(%bp), %ax
 	testw	%ax, %ax





More information about the Pkg-grub-devel mailing list