Skip to contentSkip to conversation

syscalls/execveat01: new test to verify execveat unlinked fd

PATCH Superseded Eddie.Horng 3 participants 6 messages Jul 27, 2018 – Jul 31, 2018 Library code

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 syscalls/execveat01: new test to verify execveat unlinked fd

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.

---
 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    | 142
+++++++++++++++++++++
 .../kernel/syscalls/execveat/execveat_child.c      |  32 +++++
 11 files changed, 271 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
configure.ac +1 -0
index 9208f1c6c..373d72689 100644
@@ -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
include/lapi/syscalls/arm.in +1 -0
index 71a4b713d..c44adcd7e 100644
@@ -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)
(quoted diff) +0 -0

b/include/lapi/syscalls/i386.in
index 0f9601472..19f0148fe 100644

include/lapi/syscalls/i386.in +1 -0
@@ -340,4 +340,5 @@ sched_getattr 352
 renameat2 354
 getrandom 355
 memfd_create 356
+execveat 358
 copy_file_range 377
(quoted diff) +0 -0

b/include/lapi/syscalls/s390.in
index 98c861f36..d95b282f8 100644

include/lapi/syscalls/s390.in +1 -0
@@ -331,4 +331,5 @@ sched_getattr 346
 renameat2 347
 getrandom 349
 memfd_create 350
+execveat 354
 copy_file_range 375
(quoted diff) +0 -0

b/include/lapi/syscalls/x86_64.in
index 89db79404..7907c3108 100644

include/lapi/syscalls/x86_64.in +1 -0
@@ -307,4 +307,5 @@ sched_getattr 315
 renameat2 316
 getrandom 318
 memfd_create 319
+execveat 322
 copy_file_range 326
m4/ltp-execveat.m4 new file +4 -0
new file mode 100644
index 000000000..8cb614715
@@ -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,,)
+])

(quoted diff) +0 -0

b/testcases/kernel/syscalls/execveat/.gitignore
new file mode 100644
index 000000000..c0d418603

testcases/kernel/syscalls/execveat/.gitignore new file +2 -0
@@ -0,0 +1,2 @@
+/execveat01
+/execveat_child
(quoted diff) +0 -0

b/testcases/kernel/syscalls/execveat/Makefile
new file mode 100644
index 000000000..0bab6dc83

testcases/kernel/syscalls/execveat/Makefile new file +4 -0
@@ -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

(quoted diff) +0 -0

b/testcases/kernel/syscalls/execveat/execveat.h
new file mode 100644
index 000000000..e87974d9c

testcases/kernel/syscalls/execveat/execveat.h new file +4 -0
@@ -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 <sys/types.h>
+#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 */
\ No newline at end of file

(quoted diff) +0 -0

b/testcases/kernel/syscalls/execveat/execveat01.c
new file mode 100644
index 000000000..fec675fad

testcases/kernel/syscalls/execveat/execveat01.c new file +4 -0
@@ -0,0 +1,142 @@
+/*
+ * 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 <[email protected]>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <sys/mount.h>
+#include <fcntl.h>
+#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 path[PATH_MAX];
+ char *argv[2] = {TEST_APP, NULL};
+ int fd;
+
+ if (tst_get_path(TEST_APP, path, sizeof(path))) {
+ tst_brk(TBROK | TERRNO,
+ "Couldn't found "TEST_APP" binary in $PATH");
+ }
+ SAFE_CP(path, TEST_FILE_PATH);
+
+ fd = SAFE_OPEN(TEST_FILE_PATH, O_PATH);
+ SAFE_UNLINK(TEST_FILE_PATH);
+
+ argv[0] = TEST_FILE_PATH;
+ TEST(execveat(fd, "", argv, NULL, AT_EMPTY_PATH));
+ if (TEST_ERRNO == ENOSYS) {
+ tst_brk(TCONF,
+ "execveat is not supported in this kernel.");
+ }
+ else if (TEST_RETURN) {
+ tst_res(TFAIL | TERRNO,
+ "execveat() returned unexpected errno");
+ close(fd);
+ exit(1);
+ }
+}
+
+static void verify_execveat(void)
+{
+ pid_t pid;
+ int status;
+
+ pid = SAFE_FORK();
+ if (pid == 0) {
+ do_child();
+ }
+ else {
+ SAFE_WAITPID(pid, &status, 0);
+ if (status == 0)
+ tst_res(TPASS, "execveat() can run an unlinked executable");
+ }
+}
+
+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.");
+ } else {
+ tst_brk(TBROK | TERRNO,
+ "overlayfs mount failed");
+ }
+ }
+ ovl_mounted = 1;
+}
+
+static void cleanup(void)
+{
+ if (ovl_mounted)
+ SAFE_UMOUNT(OVL_MNT);
+}
+
+static struct tst_test test = {
+ .needs_root = 1,
+ .needs_tmpdir = 1,
+ .forks_child = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = verify_execveat,
+};
+

(quoted diff) +0 -0

b/testcases/kernel/syscalls/execveat/execveat_child.c new file mode 100644
index 000000000..b2611dc9b

testcases/kernel/syscalls/execveat/execveat_child.c new file +5 -0
@@ -0,0 +1,32 @@
+/*
+ *
+ *   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 Street, Fifth Floor, Boston, MA

02110-1301 USA
+ */
+
+/*
+ * execveat_child.c
+ * dummy program which is used by execveat01.c testcase
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(void)
+{
+ printf("Hello World\n");
+ exit(0);
+}

Signature · 1 line
2.12.5
#1 lore raw

PATCH 1/1 syscalls/execveat01: new test to verify execveat unlinked fd

Hi!

Quoted 20 lines
testcases/kernel/syscalls/execveat/.gitignore new file +2 -0
new file mode 100644
index 000000000..c0d418603
@@ -0,0 +1,2 @@
+/execveat01
+/execveat_child
testcases/kernel/syscalls/execveat/Makefile new file +4 -0
new file mode 100644
index 000000000..0bab6dc83
@@ -0,0 +1,23 @@
+#
+#  Copyright (C) 2018 MediaTek Inc.  All Rights Reserved.
+#
+#  This program is free software;  you can redistribute it and/or
Quoted 1 line

modify

First of all it looks like evolution line wrapped the patch, you should turn off that for attachements.

See:

https://www.kernel.org/doc/html/v4.10/process/email-clients.html

Quoted 151 lines
testcases/kernel/syscalls/execveat/Makefile new file +12 -0
+#  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

testcases/kernel/syscalls/execveat/Makefile new file +7 -0
+#
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/execveat/execveat.h new file +4 -0
new file mode 100644
index 000000000..e87974d9c
@@ -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.
+ *
+ */

testcases/kernel/syscalls/execveat/execveat.h new file +19 -0
+
+#ifndef EXECVEAT_H
+#define EXECVEAT_H
+
+#include <sys/types.h>
+#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 */
\ No newline at end of file
testcases/kernel/syscalls/execveat/execveat01.c new file +4 -0
new file mode 100644
index 000000000..fec675fad
@@ -0,0 +1,142 @@
+/*
+ * 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 <[email protected]>
+ *
+ * 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.
+ *
+ */

testcases/kernel/syscalls/execveat/execveat01.c new file +24 -0
+
+#define _GNU_SOURCE
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <sys/mount.h>
+#include <fcntl.h>
+#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)
+{

testcases/kernel/syscalls/execveat/execveat01.c

Quoted 10 lines
testcases/kernel/syscalls/execveat/execveat01.c new file +10 -0
+	
+	char path[PATH_MAX];
+	char *argv[2] = {TEST_APP, NULL};
+	int fd;
+
+	if (tst_get_path(TEST_APP, path, sizeof(path))) {
+		tst_brk(TBROK | TERRNO, 
+		         "Couldn't found "TEST_APP" binary in $PATH");
+	}
+	SAFE_CP(path, TEST_FILE_PATH);

We do have a better API for this, have a look at creat07.c

testcases/kernel/syscalls/execveat/execveat01.c

Quoted 9 lines
testcases/kernel/syscalls/execveat/execveat01.c new file +9 -0
+	fd = SAFE_OPEN(TEST_FILE_PATH, O_PATH);
+	SAFE_UNLINK(TEST_FILE_PATH);
+
+	argv[0] = TEST_FILE_PATH;
+	TEST(execveat(fd, "", argv, NULL, AT_EMPTY_PATH));
+	if (TEST_ERRNO == ENOSYS) {
+		tst_brk(TCONF,
+			"execveat is not supported in this kernel.");
+	}

I suppose that we should handle EINVAL here, I think that we will get EINVAL rather than ENOSYS when kernel will not recognize __NR_execveat

testcases/kernel/syscalls/execveat/execveat01.c

Quoted 5 lines
testcases/kernel/syscalls/execveat/execveat01.c new file +5 -0
+	else if (TEST_RETURN) {
+		tst_res(TFAIL | TERRNO, 
+			    "execveat() returned unexpected errno");
+		close(fd);	
+		exit(1);

No need for the else branch here, since tst_brk() exits the test execution.

Also there is no need to propagate the result with the exit value, the tst_res() already did that for you.

testcases/kernel/syscalls/execveat/execveat01.c

Quoted 2 lines
testcases/kernel/syscalls/execveat/execveat01.c new file +2 -0
+	}
+}

There are several trailing whitespaces and style violations here, you can check for these with checkpatch.pl that is part of the linux kernel source tree.

Quoted 25 lines
testcases/kernel/syscalls/execveat/execveat01.c new file +25 -0
+static void verify_execveat(void)
+{
+	pid_t pid;
+	int status;
+
+	pid = SAFE_FORK();
+	if (pid == 0) {
+		do_child();	
+	}
+	else {
+		SAFE_WAITPID(pid, &status, 0);
+		if (status == 0)
+			tst_res(TPASS, "execveat() can run an unlinked executable");
+	}
+}
+
+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);

testcases/kernel/syscalls/execveat/execveat01.c

Quoted 10 lines
testcases/kernel/syscalls/execveat/execveat01.c new file +10 -0
+	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.");
+		} else {
+			tst_brk(TBROK | TERRNO,
+				"overlayfs mount failed");
+		}

here as well no need for the else branch after the tst_brk();

Quoted 50 lines
testcases/kernel/syscalls/execveat/execveat01.c new file +19 -0
+	}
+	ovl_mounted = 1;
+}
+
+static void cleanup(void)
+{
+	if (ovl_mounted)
+		SAFE_UMOUNT(OVL_MNT);
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.needs_tmpdir = 1,
+	.forks_child = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_execveat,
+};
+
testcases/kernel/syscalls/execveat/execveat_child.c new file +5 -0
new file mode 100644
index 000000000..b2611dc9b
@@ -0,0 +1,32 @@
+/*
+ *
+ *   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 Street, Fifth Floor, Boston, MA

02110-1301 USA
+ */

testcases/kernel/syscalls/execveat/execveat_child.c new file +3 -0
+
+/*
+ * execveat_child.c

testcases/kernel/syscalls/execveat/execveat_child.c

Quoted 10 lines
testcases/kernel/syscalls/execveat/execveat_child.c new file +10 -0
+ *	dummy program which is used by execveat01.c testcase
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(void)
+{
+	printf("Hello World\n");
+	exit(0);

You can print the TPASS message from here and the result will be propagated to the parent program. You just need to call tst_reinit() that will initialize the test library. See creat07_child.c.

Quoted 8 lines

+}

Signature · 6 lines
2.12.5



-- 
Mailing list info: https://lists.linux.it/listinfo/ltp
Signature · 2 lines
Cyril Hrubis
[email protected]
#2 lore raw

PATCH 1/1 syscalls/execveat01: new test to verify execveat unlinked fd

2018-07-27 17:47 GMT+08:00 Cyril Hrubis <[email protected]>:

Quoted 1 line

Hi!

Hi Cyril,
Thanks your detail review and suggestions, I have couples of questions as below:

Quoted 6 lines
Quoted 6 lines
(quoted diff) +6 -0
+static void do_child(void)
+{
+
+     char path[PATH_MAX];
+     char *argv[2] = {TEST_APP, NULL};
+     int fd;
Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+
+     if (tst_get_path(TEST_APP, path, sizeof(path))) {
+             tst_brk(TBROK | TERRNO,
+                      "Couldn't found "TEST_APP" binary in $PATH");
+     }
+     SAFE_CP(path, TEST_FILE_PATH);

We do have a better API for this, have a look at creat07.c

Could you have more detail guide on this? ie. copy TEST_APP to ovl mount path.

Quoted 10 lines

Review

Quoted 9 lines
(quoted diff) +9 -0
+     fd = SAFE_OPEN(TEST_FILE_PATH, O_PATH);
+     SAFE_UNLINK(TEST_FILE_PATH);
+
+     argv[0] = TEST_FILE_PATH;
+     TEST(execveat(fd, "", argv, NULL, AT_EMPTY_PATH));
+     if (TEST_ERRNO == ENOSYS) {
+             tst_brk(TCONF,
+                     "execveat is not supported in this kernel.");
+     }
Quoted 2 lines

I suppose that we should handle EINVAL here, I think that we will get EINVAL rather than ENOSYS when kernel will not recognize __NR_execveat

EINVAL is happened to be the same return code of this testcase is expecting -- the regression introduced from 8db6c34f1dbc ("Introduce v3 namespaced file capabilities"), therefore I might need another way to test whether kernel recognize __NR_execveat, so that I can differentiate not recognize and the regression. Do you have suggestion on this?

Quoted 8 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+int main(void)
+{
+     printf("Hello World\n");
+     exit(0);

You can print the TPASS message from here and the result will be propagated to the parent program. You just need to call tst_reinit() that will initialize the test library. See creat07_child.c.

I change execveat_child.c as below and get errors as:
tst_test.c:144: BROK: LTP_IPC_PATH is not defined tst_test.c:869: BROK: Test haven't reported results!

I think the cause is execveat() doesn't pass environment variables to its child, but SAFE_EXECL in creat07.c does.
Do you suggest pass LTP_IPC_PATH in execveat() to make tst_reinit() in execveat_child run properly, or something else?

#define TST_NO_DEFAULT_MAIN
#include "tst_test.h"

int main()
{
tst_reinit();
tst_res(TPASS, "execveat_child is lunched as expcted"); return 0;
}

thanks,
Eddie

#3 lore raw

PATCH 1/1 syscalls/execveat01: new test to verify execveat unlinked fd

Hi!

Quoted 15 lines
Quoted 6 lines
Quoted 6 lines
(quoted diff) +6 -0
+static void do_child(void)
+{
+
+     char path[PATH_MAX];
+     char *argv[2] = {TEST_APP, NULL};
+     int fd;
Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+
+     if (tst_get_path(TEST_APP, path, sizeof(path))) {
+             tst_brk(TBROK | TERRNO,
+                      "Couldn't found "TEST_APP" binary in $PATH");
+     }
+     SAFE_CP(path, TEST_FILE_PATH);

We do have a better API for this, have a look at creat07.c

Quoted 2 lines

Could you have more detail guide on this? ie. copy TEST_APP to ovl mount path

If you specify the child executable as a resource file as in:

https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#2222-datafiles

It will be compied to the test temporary directory before the test is executed, then you can SAFE_CP() the file when you need it.

Alternatively I can also change the resource file mechanims in the test library so that we can pass destionation there as well or export the TST_RESOURCE_COPY() macro to the new library. Then you can use it to copy the file into its final destination.

Quoted 10 lines
Quoted 10 lines
Quoted 9 lines
(quoted diff) +9 -0
+     fd = SAFE_OPEN(TEST_FILE_PATH, O_PATH);
+     SAFE_UNLINK(TEST_FILE_PATH);
+
+     argv[0] = TEST_FILE_PATH;
+     TEST(execveat(fd, "", argv, NULL, AT_EMPTY_PATH));
+     if (TEST_ERRNO == ENOSYS) {
+             tst_brk(TCONF,
+                     "execveat is not supported in this kernel.");
+     }
Quoted 8 lines
Quoted 2 lines

I suppose that we should handle EINVAL here, I think that we will get EINVAL rather than ENOSYS when kernel will not recognize __NR_execveat

EINVAL is happened to be the same return code of this testcase is expecting -- the regression introduced from 8db6c34f1dbc ("Introduce v3 namespaced file capabilities"), therefore I might need another way to test whether kernel recognize __NR_execveat, so that I can differentiate not recognize and the regression. Do you have suggestion on this?

We usually specify minimal kernel version for the testcase in the tst_test structure in that case and the test is skipped automatically on old kernels that do not have the execveat() syscall implemented.

Quoted 9 lines
Quoted 8 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+int main(void)
+{
+     printf("Hello World\n");
+     exit(0);

You can print the TPASS message from here and the result will be propagated to the parent program. You just need to call tst_reinit() that will initialize the test library. See creat07_child.c.

Quoted 8 lines

I change execveat_child.c as below and get errors as:
tst_test.c:144: BROK: LTP_IPC_PATH is not defined tst_test.c:869: BROK: Test haven't reported results!

I think the cause is execveat() doesn't pass environment variables to its child, but SAFE_EXECL in creat07.c does.
Do you suggest pass LTP_IPC_PATH in execveat() to make tst_reinit() in execveat_child run properly, or something else?

Yes, the LTP_IPC_PATH has to be passed manually in this case so that the library could be re-initialized.

Quoted 12 lines

#define TST_NO_DEFAULT_MAIN
#include "tst_test.h"

int main()
{
tst_reinit();
tst_res(TPASS, "execveat_child is lunched as expcted"); return 0;
}

thanks,
Eddie

Signature · 2 lines
Cyril Hrubis
[email protected]
#4 lore raw

PATCH 1/1 syscalls/execveat01: new test to verify execveat unlinked fd

In reply to Cyril Hrubis

2018-07-27 17:47 GMT+08:00 Cyril Hrubis <[email protected]>:

Quoted 9 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+int main(void)
+{
+     printf("Hello World\n");
+     exit(0);

You can print the TPASS message from here and the result will be propagated to the parent program. You just need to call tst_reinit() that will initialize the test library. See creat07_child.c.

Hi Cyril,
I removed "if (status == 0) tst_res(TPASS, ..." from execveat01.c and add "tst_res(TPASS, ..." in execveat_child.c, but I got a no reported result error:

execveat_child.c:44: PASS: execveat_child run as expected tst_test.c:869: BROK: Test haven't reported results!

It seems child's test result doesn't propagated to parent. Do I use wrong API in child or miss something in parent?

thanks,
Eddie

#5 lore raw

PATCH 1/1 syscalls/execveat01: new test to verify execveat unlinked fd

Hi!

Quoted 9 lines

I removed "if (status == 0) tst_res(TPASS, ..." from execveat01.c and add "tst_res(TPASS, ..." in execveat_child.c, but I got a no reported result error:

execveat_child.c:44: PASS: execveat_child run as expected tst_test.c:869: BROK: Test haven't reported results!

It seems child's test result doesn't propagated to parent. Do I use wrong API in child or miss something in parent?

You are right, this is supposed to work but nobody checked that and while the IPC is mapped the results pointer is not initialized in the test library.

It should work with following patch:

lib/tst_test.c +1 -0
index 008bcefe0..bb3908d6c 100644
@@ -152,6 +152,7 @@ void tst_reinit(void)
        fd = SAFE_OPEN(path, O_RDWR);
 
        ptr = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+       results = ptr;
        tst_futexes = (char*)ptr + sizeof(struct results);
        tst_max_futexes = (size - sizeof(struct results))/sizeof(futex_t);
 
Signature · 2 lines
Cyril Hrubis
[email protected]