1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Copyright (c) 2018 FUJITSU LIMITED. All rights reserved.
3 * Authors: Jinhui huang <huangjh.jy@cn.fujitsu.com>
4 * Xiao Yang <yangx.jy@cn.fujitsu.com>
5 */
6 /* Test Description:
7 * This case checks the basic functionality of the execveat(2):
8 * 1) When pathname is relative, it is relative to the directory where
9 * the executed process is located and the dirfd is the descriptor of
10 * the directory.
11 * 2) When pathname is relative and dirfd is the special value AT_FDCWD,
12 * the pathname is the relative to the current working directory of
13 * the calling process.
14 * 3) When pathname is absolute, dirfd can be ignored.
15 * 4) When pathname is an empty string and the flag AT_EMPTY_PATH is
16 * specified, dirfd specifies the file to be executed.
17 */
18
19 #define _GNU_SOURCE
20 #include "config.h"
21
22 #include <stdio.h>
23 #include <errno.h>
24
25 #include "tst_test.h"
26 #include "lapi/execveat.h"
27 #include "lapi/fcntl.h"
28 #include "execveat.h"
29
30 #define TESTDIR "testdir"
31 #define TEST_APP "execveat_child"
32 #define TEST_REL_APP TESTDIR"/"TEST_APP
33
34 static int fd1, fd4;
35 static int fd2 = AT_FDCWD, fd3 = -1;
36 static char app_abs_path[512];
37
38 static struct tcase {
39 int *fd;
40 char *pathname;
41 int flag;
42 } tcases[] = {
43 {&fd1, TEST_APP, 0},
44 {&fd2, TEST_REL_APP, 0},
45 {&fd3, app_abs_path, 0},
46 {&fd4, "", AT_EMPTY_PATH},
47 };
48
verify_execveat(unsigned int i)49 static void verify_execveat(unsigned int i)
50 {
51 struct tcase *tc = &tcases[i];
52 char *argv[2] = {TEST_APP, NULL};
53 pid_t pid;
54
55 pid = SAFE_FORK();
56 if (pid == 0) {
57 TEST(execveat(*tc->fd, tc->pathname, argv, environ, tc->flag));
58 tst_res(TFAIL | TERRNO, "execveat() returns unexpected errno");
59 }
60 }
61
setup(void)62 static void setup(void)
63 {
64 char cur_dir_path[512];
65
66 check_execveat();
67
68 SAFE_MKDIR(TESTDIR, 0777);
69 SAFE_CP(TEST_APP, TEST_REL_APP);
70
71 SAFE_GETCWD(cur_dir_path, sizeof(cur_dir_path));
72 sprintf(app_abs_path, "%s/%s", cur_dir_path, TEST_REL_APP);
73
74 fd1 = SAFE_OPEN(TESTDIR, O_DIRECTORY);
75 fd4 = SAFE_OPEN(TEST_REL_APP, O_PATH);
76 }
77
cleanup(void)78 static void cleanup(void)
79 {
80 if (fd1 > 0)
81 SAFE_CLOSE(fd1);
82
83 if (fd4 > 0)
84 SAFE_CLOSE(fd4);
85 }
86
87 static const char *const resource_files[] = {
88 TEST_APP,
89 NULL,
90 };
91
92 static struct tst_test test = {
93 .resource_files = resource_files,
94 .tcnt = ARRAY_SIZE(tcases),
95 .test = verify_execveat,
96 .child_needs_reinit = 1,
97 .forks_child = 1,
98 .cleanup = cleanup,
99 .setup = setup,
100 };
101