[PATCH] x86: Pnp byte granularity
authorZachary Amsden <zach@vmware.com>
Fri, 6 Jan 2006 08:11:55 +0000 (00:11 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 6 Jan 2006 16:33:35 +0000 (08:33 -0800)
The one remaining caller of set_limit, the PnP BIOS code, calls into the PnP
BIOS, passing kernel parameters in and out.  These parameteres may be passed
from arbitrary kernel virtual memory, so they deserve strict protection to
stop a bad BIOS from smashing beyond the object size.

Unfortunately, the use of set_limit was badly botching this by setting the
limit in terms of pages, when it really should have byte granularity.

When doing this, I discovered my BIOS had the buggy code during the "get
system device node" call:

 mov ax, es:[bx]

Which is harmless, but has a trivial workaround.

Signed-off-by: Zachary Amsden <zach@vmware.com>
Cc: "Seth, Rohit" <rohit.seth@intel.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/i386/kernel/head.S
drivers/pnp/pnpbios/bioscalls.c
include/asm-i386/system.h

index 37b599fa4d18ccd973443e544a82dddcd5549822..58d2746670b70e877603dd1dcba33acdeeb5ede0 100644 (file)
@@ -504,12 +504,12 @@ ENTRY(cpu_gdt_table)
        .quad 0x0000000000000000        /* 0x80 TSS descriptor */
        .quad 0x0000000000000000        /* 0x88 LDT descriptor */
 
-       /* Segments used for calling PnP BIOS */
-       .quad 0x00c09a0000000000        /* 0x90 32-bit code */
-       .quad 0x00809a0000000000        /* 0x98 16-bit code */
-       .quad 0x0080920000000000        /* 0xa0 16-bit data */
-       .quad 0x0080920000000000        /* 0xa8 16-bit data */
-       .quad 0x0080920000000000        /* 0xb0 16-bit data */
+       /* Segments used for calling PnP BIOS have byte granularity */
+       .quad 0x00409a0000000000        /* 0x90 32-bit code */
+       .quad 0x00009a0000000000        /* 0x98 16-bit code */
+       .quad 0x0000920000000000        /* 0xa0 16-bit data */
+       .quad 0x0000920000000000        /* 0xa8 16-bit data */
+       .quad 0x0000920000000000        /* 0xb0 16-bit data */
 
        /*
         * The APM segments have byte granularity and their bases
index 37bacfcdbc5d4d6200e001885c9928a461c03fe1..a72126180e9736080c7f6c8b7cece88ff57f48ca 100644 (file)
@@ -283,12 +283,15 @@ int pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
 static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
 {
        u16 status;
+       u16 tmp_nodenum;
        if (!pnp_bios_present())
                return PNP_FUNCTION_NOT_SUPPORTED;
        if ( !boot && pnpbios_dont_use_current_config )
                return PNP_FUNCTION_NOT_SUPPORTED;
+       tmp_nodenum = *nodenum;
        status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0,
-                              nodenum, sizeof(char), data, 65536);
+                              &tmp_nodenum, sizeof(tmp_nodenum), data, 65536);
+       *nodenum = tmp_nodenum;
        return status;
 }
 
index 24cc0c8fe34184b3715042903564b90ee517b463..9c0593b7a94e9220c238c9a9b895b694d940ad7f 100644 (file)
@@ -54,7 +54,7 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t" \
         ); } while(0)
 
 #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) )
-#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1)>>12 )
+#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1) )
 
 /*
  * Load a segment. Fall back on loading the zero