exec selftests: test ->recursion_depth
Test that trivially recursing script onto itself doesn't work. Note: this is different test from ELOOP tests in execveat.c Those test that execveat(2) doesn't follow symlinks when told to do so. Link: http://lkml.kernel.org/r/20190423192720.GA21433@avx2 Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Cc: Shuah Khan <shuah@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
a6231d1993
Коммит
4e7301e6df
|
@ -6,4 +6,5 @@ execveat.moved
|
|||
execveat.path.ephemeral
|
||||
execveat.ephemeral
|
||||
execveat.denatured
|
||||
xxxxxxxx*
|
||||
/recursion-depth
|
||||
xxxxxxxx*
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
CFLAGS = -Wall
|
||||
CFLAGS += -Wno-nonnull
|
||||
CFLAGS += -D_GNU_SOURCE
|
||||
|
||||
TEST_GEN_PROGS := execveat
|
||||
TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir
|
||||
# Makefile is a run-time dependency, since it's accessed by the execveat test
|
||||
TEST_FILES := Makefile
|
||||
|
||||
TEST_GEN_PROGS += recursion-depth
|
||||
|
||||
EXTRA_CLEAN := $(OUTPUT)/subdir.moved $(OUTPUT)/execveat.moved $(OUTPUT)/xxxxx*
|
||||
|
||||
include ../lib.mk
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Alexey Dobriyan <adobriyan@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
/* Test that pointing #! script interpreter to self doesn't recurse. */
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mount.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (unshare(CLONE_NEWNS) == -1) {
|
||||
if (errno == ENOSYS || errno == EPERM) {
|
||||
fprintf(stderr, "error: unshare, errno %d\n", errno);
|
||||
return 4;
|
||||
}
|
||||
fprintf(stderr, "error: unshare, errno %d\n", errno);
|
||||
return 1;
|
||||
}
|
||||
if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) == -1) {
|
||||
fprintf(stderr, "error: mount '/', errno %d\n", errno);
|
||||
return 1;
|
||||
}
|
||||
/* Require "exec" filesystem. */
|
||||
if (mount(NULL, "/tmp", "ramfs", 0, NULL) == -1) {
|
||||
fprintf(stderr, "error: mount ramfs, errno %d\n", errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define FILENAME "/tmp/1"
|
||||
|
||||
int fd = creat(FILENAME, 0700);
|
||||
if (fd == -1) {
|
||||
fprintf(stderr, "error: creat, errno %d\n", errno);
|
||||
return 1;
|
||||
}
|
||||
#define S "#!" FILENAME "\n"
|
||||
if (write(fd, S, strlen(S)) != strlen(S)) {
|
||||
fprintf(stderr, "error: write, errno %d\n", errno);
|
||||
return 1;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
int rv = execve(FILENAME, NULL, NULL);
|
||||
if (rv == -1 && errno == ELOOP) {
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr, "error: execve, rv %d, errno %d\n", rv, errno);
|
||||
return 1;
|
||||
}
|
Загрузка…
Ссылка в новой задаче