math: Remove slow paths from atan [BZ #15267]
[glibc.git] / malloc / tst-safe-linking.c
blob97cc108be683085e0047b9912d403c173150daac
1 /* Test reporting of Safe-Linking caught errors.
2 Copyright (C) 2020-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #include <signal.h>
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <memory.h>
23 #include <string.h>
24 #include <time.h>
25 #include <stdbool.h>
26 #include <support/capture_subprocess.h>
27 #include <support/check.h>
29 /* Run CALLBACK and check that the data on standard error equals
30 EXPECTED. */
31 static void
32 check (const char *test, void (*callback) (void *),
33 const char *expected)
35 int i, rand_mask;
36 bool success = false;
37 /* There is a chance of 1/16 that a corrupted pointer will be aligned.
38 Try multiple times so that statistical failure will be improbable. */
39 for (i = 0; i < 10 && !success; ++i)
41 rand_mask = rand () & 0xFF;
42 struct support_capture_subprocess result
43 = support_capture_subprocess (callback, &rand_mask);
44 /* Did not crash, could happen. Try again. */
45 if (strlen (result.err.buffer) == 0)
46 continue;
47 /* Crashed, must be the expected result. */
48 if (strcmp (result.err.buffer, expected) != 0)
50 support_record_failure ();
51 printf ("error: test %s unexpected standard error data\n"
52 " expected: %s\n"
53 " actual: %s\n",
54 test, expected, result.err.buffer);
56 TEST_VERIFY (WIFSIGNALED (result.status));
57 if (WIFSIGNALED (result.status))
58 TEST_VERIFY (WTERMSIG (result.status) == SIGABRT);
59 support_capture_subprocess_free (&result);
60 success = true;
62 TEST_VERIFY (success);
65 /* Implementation details must be kept in sync with malloc. */
66 #define TCACHE_FILL_COUNT 7
67 #define TCACHE_ALLOC_SIZE 0x20
68 #define MALLOC_CONSOLIDATE_SIZE 256*1024
70 /* Try corrupting the tcache list. */
71 static void
72 test_tcache (void *closure)
74 int mask = ((int *)closure)[0];
75 size_t size = TCACHE_ALLOC_SIZE;
77 /* Populate the tcache list. */
78 void * volatile a = malloc (size);
79 void * volatile b = malloc (size);
80 void * volatile c = malloc (size);
81 free (a);
82 free (b);
83 free (c);
85 /* Corrupt the pointer with a random value, and avoid optimizations. */
86 printf ("Before: c=%p, c[0]=%p\n", c, ((void **)c)[0]);
87 memset (c, mask & 0xFF, size);
88 printf ("After: c=%p, c[0]=%p\n", c, ((void **)c)[0]);
90 c = malloc (size);
91 /* This line will trigger the Safe-Linking check. */
92 b = malloc (size);
93 printf ("b=%p\n", b);
96 /* Try corrupting the fastbin list. */
97 static void
98 test_fastbin (void *closure)
100 int i;
101 int mask = ((int *)closure)[0];
102 size_t size = TCACHE_ALLOC_SIZE;
104 /* Take the tcache out of the game. */
105 for (i = 0; i < TCACHE_FILL_COUNT; ++i)
107 void * volatile p = calloc (1, size);
108 free (p);
111 /* Populate the fastbin list. */
112 void * volatile a = calloc (1, size);
113 void * volatile b = calloc (1, size);
114 void * volatile c = calloc (1, size);
115 free (a);
116 free (b);
117 free (c);
119 /* Corrupt the pointer with a random value, and avoid optimizations. */
120 printf ("Before: c=%p, c[0]=%p\n", c, ((void **)c)[0]);
121 memset (c, mask & 0xFF, size);
122 printf ("After: c=%p, c[0]=%p\n", c, ((void **)c)[0]);
124 c = calloc (1, size);
125 /* This line will trigger the Safe-Linking check. */
126 b = calloc (1, size);
127 printf ("b=%p\n", b);
130 /* Try corrupting the fastbin list and trigger a consolidate. */
131 static void
132 test_fastbin_consolidate (void *closure)
134 int i;
135 int mask = ((int*)closure)[0];
136 size_t size = TCACHE_ALLOC_SIZE;
138 /* Take the tcache out of the game. */
139 for (i = 0; i < TCACHE_FILL_COUNT; ++i)
141 void * volatile p = calloc (1, size);
142 free (p);
145 /* Populate the fastbin list. */
146 void * volatile a = calloc (1, size);
147 void * volatile b = calloc (1, size);
148 void * volatile c = calloc (1, size);
149 free (a);
150 free (b);
151 free (c);
153 /* Corrupt the pointer with a random value, and avoid optimizations. */
154 printf ("Before: c=%p, c[0]=%p\n", c, ((void **)c)[0]);
155 memset (c, mask & 0xFF, size);
156 printf ("After: c=%p, c[0]=%p\n", c, ((void **)c)[0]);
158 /* This line will trigger the Safe-Linking check. */
159 b = malloc (MALLOC_CONSOLIDATE_SIZE);
160 printf ("b=%p\n", b);
163 static int
164 do_test (void)
166 /* Seed the random for the test. */
167 srand (time (NULL));
169 check ("test_tcache", test_tcache,
170 "malloc(): unaligned tcache chunk detected\n");
171 check ("test_fastbin", test_fastbin,
172 "malloc(): unaligned fastbin chunk detected 2\n");
173 check ("test_fastbin_consolidate", test_fastbin_consolidate,
174 "malloc_consolidate(): unaligned fastbin chunk detected\n");
176 return 0;
179 #include <support/test-driver.c>