[PATCH] Cygwin: signal: Clear direction flag in sigdeleyed
Takashi Yano
takashi.yano@nifty.ne.jp
Mon Mar 24 12:33:10 GMT 2025
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.Franke@t-online.de>
> > Reviewed-by:
> > Signed-off-by: Takashi Yano <takashi.yano@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.yano@nifty.ne.jp>
More information about the Cygwin-patches
mailing list