• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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