This source file includes following definitions.
- test_abort_bug
- test_long_name
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <config.h>
18
19 #include <unistd.h>
20
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <limits.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/stat.h>
28
29 #include "pathmax.h"
30 #include "qemu.h"
31 #include "macros.h"
32
33 #if !(HAVE_GETPAGESIZE || defined getpagesize)
34 # define getpagesize() 0
35 #endif
36
37
38
39
40 #define TARGET_LEN (5 * 1024)
41
42 #if defined HAVE_OPENAT || (defined GNULIB_OPENAT && defined HAVE_FDOPENDIR)
43 # define HAVE_OPENAT_SUPPORT 1
44 #else
45 # define HAVE_OPENAT_SUPPORT 0
46 #endif
47
48
49 static int
50 test_abort_bug (void)
51 {
52 char *cwd;
53 size_t initial_cwd_len;
54 int fail = 0;
55
56
57
58 #ifdef PATH_MAX
59 int bug_possible = PATH_MAX < getpagesize ();
60 #else
61 int bug_possible = 0;
62 #endif
63 if (! bug_possible)
64 return 0;
65
66 cwd = getcwd (NULL, 0);
67 if (cwd == NULL)
68 return 2;
69
70 initial_cwd_len = strlen (cwd);
71 free (cwd);
72
73 if (HAVE_OPENAT_SUPPORT)
74 {
75 static char const dir_name[] = "confdir-14B---";
76 size_t desired_depth = ((TARGET_LEN - 1 - initial_cwd_len)
77 / sizeof dir_name);
78 size_t d;
79 for (d = 0; d < desired_depth; d++)
80 {
81 if (mkdir (dir_name, S_IRWXU) < 0 || chdir (dir_name) < 0)
82 {
83 if (! (errno == ERANGE || errno == ENAMETOOLONG
84 || errno == ENOENT))
85 fail = 3;
86 break;
87 }
88 }
89
90
91
92 cwd = getcwd (NULL, 0);
93 if (cwd == NULL)
94 fail = 4;
95
96 free (cwd);
97
98
99 rmdir (dir_name);
100 while (0 < d--)
101 {
102 if (chdir ("..") < 0)
103 {
104 fail = 5;
105 break;
106 }
107 rmdir (dir_name);
108 }
109 }
110
111 return fail;
112 }
113
114
115 #define DIR_NAME "confdir3"
116 #define DIR_NAME_LEN 8
117 #define DIR_NAME_SIZE (DIR_NAME_LEN + 1)
118
119
120 #define DOTDOTSLASH_LEN 3
121
122
123 #define BUF_SLOP 20
124
125
126 static int
127 test_long_name (void)
128 {
129 #ifndef PATH_MAX
130
131
132
133
134 return 0;
135 #elif ((INT_MAX / (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1) \
136 - DIR_NAME_SIZE - BUF_SLOP) \
137 <= PATH_MAX)
138
139
140 return 0;
141 #else
142
143
144
145
146 if (is_running_under_qemu_user ())
147 return 77;
148
149 char buf[PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1)
150 + DIR_NAME_SIZE + BUF_SLOP];
151 char *cwd = getcwd (buf, PATH_MAX);
152 size_t initial_cwd_len;
153 size_t cwd_len;
154 int fail = 0;
155 size_t n_chdirs = 0;
156
157 if (cwd == NULL)
158 return 1;
159
160 cwd_len = initial_cwd_len = strlen (cwd);
161
162 while (1)
163 {
164 # ifdef HAVE_GETCWD_SHORTER
165
166
167 size_t dotdot_max = PATH_MAX * 2;
168 # else
169 size_t dotdot_max = PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN);
170 # endif
171 char *c = NULL;
172
173 cwd_len += DIR_NAME_SIZE;
174
175
176
177
178
179
180
181
182
183
184 if (mkdir (DIR_NAME, S_IRWXU) < 0 || chdir (DIR_NAME) < 0)
185 {
186 if (! (errno == ERANGE || errno == ENAMETOOLONG || errno == ENOENT))
187 #ifdef __linux__
188 if (! (errno == EINVAL))
189 #endif
190 fail = 2;
191 break;
192 }
193
194 if (PATH_MAX <= cwd_len && cwd_len < PATH_MAX + DIR_NAME_SIZE)
195 {
196 c = getcwd (buf, PATH_MAX);
197 if (!c && errno == ENOENT)
198 {
199 fail = 3;
200 break;
201 }
202 if (c)
203 {
204 fail = 4;
205 break;
206 }
207 if (! (errno == ERANGE || errno == ENAMETOOLONG))
208 {
209 fail = 5;
210 break;
211 }
212 }
213
214 if (dotdot_max <= cwd_len - initial_cwd_len)
215 {
216 if (dotdot_max + DIR_NAME_SIZE < cwd_len - initial_cwd_len)
217 break;
218 c = getcwd (buf, cwd_len + 1);
219 if (!c)
220 {
221 if (! (errno == ERANGE || errno == ENOENT
222 || errno == ENAMETOOLONG))
223 {
224 fail = 6;
225 break;
226 }
227 if (HAVE_OPENAT_SUPPORT || errno == ERANGE || errno == ENOENT)
228 {
229 fail = 7;
230 break;
231 }
232 }
233 }
234
235 if (c && strlen (c) != cwd_len)
236 {
237 fail = 8;
238 break;
239 }
240 ++n_chdirs;
241 }
242
243
244
245
246 {
247 size_t i;
248
249
250 rmdir (DIR_NAME);
251 for (i = 0; i <= n_chdirs; i++)
252 {
253 if (chdir ("..") < 0)
254 break;
255 if (rmdir (DIR_NAME) != 0)
256 break;
257 }
258 }
259
260 return fail;
261 #endif
262 }
263
264 int
265 main (int argc, char **argv)
266 {
267 int err1 = test_abort_bug ();
268 int err2 = test_long_name ();
269 return err1 * 10 + (err1 != 0 && err2 == 77 ? 0 : err2);
270 }