Remove dynamically generated code from LRMI.
authorMichał Januszewski <spock@gentoo.org>
Mon, 22 Sep 2008 22:56:59 +0000 (23 00:56 +0200)
committerMichał Januszewski <spock@gentoo.org>
Mon, 22 Sep 2008 22:56:59 +0000 (23 00:56 +0200)
LRMI dynamically generated the return to 32-bit code (int 0xff), which
causes problem with systems using PaX, where memory pages are either
executable or writable, but never both at once.  Fix this by including
this code in a separate section in the object file and mapping it
to the absolute address 0x9000.

Thanks to the PaX team for useful suggestions and discussions in
http://bugs.gentoo.org/show_bug.cgi?id=226107

Makefile
libs/lrmi-0.10/Makefile
libs/lrmi-0.10/lrmi.c

index 3b2ae00..0d4c809 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,6 @@ endif
 
 CFLAGS ?= -Wall -g -O2
 CFLAGS += -I$(KDIR)/include
-LDFLAGS += -Wl,-z,execheap
 
 ifeq ($(call config_opt,CONFIG_X86EMU),true)
        CFLAGS += -Ilibs/x86emu
@@ -21,7 +20,7 @@ ifeq ($(call config_opt,CONFIG_X86EMU),true)
        V86LIB = x86emu
 else
        CFLAGS += -Ilibs/lrmi-0.10
-       LDFLAGS += -Llibs/lrmi-0.10 -static
+       LDFLAGS += -Llibs/lrmi-0.10 -static -Wl,--section-start,vm86_ret=0x9000
        LDLIBS += -llrmi
        V86OBJS = v86_lrmi.o
        V86LIB = lrmi
index c37bf4e..17896a3 100644 (file)
@@ -26,7 +26,7 @@ liblrmi.a: $(objects)
 
 liblrmi.so: $(pic_objects)
 #      $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -shared -o $@ $^
-       $(CC) $(CPPFLAGS) $(CFLAGS) -Wl,-soname,$(LIBNAME).so.$(MAJOR) -fPIC -shared -o $(LIBNAME).so.$(VERSION) $^
+       $(CC) $(CPPFLAGS) $(CFLAGS) -Wl,-soname,$(LIBNAME).so.$(MAJOR) -Wl,--section-start,vm86_ret=0x9000 -fPIC -shared -o $(LIBNAME).so.$(VERSION) $^
        ln -sf $(LIBNAME).so.$(VERSION) $(LIBNAME).so.$(MAJOR)
        ln -sf $(LIBNAME).so.$(MAJOR) $(LIBNAME).so
 
index 97b6ae2..7f733ef 100644 (file)
@@ -372,6 +372,18 @@ LRMI_init(void)
        context.stack_seg = (unsigned int)m >> 4;
        context.stack_off = DEFAULT_STACK_SIZE;
 
+#if defined(__linux__)
+       /*
+        The return to 32-bit code (vm86_ret section) is linked
+        into the absolute address 0x9000.
+       */
+       context.ret_seg = 0x0900;
+       context.ret_off = 0x0000;
+
+       asm (".pushsection vm86_ret, \"ax\"\nint %0\n.popsection"
+               : /* no return value */
+               : "i" (RETURN_TO_32_INT));
+#else
        /*
         Allocate the return to 32 bit routine
        */
@@ -380,9 +392,10 @@ LRMI_init(void)
        context.ret_seg = (unsigned int)m >> 4;
        context.ret_off = (unsigned int)m & 0xf;
 
-       ((unsigned char *)m)[0] = 0xcd;         /* int opcode */
+       ((unsigned char *)m)[0] = 0xcd;         /* int opcode */
        ((unsigned char *)m)[1] = RETURN_TO_32_INT;
 
+#endif  /* __linux__ */
        memset(&context.vm, 0, sizeof(context.vm));
 
        /*