This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Help with implementing ____longjmp_chk for Hurd


Hello again!

Ulrich, perhaps you're willing to help with my questions on the Linux
i386 ____longjmp_chk code?

On Sat, Aug 08, 2009 at 06:49:35PM +0200, I wrote:
> I'm currently looking into implementing ____longjmp_chk for Hurd on i386.
> This function is now OS-specific due to its usage of sigaltstack -- see
> sysdeps/unix/sysv/linux/i386/____longjmp_chk.S.
> 
> Now, my understanding of both setjmp / longjmp, and Hurd signal stuff in
> glibc is not (not yet) the best one, so I'm having a few questions.
> 
> In my undestanding, why this function needs to consider sigaltstack in
> the first place, is that it may be used to do a longjmp, while executing
> on a sigaltstack, back into the ``main stack'' code, and thus the easy
> only-jump-to-initialized-stackframe test (``jmp_buf.sp > sp'') may be
> wrong.  Correct?

Is it actually allowed to do a longjmp from a signal handler?  Or is this
a glibc extension?  And what about using setjmp and then longjmp in a
signal handler?

> My plan is to use _hurd_self_sigstate()->sigaltstack as a replacement for
> the sigaltstack syscall Linux is using.  Correct?
> 
> But then, in the aforementioned i386/____longjmp_chk.S file, there's
> ``testl $1, 4(%esp); jz .Lfail;''; in other words fail if ``!(ss_flags &
> SS_ONSTACK)''.  Correct?  And why do that?  Doesn't this mean, that
> always when a longjmp_chk is done, SS_ONSTACK has to be set, that is
> ``the process is currently executing on the alternate signal stack''
> (from the sigaltstack manpage, and
> <http://opengroup.org/onlinepubs/9699919799/functions/sigaltstack.html>).

Waking up this morning, I thought: ``Oh, this is of course correct, as
all the valid other uses are OKed by the ``jmp_buf.sp > sp'' test
above.'' -- correct?

> And then, the following calculation of addresses, which I translate to
> ``if (ss_base + ss_size - jmp_buf->sp >= ss_size) then OK else fail;''
> also isn't quite intuitive for me.

Isn't this equivalent to ``if (ss_base >= jmp_buf.sp) then OK else
fail''?  I still don't get this one.


Here is the code that I'm going to test now.  There are TODOs in it.
Comments?

diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/mach/hurd/i386/____longjmp_chk.S
similarity index 68%
copy from sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
copy to sysdeps/mach/hurd/i386/____longjmp_chk.S
index a07e6c8..fc7ae7a 100644
--- a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
+++ b/sysdeps/mach/hurd/i386/____longjmp_chk.S
@@ -20,6 +20,10 @@
 #include <jmpbuf-offsets.h>
 #include <asm-syntax.h>
 
+#include <signal-defines.h>
+/* #include <signal.h> */
+#define SS_ONSTACK 1
+
 
 	.section .rodata.str1.1,"aMS",@progbits,1
 	.type	longjmp_msg,@object
@@ -29,14 +33,14 @@ longjmp_msg:
 
 
 #ifdef PIC
-# define CALL_FAIL	movl	%ebx, %ecx;				      \
+# define CALL_FAIL	movl	%ebx, %ecx; /* TODO: what's this mov good for? */ \
 			cfi_register(%ebx,%ecx);			      \
 			LOAD_PIC_REG (bx);				      \
 			leal	longjmp_msg@GOTOFF(%ebx), %eax;		      \
-			call	__GI___fortify_fail@PLT
+			call	HIDDEN_JUMPTARGET(__fortify_fail)
 #else
 # define CALL_FAIL	movl	$longjmp_msg, %eax;			      \
-			call	__fortify_fail
+			call	HIDDEN_JUMPTARGET(__fortify_fail)
 #endif
 
 
@@ -53,32 +57,30 @@ ENTRY (____longjmp_chk)
 	PTR_DEMANGLE (%edi)
 
 	cmpl	%edi, %esp
+	/* Jumping to a higher-address frame is always allowed.  */
 	jbe	.Lok
 
-	subl	$12, %esp
-	cfi_adjust_cfa_offset(12)
-	xorl	%ebx, %ebx
-	movl	%esp, %ecx
-	movl	$__NR_sigaltstack, %eax
-	ENTER_KERNEL
-	/* Without working sigaltstack we cannot perform the test.  */
-	test	%eax, %eax
-	jne	.Lok2
-	testl	$1, 4(%esp)
+	/* Passing here, we're either about to do something invalid, or we're
+	executing on an alternative signal stack.  */
+
+	/* TODO: need locking?  */
+	/* struct hurd_sigstate * _hurd_self_sigstate (void) */
+	call	_hurd_self_sigstate
+	/* TODO: %eax and %eax->sigaltstack are always valid?  */
+
+	testl	$SS_ONSTACK, (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_FLAGS__OFFSET)(%eax)
+	/* Fail if SS_ONSTACK is not set.  */
 	jz	.Lfail
 
-	movl	(%esp), %eax
-	addl	8(%esp), %eax
-	subl	%edi, %eax
-	cmpl	8(%esp), %eax
-	jae	.Lok2
+	movl	(HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SP__OFFSET)(%eax), %ebx
+	addl	(HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SIZE__OFFSET)(%eax), %ebx
+	subl	%edi, %ebx
+	cmpl	(HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SIZE__OFFSET)(%eax), %ebx
+	/* TODO: comment this calculation.  */
+	jae	.Lok
 
 .Lfail:	CALL_FAIL
 
-.Lok2:	addl	$12, %esp
-	cfi_adjust_cfa_offset(-12)
-	movl	4(%esp), %ecx
-
 .Lok:	/* We add unwind information for the target here.  */
 	cfi_def_cfa(%ecx, 0)
 	cfi_register(%eip, %edx)
diff --git a/sysdeps/mach/hurd/i386/signal-defines.sym b/sysdeps/mach/hurd/i386/signal-defines.sym
new file mode 100644
index 0000000..9521bd7
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/signal-defines.sym
@@ -0,0 +1,10 @@
+#include <hurd/signal.h>
+#include <signal.h>
+
+--
+
+HURD_SIGSTATE__SIGALTSTACK__OFFSET	offsetof(struct hurd_sigstate, sigaltstack)
+
+SIGALTSTACK__SS_SP__OFFSET		offsetof(struct sigaltstack, ss_sp)
+SIGALTSTACK__SS_SIZE__OFFSET		offsetof(struct sigaltstack, ss_size)
+SIGALTSTACK__SS_FLAGS__OFFSET		offsetof(struct sigaltstack, ss_flags)
diff --git a/sysdeps/mach/hurd/i386/Makefile b/sysdeps/mach/hurd/i386/Makefile
index 0eef17e..5f98809 100644
--- a/sysdeps/mach/hurd/i386/Makefile
+++ b/sysdeps/mach/hurd/i386/Makefile
@@ -2,3 +2,7 @@ ifeq ($(subdir),misc)
 sysdep_routines += ioperm
 sysdep_headers += sys/io.h
 endif
+
+ifeq ($(subdir),debug)
+gen-as-const-headers += signal-defines.sym
+endif


Regards,
 Thomas

Attachment: signature.asc
Description: Digital signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]