]> git.ipfire.org Git - thirdparty/glibc.git/blame - stdlib/tst-canon-bz26341.c
support: Add capability to fork an sgid child
[thirdparty/glibc.git] / stdlib / tst-canon-bz26341.c
CommitLineData
961d7cff
AZ
1/* Check if realpath does not consume extra stack space based on symlink
2 existance in the path (BZ #26341)
3 Copyright (C) 2021 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
19
20#include <stdlib.h>
21#include <string.h>
22#include <sys/param.h>
23#include <unistd.h>
24
25#define __sysconf sysconf
26#include <eloop-threshold.h>
27#include <support/check.h>
28#include <support/support.h>
29#include <support/temp_file.h>
30#include <support/xunistd.h>
31#include <support/xthread.h>
32
33static char *filename;
34static size_t filenamelen;
35static char *linkname;
36
37#ifndef PATH_MAX
38# define PATH_MAX 1024
39#endif
40
41static void
42create_link (void)
43{
44 int fd = create_temp_file ("tst-canon-bz26341", &filename);
45 TEST_VERIFY_EXIT (fd != -1);
46 xclose (fd);
47
48 /* Create MAXLINKS symbolic links to the temporary filename.
49 On exit, linkname has the last link created. */
50 char *prevlink = filename;
51 int maxlinks = __eloop_threshold ();
52 for (int i = 0; i < maxlinks; i++)
53 {
54 linkname = xasprintf ("%s%d", filename, i);
55 xsymlink (prevlink, linkname);
56 add_temp_file (linkname);
57 prevlink = linkname;
58 }
59
60 filenamelen = strlen (filename);
61}
62
63static void *
64do_realpath (void *arg)
65{
66 /* Old implementation of realpath allocates a PATH_MAX using alloca
67 for each symlink in the path, leading to MAXSYMLINKS times PATH_MAX
68 maximum stack usage.
69 This stack allocations tries fill the thread allocated stack minus
4631c237
ST
70 the resolved path (plus some slack), the realpath (plus some
71 slack), and the system call usage (plus some slack).
961d7cff
AZ
72 If realpath uses more than 2 * PATH_MAX plus some slack it will trigger
73 a stackoverflow. */
74
4631c237 75 const size_t syscall_usage = 1 * PATH_MAX + 1024;
961d7cff
AZ
76 const size_t realpath_usage = 2 * PATH_MAX + 1024;
77 const size_t thread_usage = 1 * PATH_MAX + 1024;
78 size_t stack_size = support_small_thread_stack_size ()
4631c237 79 - syscall_usage - realpath_usage - thread_usage;
961d7cff
AZ
80 char stack[stack_size];
81 char *resolved = stack + stack_size - thread_usage + 1024;
82
83 char *p = realpath (linkname, resolved);
84 TEST_VERIFY (p != NULL);
85 TEST_COMPARE_BLOB (resolved, filenamelen, filename, filenamelen);
86
87 return NULL;
88}
89
90static int
91do_test (void)
92{
93 create_link ();
94
95 pthread_t th = xpthread_create (support_small_stack_thread_attribute (),
96 do_realpath, NULL);
97 xpthread_join (th);
98
99 return 0;
100}
101
102#include <support/test-driver.c>