Message ID | 20180721142035.21059-9-hjl.tools@gmail.com |
---|---|
State | New |
Headers | show |
Series | x86/CET: The last 12 patches to enable Intel CET | expand |
On 07/21/2018 10:20 AM, H.J. Lu wrote: > Check swapcontext works with a wrapper. > > * stdlib/Makefile (tests): Add tst-swapcontext1. > * stdlib/tst-swapcontext1.c: New test. OK for 2.28 if you can answer the licensing question. Reviewed-by: Carlos O'Donell <carlos@redhat.com> > --- > stdlib/Makefile | 3 +- > stdlib/tst-swapcontext1.c | 92 +++++++++++++++++++++++++++++++++++++++ > 2 files changed, 94 insertions(+), 1 deletion(-) > create mode 100644 stdlib/tst-swapcontext1.c > > diff --git a/stdlib/Makefile b/stdlib/Makefile > index b5e55b0a55..bc8929f2b9 100644 > --- a/stdlib/Makefile > +++ b/stdlib/Makefile > @@ -84,7 +84,8 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ > tst-cxa_atexit tst-on_exit test-atexit-race \ > test-at_quick_exit-race test-cxa_atexit-race \ > test-on_exit-race test-dlclose-exit-race \ > - tst-makecontext-align test-bz22786 tst-strtod-nan-sign > + tst-makecontext-align test-bz22786 tst-strtod-nan-sign \ > + tst-swapcontext1 OK. > > tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \ > tst-tls-atexit tst-tls-atexit-nodelete > diff --git a/stdlib/tst-swapcontext1.c b/stdlib/tst-swapcontext1.c > new file mode 100644 > index 0000000000..6dd52f22a6 > --- /dev/null > +++ b/stdlib/tst-swapcontext1.c > @@ -0,0 +1,92 @@ > +/* Check swapcontext wrapper. > + Modified from c-c++-common/asan/swapcontext-test-1.c in GCC testsuite. I'm not sure we can relicense a test like this or copy the test. > + Copyright (C) 2018 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <http://www.gnu.org/licenses/>. */ > + > +#include <stdio.h> > +#include <ucontext.h> > +#include <unistd.h> > + > +__attribute__((noinline, noclone)) > +__INDIRECT_RETURN > +int > +myswapcontext (ucontext_t *oucp, ucontext_t *ucp) > +{ > + int res = swapcontext (oucp, ucp); > + return res; > +} > + > +ucontext_t orig_context; > +ucontext_t child_context; > + > +void > +Child (int mode) > +{ > + char x[32] = {0}; /* Stack gets poisoned. */ > + printf("Child: %p\n", x); > + /* (a) Do nothing, just return to parent function. > + (b) Jump into the original function. Stack remains poisoned unless we do > + something. */ > + if (mode == 1) > + { > + if (myswapcontext (&child_context, &orig_context) < 0) > + { > + perror ("swapcontext"); > + _exit (0); > + } > + } OK. > +} > + > +int > +Run (int arg, int mode) > +{ > + int i; > + const int kStackSize = 1 << 20; > + char child_stack[kStackSize + 1]; > + printf ("Child stack: %p\n", child_stack); > + /* Setup child context. */ > + getcontext (&child_context); > + child_context.uc_stack.ss_sp = child_stack; > + child_context.uc_stack.ss_size = kStackSize / 2; > + if (mode == 0) > + child_context.uc_link = &orig_context; > + makecontext (&child_context, (void (*)(void))Child, 1, mode); > + if (myswapcontext (&orig_context, &child_context) < 0) > + { > + perror("swapcontext"); > + return 0; > + } > + /* Touch childs's stack to make sure it's unpoisoned. */ > + for (i = 0; i < kStackSize; i++) > + child_stack[i] = i; > + return child_stack[arg]; OK. > +} > + > +volatile int zero = 0; > + > +static int > +do_test (void) > +{ > + int ret = 0; > + ret += Run (zero, 0); > + fprintf (stderr, "Test1 passed\n"); > + ret += Run (zero, 1); > + fprintf (stderr, "Test2 passed\n"); > + return ret; > +} OK. > + > +#include <support/test-driver.c> > OK.
On Tue, Jul 24, 2018 at 11:27:04PM -0400, Carlos O'Donell wrote: > On 07/21/2018 10:20 AM, H.J. Lu wrote: > > Check swapcontext works with a wrapper. > > > > * stdlib/Makefile (tests): Add tst-swapcontext1. > > * stdlib/tst-swapcontext1.c: New test. > > OK for 2.28 if you can answer the licensing question. > I am dropping this for now. H.J.
diff --git a/stdlib/Makefile b/stdlib/Makefile index b5e55b0a55..bc8929f2b9 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -84,7 +84,8 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ tst-cxa_atexit tst-on_exit test-atexit-race \ test-at_quick_exit-race test-cxa_atexit-race \ test-on_exit-race test-dlclose-exit-race \ - tst-makecontext-align test-bz22786 tst-strtod-nan-sign + tst-makecontext-align test-bz22786 tst-strtod-nan-sign \ + tst-swapcontext1 tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \ tst-tls-atexit tst-tls-atexit-nodelete diff --git a/stdlib/tst-swapcontext1.c b/stdlib/tst-swapcontext1.c new file mode 100644 index 0000000000..6dd52f22a6 --- /dev/null +++ b/stdlib/tst-swapcontext1.c @@ -0,0 +1,92 @@ +/* Check swapcontext wrapper. + Modified from c-c++-common/asan/swapcontext-test-1.c in GCC testsuite. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <ucontext.h> +#include <unistd.h> + +__attribute__((noinline, noclone)) +__INDIRECT_RETURN +int +myswapcontext (ucontext_t *oucp, ucontext_t *ucp) +{ + int res = swapcontext (oucp, ucp); + return res; +} + +ucontext_t orig_context; +ucontext_t child_context; + +void +Child (int mode) +{ + char x[32] = {0}; /* Stack gets poisoned. */ + printf("Child: %p\n", x); + /* (a) Do nothing, just return to parent function. + (b) Jump into the original function. Stack remains poisoned unless we do + something. */ + if (mode == 1) + { + if (myswapcontext (&child_context, &orig_context) < 0) + { + perror ("swapcontext"); + _exit (0); + } + } +} + +int +Run (int arg, int mode) +{ + int i; + const int kStackSize = 1 << 20; + char child_stack[kStackSize + 1]; + printf ("Child stack: %p\n", child_stack); + /* Setup child context. */ + getcontext (&child_context); + child_context.uc_stack.ss_sp = child_stack; + child_context.uc_stack.ss_size = kStackSize / 2; + if (mode == 0) + child_context.uc_link = &orig_context; + makecontext (&child_context, (void (*)(void))Child, 1, mode); + if (myswapcontext (&orig_context, &child_context) < 0) + { + perror("swapcontext"); + return 0; + } + /* Touch childs's stack to make sure it's unpoisoned. */ + for (i = 0; i < kStackSize; i++) + child_stack[i] = i; + return child_stack[arg]; +} + +volatile int zero = 0; + +static int +do_test (void) +{ + int ret = 0; + ret += Run (zero, 0); + fprintf (stderr, "Test1 passed\n"); + ret += Run (zero, 1); + fprintf (stderr, "Test2 passed\n"); + return ret; +} + +#include <support/test-driver.c>