From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eddie.Horng Date: Wed, 1 Aug 2018 16:17:54 +0800 Subject: [LTP] [PATCH v2] syscalls/execveat01: new test to verify execveat unlinked fd Message-ID: <1533111474.1176.4.camel@mtkswgap22> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: ltp@lists.linux.it Exercise the execveat() syscall to verify an executable is opened then unlinked can be executed. The regression is introduced from 8db6c34f1dbc ("Introduce v3 namespaced file capabilities"). Overlayfs and possibly other networking filesystems unhash the dentry on unlink, fail on this test with above change. Signed-off-by: Eddie Horng --- Changes in v2: - use resource file for TEST_APP - pass environ to execveat() - specific min kernel version 3.19.0 to make sure execveat is supported - add needs_ipc_path = 1 - execveat_child print TPASS to propagate result to parent --- configure.ac | 1 + include/lapi/syscalls/arm.in | 1 + include/lapi/syscalls/i386.in | 1 + include/lapi/syscalls/s390.in | 1 + include/lapi/syscalls/x86_64.in | 1 + m4/ltp-execveat.m4 | 25 ++++ testcases/kernel/syscalls/execveat/.gitignore | 2 + testcases/kernel/syscalls/execveat/Makefile | 23 ++++ testcases/kernel/syscalls/execveat/execveat.h | 42 +++++++ testcases/kernel/syscalls/execveat/execveat01.c | 128 +++++++++++++++++++++ .../kernel/syscalls/execveat/execveat_child.c | 41 +++++++ 11 files changed, 266 insertions(+) create mode 100644 m4/ltp-execveat.m4 create mode 100644 testcases/kernel/syscalls/execveat/.gitignore create mode 100644 testcases/kernel/syscalls/execveat/Makefile create mode 100644 testcases/kernel/syscalls/execveat/execveat.h create mode 100644 testcases/kernel/syscalls/execveat/execveat01.c create mode 100644 testcases/kernel/syscalls/execveat/execveat_child.c diff --git a/configure.ac b/configure.ac index 9208f1c6c..373d72689 100644 --- a/configure.ac +++ b/configure.ac @@ -196,6 +196,7 @@ LTP_CHECK_FSTATAT LTP_CHECK_MKNODAT LTP_CHECK_READLINKAT LTP_CHECK_OPENAT +LTP_CHECK_EXECVEAT LTP_CHECK_RENAMEAT LTP_CHECK_RENAMEAT2 LTP_CHECK_FALLOCATE diff --git a/include/lapi/syscalls/arm.in b/include/lapi/syscalls/arm.in index 71a4b713d..c44adcd7e 100644 --- a/include/lapi/syscalls/arm.in +++ b/include/lapi/syscalls/arm.in @@ -340,4 +340,5 @@ sched_getattr (__NR_SYSCALL_BASE+381) renameat2 (__NR_SYSCALL_BASE+382) getrandom (__NR_SYSCALL_BASE+384) memfd_create (__NR_SYSCALL_BASE+385) +execveat (__NR_SYSCALL_BASE+387) copy_file_range (__NR_SYSCALL_BASE+391) diff --git a/include/lapi/syscalls/i386.in b/include/lapi/syscalls/i386.in index 0f9601472..19f0148fe 100644 --- a/include/lapi/syscalls/i386.in +++ b/include/lapi/syscalls/i386.in @@ -340,4 +340,5 @@ sched_getattr 352 renameat2 354 getrandom 355 memfd_create 356 +execveat 358 copy_file_range 377 diff --git a/include/lapi/syscalls/s390.in b/include/lapi/syscalls/s390.in index 98c861f36..d95b282f8 100644 --- a/include/lapi/syscalls/s390.in +++ b/include/lapi/syscalls/s390.in @@ -331,4 +331,5 @@ sched_getattr 346 renameat2 347 getrandom 349 memfd_create 350 +execveat 354 copy_file_range 375 diff --git a/include/lapi/syscalls/x86_64.in b/include/lapi/syscalls/x86_64.in index 89db79404..7907c3108 100644 --- a/include/lapi/syscalls/x86_64.in +++ b/include/lapi/syscalls/x86_64.in @@ -307,4 +307,5 @@ sched_getattr 315 renameat2 316 getrandom 318 memfd_create 319 +execveat 322 copy_file_range 326 diff --git a/m4/ltp-execveat.m4 b/m4/ltp-execveat.m4 new file mode 100644 index 000000000..8cb614715 --- /dev/null +++ b/m4/ltp-execveat.m4 @@ -0,0 +1,25 @@ +dnl +dnl Copyright (c) Linux Test Project, 2014 +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +dnl the GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +dnl + +dnl +dnl LTP_CHECK_EXECVEAT +dnl ---------------------------- +dnl +AC_DEFUN([LTP_CHECK_EXECVEAT],[ +AC_CHECK_FUNCS(execveat,,) +]) diff --git a/testcases/kernel/syscalls/execveat/.gitignore b/testcases/kernel/syscalls/execveat/.gitignore new file mode 100644 index 000000000..c0d418603 --- /dev/null +++ b/testcases/kernel/syscalls/execveat/.gitignore @@ -0,0 +1,2 @@ +/execveat01 +/execveat_child diff --git a/testcases/kernel/syscalls/execveat/Makefile b/testcases/kernel/syscalls/execveat/Makefile new file mode 100644 index 000000000..0bab6dc83 --- /dev/null +++ b/testcases/kernel/syscalls/execveat/Makefile @@ -0,0 +1,23 @@ +# +# Copyright (C) 2018 MediaTek Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +# the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +top_srcdir ?= ../../../.. + +include $(top_srcdir)/include/mk/testcases.mk + +include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/execveat/execveat.h b/testcases/kernel/syscalls/execveat/execveat.h new file mode 100644 index 000000000..53c8be8a5 --- /dev/null +++ b/testcases/kernel/syscalls/execveat/execveat.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 or any later of the GNU General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef EXECVEAT_H +#define EXECVEAT_H + +#include +#include "config.h" +#include "lapi/syscalls.h" + +#if !defined(HAVE_EXECVEAT) +int execveat(int dirfd, const char *pathname, + char *const argv[], char *const envp[], + int flags) +{ + return tst_syscall(__NR_execveat, dirfd, pathname, argv, envp, flags); +} +#endif + + +#endif /* EXECVEAT_H */ diff --git a/testcases/kernel/syscalls/execveat/execveat01.c b/testcases/kernel/syscalls/execveat/execveat01.c new file mode 100644 index 000000000..768b196d3 --- /dev/null +++ b/testcases/kernel/syscalls/execveat/execveat01.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 or any later of the GNU General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Started by Eddie Horng + * + * DESCRIPTION + * Check if an unlinked executable can run in overlayfs mount. + * The regression is introduced from 8db6c34f1dbc ("Introduce v3 + * namespaced file capabilities"). in security/commoncap.c, + * cap_inode_getsecurity() use d_find_alias() cause unhashed dentry + * can't be found. The solution could use d_find_any_alias() instead of + * d_find_alias(). + * + * From kernel 4.14, this case is expected fails, execveat shell + * return EINVAL. + * + */ + +#define _GNU_SOURCE +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tst_test.h" +#include "execveat.h" + +#define OVL_MNT "ovl" +#define TEST_APP "execveat_child" +#define TEST_FILE_PATH OVL_MNT"/"TEST_APP + +static int ovl_mounted; + +static void do_child(void) +{ + char *argv[2] = {TEST_FILE_PATH, NULL}; + int fd; + + SAFE_CP(TEST_APP, TEST_FILE_PATH); + + fd = SAFE_OPEN(TEST_FILE_PATH, O_PATH); + SAFE_UNLINK(TEST_FILE_PATH); + + TEST(execveat(fd, "", argv, environ, AT_EMPTY_PATH)); + tst_res(TFAIL | TERRNO, "execveat() returned unexpected errno"); +} + +static void verify_execveat(void) +{ + pid_t pid; + + pid = SAFE_FORK(); + if (pid == 0) { + do_child(); + exit(1); + } + SAFE_WAITPID(pid, NULL, 0); +} + +static void setup(void) +{ + int ret; + + /* Setup an overlay mount with lower file */ + SAFE_MKDIR("lower", 0755); + SAFE_MKDIR("upper", 0755); + SAFE_MKDIR("work", 0755); + SAFE_MKDIR(OVL_MNT, 0755); + ret = mount("overlay", OVL_MNT, "overlay", 0, + "lowerdir=lower,upperdir=upper,workdir=work"); + if (ret < 0) { + if (errno == ENODEV) { + tst_brk(TCONF, + "overlayfs is not configured in this kernel."); + } + tst_brk(TBROK | TERRNO, "overlayfs mount failed"); + } + ovl_mounted = 1; +} + +static void cleanup(void) +{ + if (ovl_mounted) + SAFE_UMOUNT(OVL_MNT); +} + +static const char *const resource_files[] = { + TEST_APP, + NULL, +}; + +static struct tst_test test = { + .needs_root = 1, + .needs_tmpdir = 1, + .forks_child = 1, + .needs_ipc_path = 1, + .setup = setup, + .cleanup = cleanup, + .test_all = verify_execveat, + .resource_files = resource_files, + .min_kver = "3.19.0", +}; + diff --git a/testcases/kernel/syscalls/execveat/execveat_child.c b/testcases/kernel/syscalls/execveat/execveat_child.c new file mode 100644 index 000000000..68fcd1325 --- /dev/null +++ b/testcases/kernel/syscalls/execveat/execveat_child.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 or any later of the GNU General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* + * execveat_child.c + * dummy program which is used by execveat01.c testcase + */ + + +#define TST_NO_DEFAULT_MAIN +#include "tst_test.h" + + +int main(void) +{ + tst_reinit(); + tst_res(TPASS, "execveat_child run as expected"); + return 0; +} + -- 2.12.5