Subject: Re: non-exec stack problems with multithreaded programs
To: Nathan J. Williams <nathanw@wasabisystems.com>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: port-i386
Date: 12/09/2003 19:40:37
This is a multipart MIME message.
--==_Exmh_19774565406090
Content-Type: text/plain; charset=us-ascii
nathanw@wasabisystems.com said:
> make it possible for signals to still be delivered even if the program
> was doing some USER_LDT hackery
I've checked what FreeBSD does here: They have all userlevel segment
descriptors in the LDT, so that they can be corrupted by the user.
Faults in what corresponds to the "iret" in our calltrap() are
caught separately.
NetBSD indeed gets into an endless loop because the GPF on "iret"
happens which the CS is still at kernel priority, so that case is not
handled appropriately as a user trap.
I'd say handling this case and putting everything into the LDT, as
FreeBSD does, is the way to go.
Unfortunately:-) I have to confine myself to theoretical considerations
for the moment, as I'll likely be AFK from friday until next year,
so it doesn't make sense to start major projects now.
To get at least multithreaded programs needing a trampoline on the
stack running, I'd propose the appended minimal stopgap patch.
(Actually, I'm not sure under which conditions the trampoline
stuff in gcc-3.3 gets used. It is definitely used by ada programs
if they use "tasking". Might be necessary for c++ exception
handling too.)
If noone objects, I'll commit that patch tomorrow.
best regards
Matthias
--==_Exmh_19774565406090
Content-Type: text/plain ; name="execstack.txt"; charset=us-ascii
Content-Description: execstack.txt
Content-Disposition: attachment; filename="execstack.txt"
Index: i386/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/pmap.c,v
retrieving revision 1.164
diff -u -p -r1.164 pmap.c
--- i386/pmap.c 3 Nov 2003 04:02:13 -0000 1.164
+++ i386/pmap.c 3 Dec 2003 17:26:51 -0000
@@ -769,7 +769,7 @@ pmap_exec_fixup(struct vm_map *map, stru
va = trunc_page(ent->end) - PAGE_SIZE;
}
vm_map_unlock_read(map);
- if (va == pm->pm_hiexec)
+ if (va == pm->pm_hiexec && tf->tf_cs == GSEL(GUCODEBIG_SEL, SEL_UPL))
return (0);
pm->pm_hiexec = va;
--==_Exmh_19774565406090--