tools/testing/selftests/exec/execveat.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/exec/execveat.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/exec/execveat.c
Extension
.c
Size
15943 bytes
Lines
521
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!cwd) {
			ksft_perror("Failed to getcwd()");
			return 2;
		}
		strcpy(longpath, cwd);
		strcat(longpath, "/");
		memset(longname, 'x', XX_DIR_LEN - 1);
		longname[XX_DIR_LEN - 1] = '/';
		longname[XX_DIR_LEN] = '\0';
		count = (PATH_MAX - 3 - strlen(cwd)) / XX_DIR_LEN;
		for (ii = 0; ii < count; ii++) {
			strcat(longpath, longname);
			mkdir(longpath, 0755);
		}
		len = (PATH_MAX - 3 - strlen(cwd)) - (count * XX_DIR_LEN);
		if (len <= 0)
			len = 1;
		memset(longname, 'y', len);
		longname[len] = '\0';
		strcat(longpath, longname);
		free(cwd);
	}
	exe_cp(src, longpath);

	/*
	 * Execute as a pre-opened file descriptor, which works whether this is
	 * a script or not (because the interpreter sees a filename like
	 * "/dev/fd/20").
	 */
	fd = open(longpath, O_RDONLY);
	if (fd > 0) {
		ksft_print_msg("Invoke copy of '%s' via filename of length %zu:\n",
			       src, strlen(longpath));
		fail += check_execveat(fd, "", AT_EMPTY_PATH);
	} else {
		ksft_print_msg("Failed to open length %zu filename, errno=%d (%s)\n",
			       strlen(longpath), errno, strerror(errno));
		fail++;
	}

	/*
	 * Execute as a long pathname relative to "/".  If this is a script,
	 * the interpreter will launch but fail to open the script because its
	 * name ("/dev/fd/5/xxx....") is bigger than PATH_MAX.
	 *
	 * The failure code is usually 127 (POSIX: "If a command is not found,
	 * the exit status shall be 127."), but some systems give 126 (POSIX:
	 * "If the command name is found, but it is not an executable utility,
	 * the exit status shall be 126."), so allow either.
	 */
	if (is_script) {
		ksft_print_msg("Invoke script via root_dfd and relative filename\n");
		fail += check_execveat_invoked_rc(root_dfd, longpath + 1, 0,
						  127, 126);
	} else {
		ksft_print_msg("Invoke exec via root_dfd and relative filename\n");
		fail += check_execveat(root_dfd, longpath + 1, 0);
	}

	return fail;
}

static int check_execveat_comm(int fd, char *argv0, char *expected)
{
	char buf[128], *old_env, *old_argv0;
	int ret;

	snprintf(buf, sizeof(buf), CHECK_COMM "=%s", expected);

	old_env = envp[1];
	envp[1] = buf;

	old_argv0 = argv[0];
	argv[0] = argv0;

	ksft_print_msg("Check execveat(AT_EMPTY_PATH)'s comm is %s\n",
		       expected);
	ret = check_execveat_invoked_rc(fd, "", AT_EMPTY_PATH, 0, 0);

	envp[1] = old_env;
	argv[0] = old_argv0;

	return ret;
}

static int run_tests(void)
{
	int fail = 0;
	char *fullname = realpath("execveat", NULL);
	char *fullname_script = realpath("script", NULL);

Annotation

Implementation Notes