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 */
5
6 /* Test Description:
7 * Check various errnos for execveat(2):
8 * 1) execveat() fails and returns EBADF if dirfd is a invalid file
9 * descriptor.
10 * 2) execveat() fails and returns EINVAL if flag specified is invalid.
11 * 3) execveat() fails and returns ELOOP if the file identified by dirfd and
12 * pathname is a symbolic link and flag includes AT_SYMLINK_NOFOLLOW.
13 * 4) execveat() fails and returns ENOTDIR if pathname is relative and dirfd
14 * is a file descriptor referring to a file other than a directory.
15 */
16
17 #define _GNU_SOURCE
18 #include "config.h"
19
20 #include <stdio.h>
21 #include <errno.h>
22
23 #include "tst_test.h"
24 #include "lapi/execveat.h"
25 #include "lapi/fcntl.h"
26 #include "execveat.h"
27
28 #define TESTDIR "testdir"
29 #define TEST_APP "execveat_errno"
30 #define TEST_SYMLINK "execveat_symlink"
31 #define TEST_REL_APP TESTDIR"/"TEST_APP
32 #define TEST_ERL_SYMLINK TESTDIR"/"TEST_SYMLINK
33
34 static int bad_fd = -1, fd;
35 static char app_abs_path[512], app_sym_path[512];
36
37 static struct tcase {
38 int *fd;
39 char *pathname;
40 int flag;
41 int exp_err;
42 } tcases[] = {
43 {&bad_fd, "", AT_EMPTY_PATH, EBADF},
44 {&fd, app_abs_path, -1, EINVAL},
45 {&fd, app_sym_path, AT_SYMLINK_NOFOLLOW, ELOOP},
46 {&fd, TEST_REL_APP, 0, ENOTDIR},
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 if (tc->exp_err != TST_ERR) {
59 tst_res(TFAIL | TTERRNO,
60 "execveat() fails unexpectedly, expected: %s",
61 tst_strerrno(tc->exp_err));
62 } else {
63 tst_res(TPASS | TTERRNO,
64 "execveat() fails as expected");
65 }
66 }
67 }
68
setup(void)69 static void setup(void)
70 {
71 char cur_dir_path[512];
72
73 check_execveat();
74
75 SAFE_MKDIR(TESTDIR, 0777);
76
77 SAFE_CP(TEST_APP, TEST_REL_APP);
78
79 SAFE_GETCWD(cur_dir_path, sizeof(cur_dir_path));
80 sprintf(app_abs_path, "%s/%s", cur_dir_path, TEST_REL_APP);
81 sprintf(app_sym_path, "%s/%s", cur_dir_path, TEST_ERL_SYMLINK);
82
83 SAFE_SYMLINK(TEST_REL_APP, TEST_ERL_SYMLINK);
84
85 fd = SAFE_OPEN(TEST_REL_APP, O_PATH);
86 }
87
88 static const char *const resource_files[] = {
89 TEST_APP,
90 NULL,
91 };
92
cleanup(void)93 static void cleanup(void)
94 {
95 if (fd > 0)
96 SAFE_CLOSE(fd);
97 }
98
99 static struct tst_test test = {
100 .resource_files = resource_files,
101 .tcnt = ARRAY_SIZE(tcases),
102 .test = verify_execveat,
103 .child_needs_reinit = 1,
104 .forks_child = 1,
105 .cleanup = cleanup,
106 .setup = setup,
107 };
108