| commit 7c9a7c68363051cfc5fa1ebb96b3b2c1f82dcb76 |
| Author: DJ Delorie <dj@redhat.com> |
| Date: Fri Nov 30 22:13:09 2018 -0500 |
| |
| malloc: Add another test for tcache double free check. |
| |
| This one tests for BZ#23907 where the double free |
| test didn't check the tcache bin bounds before dereferencing |
| the bin. |
| |
| [BZ #23907] |
| * malloc/tst-tcfree3.c: New. |
| * malloc/Makefile: Add it. |
| |
| diff --git a/malloc/Makefile b/malloc/Makefile |
| index e6dfbfc14cb3d140..388cf7e9ee3a2569 100644 |
| |
| |
| @@ -38,7 +38,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ |
| tst-malloc_info \ |
| tst-malloc-too-large \ |
| tst-malloc-stats-cancellation \ |
| - tst-tcfree1 tst-tcfree2 \ |
| + tst-tcfree1 tst-tcfree2 tst-tcfree3 \ |
| |
| tests-static := \ |
| tst-interpose-static-nothread \ |
| diff --git a/malloc/tst-tcfree3.c b/malloc/tst-tcfree3.c |
| new file mode 100644 |
| index 0000000000000000..016d30ddd8114082 |
| |
| |
| @@ -0,0 +1,56 @@ |
| +/* Test that malloc tcache catches double free. |
| + 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 <malloc.h> |
| +#include <string.h> |
| + |
| +/* Prevent GCC from optimizing away any malloc/free pairs. */ |
| +#pragma GCC optimize ("O0") |
| + |
| +static int |
| +do_test (void) |
| +{ |
| + /* Do two allocation of any size that fit in tcache, and one that |
| + doesn't. */ |
| + int ** volatile a = malloc (32); |
| + int ** volatile b = malloc (32); |
| + /* This is just under the mmap threshold. */ |
| + int ** volatile c = malloc (127 * 1024); |
| + |
| + /* The invalid "tcache bucket" we might dereference will likely end |
| + up somewhere within this memory block, so make all the accidental |
| + "next" pointers cause segfaults. BZ #23907. */ |
| + memset (c, 0xff, 127 * 1024); |
| + |
| + free (a); // puts in tcache |
| + |
| + /* A is now free and contains the key we use to detect in-tcache. |
| + Copy the key to the other chunks. */ |
| + memcpy (b, a, 32); |
| + memcpy (c, a, 32); |
| + |
| + /* This free tests the "are we in the tcache already" loop with a |
| + VALID bin but "coincidental" matching key. */ |
| + free (b); // should NOT abort |
| + /* This free tests the "is it a valid tcache bin" test. */ |
| + free (c); // should NOT abort |
| + |
| + return 0; |
| +} |
| + |
| +#include <support/test-driver.c> |