On Mon, 24 Mar 2025 11:59:58 +0100
Christian Franke wrote:
> Takashi Yano wrote:
> > x86_64 ABI requires the direction flag in CPU flags register cleared.
> > https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions
> > However, currently that flag is not maintained in signal handler.
> > Therefore, if the signal handler is called when that flag is set, it
> > destroys the data and may crash if rep instruction is used in the
> > signal handler. With this patch, the direction flag is cleared in
> > sigdelayed() by adding cld instruction.
> >
> > Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257704.html
> > Fixes: 1fd5e000ace5 ("import winsup-2000-02-17 snapshot")
> > Reported-by: Christian Franke <christian.fra...@t-online.de>
> > Reviewed-by:
> > Signed-off-by: Takashi Yano <takashi.y...@nifty.ne.jp>
> > ---
> >   winsup/cygwin/scripts/gendef | 1 +
> >   1 file changed, 1 insertion(+)
> >
> > diff --git a/winsup/cygwin/scripts/gendef b/winsup/cygwin/scripts/gendef
> > index a2f0392bc..861a2405b 100755
> > --- a/winsup/cygwin/scripts/gendef
> > +++ b/winsup/cygwin/scripts/gendef
> > @@ -179,6 +179,7 @@ sigdelayed:
> >     movq    %rsp,%rbp
> >     pushf
> >     .seh_pushreg %rax                       # fake, there's no .seh_pushreg 
> > for the flags
> > +   cld                                     # x86_64 ABI requires direction 
> > flag cleared
> >     # stack is aligned or unaligned on entry!
> >     # make sure it is aligned from here on
> >     # We could be called from an interrupted thread which doesn't know
> 
> Works as expected:
> - the testcase no longer aborts.
> 
> - a version with modified main loop does not detect DF modification by 
> the signal:
> 
>    while ((cnt = sigcnt) < 1000) {
>      if (!(__builtin_ia32_readeflags_u64() & 0x0400) != !std)
>        return 13;
>      if ((cnt & 1) && !std) {
>        asm volatile ("std");
>        std = 1;
>      }
>      else if (!(cnt & 1) && std) {
>        asm volatile ("cld");
>        std = 0;
>      }
>    }
> 
> - The related stress-ng testcases no longer report segfaults:
> 
> $ n=0
> $ while
>    stress-ng --parallel 2 --with memcpy,tree --memcpy-method libc 
> --tree-method btree -t 2;
> do echo OK $((++n)); done
> ...
> OK 500
> ...

Thanks for testing!

-- 
Takashi Yano <takashi.y...@nifty.ne.jp>

Reply via email to