diff options
Diffstat (limited to 'debug')
-rw-r--r-- | debug/Makefile | 1 | ||||
-rw-r--r-- | debug/Versions | 3 | ||||
-rw-r--r-- | debug/explicit_bzero_chk.c | 44 | ||||
-rw-r--r-- | debug/tst-chk1.c | 28 |
4 files changed, 76 insertions, 0 deletions
diff --git a/debug/Makefile b/debug/Makefile index 6b5f31e4f6..84d3f92c0d 100644 --- a/debug/Makefile +++ b/debug/Makefile @@ -48,6 +48,7 @@ routines = backtrace backtracesyms backtracesymsfd noophooks \ vdprintf_chk obprintf_chk \ longjmp_chk ____longjmp_chk \ fdelt_chk poll_chk ppoll_chk \ + explicit_bzero_chk \ stack_chk_fail fortify_fail \ $(static-only-routines) static-only-routines := warning-nop stack_chk_fail_local diff --git a/debug/Versions b/debug/Versions index 0482c85f19..a6628db356 100644 --- a/debug/Versions +++ b/debug/Versions @@ -55,6 +55,9 @@ libc { GLIBC_2.16 { __poll_chk; __ppoll_chk; } + GLIBC_2.25 { + __explicit_bzero_chk; + } GLIBC_PRIVATE { __fortify_fail; } diff --git a/debug/explicit_bzero_chk.c b/debug/explicit_bzero_chk.c new file mode 100644 index 0000000000..2e507f8297 --- /dev/null +++ b/debug/explicit_bzero_chk.c @@ -0,0 +1,44 @@ +/* Generic implementation of __explicit_bzero_chk. + Copyright (C) 1991-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Torbjorn Granlund (tege@sics.se). + + 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/>. */ + +/* This is the generic definition of __explicit_bzero_chk. The + __explicit_bzero_chk symbol is used as the implementation of + explicit_bzero throughout glibc. If this file is overriden by an + architecture, both __explicit_bzero_chk and + __explicit_bzero_chk_internal have to be defined (the latter not as + an IFUNC). */ + +#include <string.h> + +void +__explicit_bzero_chk (void *dst, size_t len, size_t dstlen) +{ + /* Inline __memset_chk to avoid a PLT reference to __memset_chk. */ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + memset (dst, '\0', len); + /* Compiler barrier. */ + asm volatile ("" ::: "memory"); +} + +/* libc-internal references use the hidden + __explicit_bzero_chk_internal symbol. This is necessary if + __explicit_bzero_chk is implemented as an IFUNC because some + targets do not support hidden references to IFUNC symbols. */ +strong_alias (__explicit_bzero_chk, __explicit_bzero_chk_internal) diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c index 478c2fbb81..e87a279fb2 100644 --- a/debug/tst-chk1.c +++ b/debug/tst-chk1.c @@ -160,6 +160,10 @@ do_test (void) if (memcmp (buf, "aabcdabc\0\0", 10)) FAIL (); + explicit_bzero (buf + 6, 4); + if (memcmp (buf, "aabcda\0\0\0\0", 10)) + FAIL (); + strcpy (buf + 4, "EDCBA"); if (memcmp (buf, "aabcEDCBA", 10)) FAIL (); @@ -201,6 +205,10 @@ do_test (void) if (memcmp (buf, "aabcdabc\0\0", 10)) FAIL (); + explicit_bzero (buf + 6, l0 + 4); + if (memcmp (buf, "aabcda\0\0\0\0", 10)) + FAIL (); + strcpy (buf + 4, str1 + 5); if (memcmp (buf, "aabcEDCBA", 10)) FAIL (); @@ -256,6 +264,10 @@ do_test (void) if (memcmp (a.buf1, "aabcdabc\0\0", 10)) FAIL (); + explicit_bzero (a.buf1 + 6, l0 + 4); + if (memcmp (a.buf1, "aabcda\0\0\0\0", 10)) + FAIL (); + #if __USE_FORTIFY_LEVEL < 2 /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2 and sufficient GCC support, as the string operations overflow @@ -346,6 +358,14 @@ do_test (void) CHK_FAIL_END CHK_FAIL_START + explicit_bzero (buf + 9, 2); + CHK_FAIL_END + + CHK_FAIL_START + explicit_bzero (buf + 9, l0 + 2); + CHK_FAIL_END + + CHK_FAIL_START strcpy (buf + 5, str1 + 5); CHK_FAIL_END @@ -454,6 +474,14 @@ do_test (void) bzero (a.buf1 + 9, l0 + 2); CHK_FAIL_END + CHK_FAIL_START + explicit_bzero (a.buf1 + 9, 2); + CHK_FAIL_END + + CHK_FAIL_START + explicit_bzero (a.buf1 + 9, l0 + 2); + CHK_FAIL_END + # if __USE_FORTIFY_LEVEL >= 2 # define O 0 # else |