Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200609011251.GD1079@brightrain.aerifal.cx>
Date: Mon, 8 Jun 2020 21:12:51 -0400
From: Rich Felker <dalias@...c.org>
To: sidneym@...eaurora.org
Cc: musl@...ts.openwall.com
Subject: Re: sigsetjmp

On Mon, Jun 08, 2020 at 08:01:24PM -0500, sidneym@...eaurora.org wrote:
> 
> 
> > -----Original Message-----
> > From: Rich Felker <dalias@...c.org>
> > Sent: Monday, June 8, 2020 12:11 PM
> > To: sidneym@...eaurora.org
> > Cc: musl@...ts.openwall.com
> > Subject: Re: [musl] sigsetjmp
> > 
> > On Sun, Jun 07, 2020 at 08:45:11PM -0500, sidneym@...eaurora.org wrote:
> > > Wanting to make sure I'm reading the requirements correctly.
> > >
> > > Looks like this routine only needs to save the link register and env,
> > > call setjmp then restore the link register and env followed by the tail
> call.
> > 
> > Yes, that's correct. This is an unconventional design but necessary so
> that the
> > stack frame has already been restored when signals are unmasked by
> > siglongjmp. See the message for commit
> > 583e55122e767b1586286a0d9c35e2a4027998ab for a description of how this
> > works.
> > 
> > > Hexagon was out of date so I did this:
> > >
> > >
> > >
> > > ..balign 4
> > >
> > > ..type sigsetjmp,@function
> > >
> > > sigsetjmp:
> > >
> > >         // if savemask is 0 sigsetjmp behaves like setjmp
> > >
> > >         {
> > >
> > >                 p0 = cmp.eq(r1, #0)
> > >
> > >                 if (p0.new) jump:t ##setjmp
> > >
> > >         }
> > >
> > >         {
> > >
> > >                 memw(r0+#64+4) = r16  // save r16 in __ss[0]
> > >
> > >                 memw(r0+#64)   = r31  // save linkregister in __fl
> > >
> > >                 r16 = r0
> > >
> > >         }
> > 
> > This is not correct. __ss[0] is occupied by the saved signal mask, and
> will be
> > clobbered when it's saved in the tail call. Instead you need to use unused
> space
> > in struct __jmp_buf_tag. The canonical place is
> > (char*)__ss+8 (the "HURD ABI area" :) assuming _NSIG==65.
> 
> I was not able to find a description of the HURD ABI area is it documented
> someplace?

By "HURD ABI" I just mean the fact that sigset_t is gratuitously 128
bytes rather than 8 bytes, because early glibc imagined uselessly
having 1024 signals like GNU HURD will someday do.

The point is that only the first 8 (or 16, on MIPS*) bytes of the
signal mask save area (__ss[]) are actually used for saving a signal
mask, and the rest is free for sigsetjmp to use for other purposes.

> So upon entry to sigsetjmp __ss[0] is holding the saved mask and using
> __ss[0] to buffer r16 will clobber it, correct?  As it is coded __ss[0] is
> just used over the call to setjmp to preserve the value of r16.

No, upon entry __ss[0] is uninitialized. __sigsetjmp_tail will store
the signal mask into it (and __ss[1], on 32-bit archs) before
returning to the caller, and on the second return (via siglongjmp)
will restore the signal mask from there.

> If __ss is r0+#64+4, then you are suggesting that I use r0+#64+4+8 or
> __ss[2]. I need to look into this some more because with that I'm have some
> testcase issues.

Yes, that sounds right. Look what other archs do. The arm version is
very easy to read.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.