diff --git a/ChangeLog b/ChangeLog index 6fd1c664fd..bb7a04b007 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2015-05-08 Carlos O'Donell + + [BZ #18125] + * stdlib/tst-setcontext3.c: New file. + * stdlib/tst-setcontext3.sh: New file. + * stdlib/Makefile (tests): Add tst-setcontext3. + (tst-setcontext3.out): Custom rule to run tst-setcontext3.sh + to verify test program created output file. + * sysdeps/unix/sysv/linux/aarch64/setcontext.S: Call exit. + * sysdeps/unix/sysv/linux/arm/setcontext.S: Likewise. + * sysdeps/unix/sysv/linux/hppa/setcontext.S: Likewise. + * sysdeps/unix/sysv/linux/nios2/setcontext.S: Likewise. + 2015-05-06 Roland McGrath [BZ #18383] diff --git a/NEWS b/NEWS index aaaaf4e536..fb4228330a 100644 --- a/NEWS +++ b/NEWS @@ -9,15 +9,15 @@ Version 2.22 * The following bugs are resolved with this release: - 4719, 6792, 13064, 14094, 14841, 14906, 15319, 15467, 15790, 15969, 16351, - 16512, 16560, 16783, 16850, 17090, 17195, 17269, 17523, 17542, 17569, - 17588, 17596, 17620, 17621, 17628, 17631, 17692, 17711, 17715, 17776, - 17779, 17792, 17836, 17912, 17916, 17930, 17932, 17944, 17949, 17964, - 17965, 17967, 17969, 17978, 17987, 17991, 17996, 17998, 17999, 18007, - 18019, 18020, 18029, 18030, 18032, 18036, 18038, 18039, 18042, 18043, - 18046, 18047, 18068, 18080, 18093, 18100, 18104, 18110, 18111, 18128, - 18138, 18185, 18197, 18206, 18210, 18211, 18247, 18287, 18319, 18333, - 18346. + 4719, 6792, 13064, 14094, 14841, 14906, 15319, 15467, 15790, 15969, + 16351, 16512, 16560, 16783, 16850, 17090, 17195, 17269, 17523, 17542, + 17569, 17588, 17596, 17620, 17621, 17628, 17631, 17692, 17711, 17715, + 17776, 17779, 17792, 17836, 17912, 17916, 17930, 17932, 17944, 17949, + 17964, 17965, 17967, 17969, 17978, 17987, 17991, 17996, 17998, 17999, + 18007, 18019, 18020, 18029, 18030, 18032, 18036, 18038, 18039, 18042, + 18043, 18046, 18047, 18068, 18080, 18093, 18100, 18104, 18110, 18111, + 18125, 18128, 18138, 18185, 18197, 18206, 18210, 18211, 18247, 18287, + 18319, 18333, 18346. * Cache information can be queried via sysconf() function on s390 e.g. with _SC_LEVEL1_ICACHE_SIZE as argument. diff --git a/stdlib/Makefile b/stdlib/Makefile index c78fdb51ec..3300dd2142 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -73,7 +73,8 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1 \ tst-makecontext3 bug-getcontext bug-fmtmsg1 \ tst-secure-getenv tst-strtod-overflow tst-strtod-round \ - tst-tininess tst-strtod-underflow tst-tls-atexit + tst-tininess tst-strtod-underflow tst-tls-atexit \ + tst-setcontext3 tests-static := tst-secure-getenv modules-names = tst-tls-atexit-lib @@ -157,3 +158,9 @@ tst-tls-atexit-lib.so-no-z-defs = yes $(objpfx)tst-tls-atexit: $(shared-thread-library) $(libdl) $(objpfx)tst-tls-atexit.out: $(objpfx)tst-tls-atexit-lib.so + +$(objpfx)tst-setcontext3.out: tst-setcontext3.sh $(objpfx)tst-setcontext3 + $(SHELL) $< $(common-objpfx) '$(test-program-prefix-before-env)' \ + '$(run-program-env)' '$(test-program-prefix-after-env)' \ + $(common-objpfx)stdlib/; \ + $(evaluate-test) diff --git a/stdlib/tst-setcontext3.c b/stdlib/tst-setcontext3.c new file mode 100644 index 0000000000..fda21285c6 --- /dev/null +++ b/stdlib/tst-setcontext3.c @@ -0,0 +1,138 @@ +/* Bug 18125: Verify setcontext calls exit() and not _exit(). + Copyright (C) 2015 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Please note that depending on the outcome of Bug 18135 this test + may become invalid, and instead of testing for calling exit it + should be reworked to test for the last context calling + pthread_exit(). */ + +static ucontext_t ctx; +static char *filename; + +/* It is intended that this function does nothing. */ +static void +cf (void) +{ + printf ("called context function\n"); +} + +static void +exit_called (void) +{ + int fd; + ssize_t res; + const char buf[] = "Called exit function\n"; + + fd = open (filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + if (fd == -1) + { + printf ("FAIL: Unable to create test file %s\n", filename); + exit (1); + } + res = write (fd, buf, sizeof (buf)); + if (res != sizeof (buf)) + { + printf ("FAIL: Expected to write test file in one write call.\n"); + exit (1); + } + res = close (fd); + if (res == -1) + { + printf ("FAIL: Failed to close test file.\n"); + exit (1); + } + printf ("PASS: %s", buf); +} + +/* The test expects a filename given by the wrapper calling script. + The test then registers an atexit handler that will create the + file to indicate that the atexit handler ran. Then the test + creates a context, modifies it with makecontext, and sets it. + The context has only a single context which then must exit. + If it incorrectly exits via _exit then the atexit handler is + not run, the file is not created, and the wrapper detects this + and fails the test. This test cannot be done using an _exit + interposer since setcontext avoids the PLT and calls _exit + directly. */ +static int +do_test (int argc, char **argv) +{ + int ret; + char st1[32768]; + ucontext_t tempctx = ctx; + + if (argc < 2) + { + printf ("FAIL: Test missing filename argument.\n"); + exit (1); + } + + filename = argv[1]; + + atexit (exit_called); + + puts ("making contexts"); + if (getcontext (&ctx) != 0) + { + if (errno == ENOSYS) + { + /* Exit with 77 to mark the test as UNSUPPORTED. */ + printf ("UNSUPPORTED: getcontext not implemented.\n"); + exit (77); + } + + printf ("FAIL: getcontext failed.\n"); + exit (1); + } + + ctx.uc_stack.ss_sp = st1; + ctx.uc_stack.ss_size = sizeof (st1); + ctx.uc_link = 0; + makecontext (&ctx, cf, 0); + + /* Without this check, a stub makecontext can make us spin forever. */ + if (memcmp (&tempctx, &ctx, sizeof ctx) == 0) + { + puts ("UNSUPPORTED: makecontext was a no-op, presuming not implemented"); + exit (77); + } + + ret = setcontext (&ctx); + if (ret != 0) + { + printf ("FAIL: setcontext returned with %d and errno of %d.\n", ret, errno); + exit (1); + } + + printf ("FAIL: Impossibly returned to main.\n"); + exit (1); +} + +#include "../test-skeleton.c" diff --git a/stdlib/tst-setcontext3.sh b/stdlib/tst-setcontext3.sh new file mode 100644 index 0000000000..6ad67a8aeb --- /dev/null +++ b/stdlib/tst-setcontext3.sh @@ -0,0 +1,54 @@ +#! /bin/bash +# Bug 18125: Test the exit functionality of setcontext(). +# Copyright (C) 2015 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 +# . + +set -e + +common_objpfx=$1 +test_program_prefix_before_env=$2 +run_program_env=$3 +test_program_prefix_after_env=$4 +objpfx=$5 + +test_pre="${test_program_prefix_before_env} ${run_program_env}" +test="${test_program_prefix_after_env} ${objpfx}tst-setcontext3" +out=${objpfx}tst-setcontext3.out + +tempfiles=() +cleanup() { + rm -f "${tempfiles[@]}" +} +trap cleanup 0 + +tempfile=$(mktemp "tst-setcontext3.XXXXXXXXXX") +tempfiles+=("$tempfile") + +# We want to run the test program and see if secontext called +# exit() and wrote out the test file we specified. If the +# test exits with a non-zero status this will fail because we +# are using `set -e`. +$test_pre $test "$tempfile" + +# Look for resulting file. +if [ -e "$tempfile" ]; then + echo "PASS: tst-setcontext3 an exit() and created $tempfile" + exit 0 +else + echo "FAIL: tst-setcontext3 did not create $tempfile" + exit 1 +fi diff --git a/sysdeps/unix/sysv/linux/aarch64/setcontext.S b/sysdeps/unix/sysv/linux/aarch64/setcontext.S index 6dd78361cd..ae67581660 100644 --- a/sysdeps/unix/sysv/linux/aarch64/setcontext.S +++ b/sysdeps/unix/sysv/linux/aarch64/setcontext.S @@ -125,5 +125,5 @@ weak_alias (__setcontext, setcontext) ENTRY (__startcontext) mov x0, x19 cbnz x0, __setcontext -1: b HIDDEN_JUMPTARGET (_exit) +1: b HIDDEN_JUMPTARGET (exit) END (__startcontext) diff --git a/sysdeps/unix/sysv/linux/arm/setcontext.S b/sysdeps/unix/sysv/linux/arm/setcontext.S index 5268e06892..24c72945c8 100644 --- a/sysdeps/unix/sysv/linux/arm/setcontext.S +++ b/sysdeps/unix/sysv/linux/arm/setcontext.S @@ -91,7 +91,7 @@ ENTRY(__startcontext) bne PLTJMP(__setcontext) @ New context was 0 - exit - b PLTJMP(HIDDEN_JUMPTARGET(_exit)) + b PLTJMP(HIDDEN_JUMPTARGET(exit)) END(__startcontext) #ifdef PIC diff --git a/sysdeps/unix/sysv/linux/hppa/setcontext.S b/sysdeps/unix/sysv/linux/hppa/setcontext.S index 72714104f8..abe87a9603 100644 --- a/sysdeps/unix/sysv/linux/hppa/setcontext.S +++ b/sysdeps/unix/sysv/linux/hppa/setcontext.S @@ -18,6 +18,7 @@ . */ #include +#include #include "ucontext_i.h" @@ -139,7 +140,7 @@ ENTRY(__setcontext) nop /* No further context available. Exit now. */ - bl _exit, %r2 + bl HIDDEN_JUMPTARGET(exit), %r2 ldi -1, %r26 diff --git a/sysdeps/unix/sysv/linux/nios2/setcontext.S b/sysdeps/unix/sysv/linux/nios2/setcontext.S index 9a8dd87b93..f40b73389d 100644 --- a/sysdeps/unix/sysv/linux/nios2/setcontext.S +++ b/sysdeps/unix/sysv/linux/nios2/setcontext.S @@ -89,15 +89,15 @@ ENTRY(__startcontext) mov r4, r16 bne r4, zero, __setcontext - /* If uc_link == zero, call _exit. */ + /* If uc_link == zero, call exit. */ #ifdef PIC nextpc r22 1: movhi r8, %hiadj(_gp_got - 1b) addi r8, r8, %lo(_gp_got - 1b) add r22, r22, r8 - ldw r8, %call(HIDDEN_JUMPTARGET(_exit))(r22) + ldw r8, %call(HIDDEN_JUMPTARGET(exit))(r22) jmp r8 #else - jmpi _exit + jmpi exit #endif END(__startcontext)