aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorSteve Muckle <smuckle.linux@gmail.com>2017-10-13 00:44:57 -0400
committerShuah Khan <shuahkh@osg.samsung.com>2017-11-15 10:01:42 -0500
commit2d80c92d6cae986e8f3f04e64dbea9883680ae1c (patch)
treed662412c2bccb69adda61de54848d1ee2305f80f /tools
parentd54e9a8f4430d789a7b462b5318b1012d5643fd4 (diff)
selftests/exec: include cwd in long path calculation
When creating a pathname close to PATH_MAX to test execveat, factor in the current working directory path otherwise we end up with an absolute path that is longer than PATH_MAX. While execveat() may succeed, subsequent calls to the kernel from the runtime environment which are required to successfully execute the test binary/script may fail because of this. To keep the semantics of the test the same, rework the relative pathname part of the test to be relative to the root directory so it isn't decreased by the length of the current working directory path. Signed-off-by: Steve Muckle <smuckle.linux@gmail.com> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/exec/execveat.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/tools/testing/selftests/exec/execveat.c b/tools/testing/selftests/exec/execveat.c
index 8d5d1d2ee7c1..67cd4597db2b 100644
--- a/tools/testing/selftests/exec/execveat.c
+++ b/tools/testing/selftests/exec/execveat.c
@@ -147,7 +147,7 @@ static void exe_cp(const char *src, const char *dest)
147} 147}
148 148
149#define XX_DIR_LEN 200 149#define XX_DIR_LEN 200
150static int check_execveat_pathmax(int dot_dfd, const char *src, int is_script) 150static int check_execveat_pathmax(int root_dfd, const char *src, int is_script)
151{ 151{
152 int fail = 0; 152 int fail = 0;
153 int ii, count, len; 153 int ii, count, len;
@@ -156,20 +156,30 @@ static int check_execveat_pathmax(int dot_dfd, const char *src, int is_script)
156 156
157 if (*longpath == '\0') { 157 if (*longpath == '\0') {
158 /* Create a filename close to PATH_MAX in length */ 158 /* Create a filename close to PATH_MAX in length */
159 char *cwd = getcwd(NULL, 0);
160
161 if (!cwd) {
162 printf("Failed to getcwd(), errno=%d (%s)\n",
163 errno, strerror(errno));
164 return 2;
165 }
166 strcpy(longpath, cwd);
167 strcat(longpath, "/");
159 memset(longname, 'x', XX_DIR_LEN - 1); 168 memset(longname, 'x', XX_DIR_LEN - 1);
160 longname[XX_DIR_LEN - 1] = '/'; 169 longname[XX_DIR_LEN - 1] = '/';
161 longname[XX_DIR_LEN] = '\0'; 170 longname[XX_DIR_LEN] = '\0';
162 count = (PATH_MAX - 3) / XX_DIR_LEN; 171 count = (PATH_MAX - 3 - strlen(cwd)) / XX_DIR_LEN;
163 for (ii = 0; ii < count; ii++) { 172 for (ii = 0; ii < count; ii++) {
164 strcat(longpath, longname); 173 strcat(longpath, longname);
165 mkdir(longpath, 0755); 174 mkdir(longpath, 0755);
166 } 175 }
167 len = (PATH_MAX - 3) - (count * XX_DIR_LEN); 176 len = (PATH_MAX - 3 - strlen(cwd)) - (count * XX_DIR_LEN);
168 if (len <= 0) 177 if (len <= 0)
169 len = 1; 178 len = 1;
170 memset(longname, 'y', len); 179 memset(longname, 'y', len);
171 longname[len] = '\0'; 180 longname[len] = '\0';
172 strcat(longpath, longname); 181 strcat(longpath, longname);
182 free(cwd);
173 } 183 }
174 exe_cp(src, longpath); 184 exe_cp(src, longpath);
175 185
@@ -190,7 +200,7 @@ static int check_execveat_pathmax(int dot_dfd, const char *src, int is_script)
190 } 200 }
191 201
192 /* 202 /*
193 * Execute as a long pathname relative to ".". If this is a script, 203 * Execute as a long pathname relative to "/". If this is a script,
194 * the interpreter will launch but fail to open the script because its 204 * the interpreter will launch but fail to open the script because its
195 * name ("/dev/fd/5/xxx....") is bigger than PATH_MAX. 205 * name ("/dev/fd/5/xxx....") is bigger than PATH_MAX.
196 * 206 *
@@ -200,10 +210,10 @@ static int check_execveat_pathmax(int dot_dfd, const char *src, int is_script)
200 * the exit status shall be 126."), so allow either. 210 * the exit status shall be 126."), so allow either.
201 */ 211 */
202 if (is_script) 212 if (is_script)
203 fail += check_execveat_invoked_rc(dot_dfd, longpath, 0, 213 fail += check_execveat_invoked_rc(root_dfd, longpath + 1, 0,
204 127, 126); 214 127, 126);
205 else 215 else
206 fail += check_execveat(dot_dfd, longpath, 0); 216 fail += check_execveat(root_dfd, longpath + 1, 0);
207 217
208 return fail; 218 return fail;
209} 219}
@@ -218,6 +228,7 @@ static int run_tests(void)
218 int subdir_dfd_ephemeral = open_or_die("subdir.ephemeral", 228 int subdir_dfd_ephemeral = open_or_die("subdir.ephemeral",
219 O_DIRECTORY|O_RDONLY); 229 O_DIRECTORY|O_RDONLY);
220 int dot_dfd = open_or_die(".", O_DIRECTORY|O_RDONLY); 230 int dot_dfd = open_or_die(".", O_DIRECTORY|O_RDONLY);
231 int root_dfd = open_or_die("/", O_DIRECTORY|O_RDONLY);
221 int dot_dfd_path = open_or_die(".", O_DIRECTORY|O_RDONLY|O_PATH); 232 int dot_dfd_path = open_or_die(".", O_DIRECTORY|O_RDONLY|O_PATH);
222 int dot_dfd_cloexec = open_or_die(".", O_DIRECTORY|O_RDONLY|O_CLOEXEC); 233 int dot_dfd_cloexec = open_or_die(".", O_DIRECTORY|O_RDONLY|O_CLOEXEC);
223 int fd = open_or_die("execveat", O_RDONLY); 234 int fd = open_or_die("execveat", O_RDONLY);
@@ -353,8 +364,8 @@ static int run_tests(void)
353 /* Attempt to execute relative to non-directory => ENOTDIR */ 364 /* Attempt to execute relative to non-directory => ENOTDIR */
354 fail += check_execveat_fail(fd, "execveat", 0, ENOTDIR); 365 fail += check_execveat_fail(fd, "execveat", 0, ENOTDIR);
355 366
356 fail += check_execveat_pathmax(dot_dfd, "execveat", 0); 367 fail += check_execveat_pathmax(root_dfd, "execveat", 0);
357 fail += check_execveat_pathmax(dot_dfd, "script", 1); 368 fail += check_execveat_pathmax(root_dfd, "script", 1);
358 return fail; 369 return fail;
359} 370}
360 371