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] |
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] |