All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH] fix fs_perms tests
@ 2010-04-02 18:59 Cyril Hrubis
       [not found] ` <g2x364299f41004021212z6e85833ybccad62e6780ec26@mail.gmail.com>
  0 siblings, 1 reply; 10+ messages in thread
From: Cyril Hrubis @ 2010-04-02 18:59 UTC (permalink / raw)
  To: ltp-list

[-- Attachment #1: Type: text/plain, Size: 1117 bytes --]

Hi!
It looks (at least for me) that fs_perms tests are broken for a long time (as
they are trying to find binaries in working directory instead of LTPROOT).

Attached patch fixes fs_perm.c to look for test binary in
$LTPROOT/testcases/bin/ rather than in ./ and converts silly and broken
fs_perms_simple.sh script into runtest file that is also added into runltp
script.


The way how now fs_perm is copying test file into temporary directory is not
ideall either because the test fails when executed by hand. I could think of
creating file with a such line:

#!/bin/true

Or maybe more robust:

#!/bin/sh
true

But I'm not sure if there is always /bin/true (as it's buildin in most of the
shells) or if I it's good idea to add dependecy for /bin/sh. But this would
avoid compiling dummy C program and copying it from $LTPROOT/testcases/bin/.

Or we could do some trickery to embed the "dummy" binary file into the code as
array.

Any ideas here?


However the problem discussed above fs_perms tests are at least working with
this patch.

Signed-off-by: Cyril Hrubis chrubis@suse.cz

-- 
Cyril Hrubis
chrubis@suse.cz

[-- Attachment #2: fix_fs_perms.patch --]
[-- Type: text/x-patch, Size: 9850 bytes --]

diff --git a/runltp b/runltp
index b848a7f..097e32e 100755
--- a/runltp
+++ b/runltp
@@ -557,6 +557,7 @@ main()
 
         for SCENFILES in ${LTPROOT}/runtest/syscalls                \
                          ${LTPROOT}/runtest/fs                      \
+                         ${LTPROOT}/runtest/fs_perms_simple         \
                          ${LTPROOT}/runtest/fsx                     \
                          ${LTPROOT}/runtest/dio                     \
                          ${LTPROOT}/runtest/io                      \
diff --git a/runtest/fs b/runtest/fs
index 75c5e38..2de871d 100644
--- a/runtest/fs
+++ b/runtest/fs
@@ -64,9 +64,6 @@ writetest01	writetest
 #Also run the fs_di (Data Integrity tests)
 fs_di fs_di -d $TMPDIR
 
-#Also run the fs_perms (File System Permission Tests)
-fs_perms fs_perms_simpletest.sh
-
 # Read every file in /proc. Not likely to crash, but does enough 
 # to disturb the kernel. A good kernel latency killer too.
 # Was not sure why it should reside in runtest/crashme and won´t get tested ever
diff --git a/runtest/fs_perms_simple b/runtest/fs_perms_simple
new file mode 100644
index 0000000..cc986bd
--- /dev/null
+++ b/runtest/fs_perms_simple
@@ -0,0 +1,26 @@
+#
+# These tests are setting file permissions/group/uid and are trying to
+# open/write/execute the file.
+#
+#
+#
+# fs_perms file_mode file_uid file_gid test_uid test_gid mode (r|w|x) expected_result
+#
+fs_perms01 fs_perms 001 99 99 12 100 x 0
+fs_perms02 fs_perms 010 99 99 200 99 x 0
+fs_perms03 fs_perms 100 99 99 99 500 x 0
+fs_perms04 fs_perms 002 99 99 12 100 w 0
+fs_perms05 fs_perms 020 99 99 200 99 w 0
+fs_perms06 fs_perms 200 99 99 99 500 w 0
+fs_perms07 fs_perms 004 99 99 12 100 r 0
+fs_perms08 fs_perms 040 99 99 200 99 r 0
+fs_perms09 fs_perms 400 99 99 99 500 r 0
+fs_perms10 fs_perms 000 99 99 99 99  r 1
+fs_perms11 fs_perms 000 99 99 99 99  w 1
+fs_perms12 fs_perms 000 99 99 99 99  x 1
+fs_perms13 fs_perms 010 99 99 99 500 x 1
+fs_perms14 fs_perms 100 99 99 200 99 x 1
+fs_perms15 fs_perms 020 99 99 99 500 w 1
+fs_perms16 fs_perms 200 99 99 200 99 w 1
+fs_perms17 fs_perms 040 99 99 99 500 r 1
+fs_perms18 fs_perms 400 99 99 200 99 r 1
diff --git a/testcases/kernel/fs/fs_perms/fs_perms.c b/testcases/kernel/fs/fs_perms/fs_perms.c
index ad44028..274988d 100644
--- a/testcases/kernel/fs/fs_perms/fs_perms.c
+++ b/testcases/kernel/fs/fs_perms/fs_perms.c
@@ -1,5 +1,6 @@
 /*
  *   Copyright (c) International Business Machines  Corp., 2000
+ *   Copyright (c) 2010 Cyril Hrubis chrubis@suse.cz
  *
  *   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
@@ -42,111 +43,132 @@
 char *TCID = "fs_perms";
 int TST_TOTAL = 1;
 
-static int testsetup(mode_t mode, int cuserId, int cgroupId)
+void cleanup(void)
+{
+	tst_rmdir();
+	tst_exit();
+}
+
+/*
+ * Create temporary directory and copy binary file equivalent to /bin/true into
+ * it as test.file.
+ */
+static int testsetup(mode_t mode, int user_id, int group_id)
 {
 	int ret;
-	char cmd_str[256];
+	char *ltp_root = getenv("LTPROOT");
+	char cmd_str[1024];
 
-	sprintf(cmd_str, "cp %s/testx test.file", getcwd(NULL, 0));
 	tst_tmpdir();
 
-	ret = unlink("test.file");
-	if (ret && errno != ENOENT)
-		goto done;
+	if (ltp_root == NULL)
+		tst_brkm(TBROK, cleanup, "LTPROOT variable is not exported"); 
+
+	snprintf(cmd_str, sizeof(cmd_str), "cp %s/testcases/bin/fs_perms_testx test.file",
+                 ltp_root);
+
 	ret = system(cmd_str);
+	
 	if (ret)
-		goto done;
+		return ret;
+
 	ret = chmod("test.file", mode);
+	
 	if (ret)
-		goto done;
-	ret = chown("test.file", cuserId, cgroupId);
+		return ret;
 
- done:
+	ret = chown("test.file", user_id, group_id);
+	
 	return ret;
 }
 
-void cleanup(void)
+static int testfperm(int user_id, int group_id, char *fperm)
 {
-	tst_rmdir();
-	tst_exit();
-}
-
-static int testfperm(int userId, int groupId, char *fperm)
-{
-	/* SET CURRENT USER/GROUP PERMISSIONS */
-	if (setegid(groupId)) {
-		tst_brkm(TBROK, cleanup, "could not setegid to %d: %s", groupId, strerror(errno));
+	FILE *testfile;
+	int ret;
+	
+	if (setegid(group_id)) {
+		tst_brkm(TBROK, cleanup, "could not setegid to %d: %s", group_id, strerror(errno));
 		seteuid(0);
 		setegid(0);
 		return -1;
 	}
-	if (seteuid(userId)) {
-		tst_brkm(TBROK, cleanup, "could not seteuid to %d: %s", userId, strerror(errno));
+
+	if (seteuid(user_id)) {
+		tst_brkm(TBROK, cleanup, "could not seteuid to %d: %s", user_id, strerror(errno));
 		seteuid(0);
 		setegid(0);
 		return -1;
 	}
 
-	switch (tolower(fperm[0])) {
-	case 'x': {
+	if (tolower(fperm[0]) == 'x') {
 		int status;
+		
 		if (fork() == 0) {
 			execlp("./test.file", "test.file", NULL);
 			exit(1);
 		}
+		
 		wait(&status);
+		
 		seteuid(0);
 		setegid(0);
+		
 		return WEXITSTATUS(status);
 	}
-	default: {
-		FILE *testfile;
-		if ((testfile = fopen("test.file", fperm))) {
-			fclose(testfile);
-			seteuid(0);
-			setegid(0);
-			return 0;
-		} else {
-			seteuid(0);
-			setegid(0);
-			return 1;
-		}
-	}
-	}
+
+	if ((testfile = fopen("test.file", fperm))) {
+		fclose(testfile);
+		ret = 0;
+	} else
+		ret = 1;	
+
+	seteuid(0);
+	setegid(0);
+
+	return ret;
+}
+
+static void print_usage(const char *bname)
+{
+	char *usage = "<file mode> <file UID> <file GID> "
+                      "<tester UID> <tester GID> <permission "
+                      "to test r|w|x> <expected result 0|1>";
+
+	printf("Usage: %s %s\n", bname, usage);
 }
 
 int main(int argc, char *argv[])
 {
 	char *fperm;
-	int result, exresult = 0, cuserId = 0, cgroupId = 0, userId = 0, groupId = 0;
+	int result, exresult, cuser_id, cgroup_id, user_id, group_id;
 	mode_t mode;
 
 	tst_require_root(tst_exit);
 
-	switch (argc) {
-	case 8:
-		mode = strtol(argv[1], (char **)NULL, 010);
-		cuserId = atoi(argv[2]);
-		cgroupId = atoi(argv[3]);
-		userId = atoi(argv[4]);
-		groupId = atoi(argv[5]);
-		fperm = argv[6];
-		exresult = atoi(argv[7]);
-		break;
-	default:
-		printf("Usage: %s <mode of file> <UID of file> <GID of file> <UID of tester> <GID of tester> <permission to test r|w|x> <expected result as 0|1>\n", argv[0]);
+	if (argc != 8) {
+		print_usage(argv[0]);
 		return 1;
 	}
 
-	result = testsetup(mode, cuserId, cgroupId);
-	if (result) {
+	mode      = strtol(argv[1], NULL, 010);
+	cuser_id  = atoi(argv[2]);
+	cgroup_id = atoi(argv[3]);
+	user_id   = atoi(argv[4]);
+	group_id  = atoi(argv[5]);
+	fperm     = argv[6];
+	exresult  = atoi(argv[7]);
+
+	result = testsetup(mode, cuser_id, cgroup_id);
+
+	if (result)
 		tst_brkm(TBROK, cleanup, "testsetup() failed: %s", strerror(errno));
-	}
 
-	result = testfperm(userId, groupId, fperm);
-	unlink("test.file");
+	result = testfperm(user_id, group_id, fperm);
+
 	tst_resm(exresult == result ? TPASS : TFAIL, "%c a %03o file owned by (%d/%d) as user/group(%d/%d)",
-		fperm[0], mode, cuserId, cgroupId, userId, groupId);
-	cleanup();
-	return 0;
+		fperm[0], mode, cuser_id, cgroup_id, user_id, group_id);
+
+	tst_rmdir();
+	tst_exit();
 }
diff --git a/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh b/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh
deleted file mode 100755
index 5a8df8b..0000000
--- a/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/sh
-
-Code=0
-
-test()
-{
-    arg=${1}; shift
-    res=${1}
-
-    ./fs_perms ${arg} ${res}
-    if [ $? -ne 0 ]; then
-       Code=$((Code + 1))
-    fi
-}
-
-test "001 99 99 12 100 x" 0
-test "010 99 99 200 99 x" 0
-test "100 99 99 99 500 x" 0
-test "002 99 99 12 100 w" 0
-test "020 99 99 200 99 w" 0
-test "200 99 99 99 500 w" 0
-test "004 99 99 12 100 r" 0
-test "040 99 99 200 99 r" 0
-test "400 99 99 99 500 r" 0
-test "000 99 99 99 99 r" 1
-test "000 99 99 99 99 w" 1
-test "000 99 99 99 99 x" 1
-test "010 99 99 99 500 x" 1
-test "100 99 99 200 99 x" 1
-test "020 99 99 99 500 w" 1
-test "200 99 99 200 99 w" 1
-test "040 99 99 99 500 r" 1
-test "400 99 99 200 99 r" 1
-
-exit ${Code}
diff --git a/testcases/kernel/fs/fs_perms/fs_perms_testx.c b/testcases/kernel/fs/fs_perms/fs_perms_testx.c
new file mode 100644
index 0000000..4af2aea
--- /dev/null
+++ b/testcases/kernel/fs/fs_perms/fs_perms_testx.c
@@ -0,0 +1,29 @@
+/*
+ *   Copyright (c) 2010 Cyril Hrubis chrubis@suse.cz
+ *
+ *   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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+ /*
+  * This program just mimics /bin/true behaviour (as the main test tries to
+  * execute this).
+  */
+
+#include <stdio.h>
+
+int main(void)
+{
+	return 0;
+}
diff --git a/testcases/kernel/fs/fs_perms/testx.c b/testcases/kernel/fs/fs_perms/testx.c
deleted file mode 100644
index 5944ce0..0000000
--- a/testcases/kernel/fs/fs_perms/testx.c
+++ /dev/null
@@ -1,4 +0,0 @@
-#include <stdio.h>
-int main(void) {
-	return 0;
-}

[-- Attachment #3: Type: text/plain, Size: 345 bytes --]

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev

[-- Attachment #4: Type: text/plain, Size: 155 bytes --]

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [LTP] [PATCH] fix fs_perms tests
       [not found] ` <g2x364299f41004021212z6e85833ybccad62e6780ec26@mail.gmail.com>
@ 2010-04-08 15:48   ` Cyril Hrubis
  2010-04-19 18:41   ` Cyril Hrubis
  1 sibling, 0 replies; 10+ messages in thread
From: Cyril Hrubis @ 2010-04-08 15:48 UTC (permalink / raw)
  To: Garrett Cooper; +Cc: ltp-list

Hi!
> > #!/bin/true
> >
> > Or maybe more robust:
> >
> > #!/bin/sh
> > true
> >
> > But I'm not sure if there is always /bin/true (as it's buildin in most of the
> > shells) or if I it's good idea to add dependecy for /bin/sh. But this would
> > avoid compiling dummy C program and copying it from $LTPROOT/testcases/bin/.
> >
> > Or we could do some trickery to embed the "dummy" binary file into the code as
> > array.
> 
> It could just be an empty file, or one with just a shebang. Example:
> 
> [gcooper@bayonetta ~]$ ./bar
> [gcooper@bayonetta ~]$ echo $?
> 0
> [gcooper@bayonetta ~]$ cat bar
> #!/bin/sh
> 
> `:' is an alternative to `true' too.

I did a little research what is going on when file is executed (and what is
standardized by POSIX).

Accordingly to posix standard, path to sh cannot be assumed /bin/sh either
/usr/bin/sh. However when file is executed by execlp() and kernel returns
ENOEXEC (because no binfmt handler was found for such file) it end up executed
by sh. So empty file (and wrong path to sh in shebang) should be safe as far as
kernel returns ENOEXEC (and as far as I understand sys_execve and friends from
linux/fs/exec.c this is true in case nobody plays with binfmt handlers) and
maybe may fail in very non standart enviroments. The most robust way seems to
be to look for sh in $PATH and create shebang accordingly.

Any thoughts?

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [LTP] [PATCH] fix fs_perms tests
       [not found] ` <g2x364299f41004021212z6e85833ybccad62e6780ec26@mail.gmail.com>
  2010-04-08 15:48   ` Cyril Hrubis
@ 2010-04-19 18:41   ` Cyril Hrubis
  2010-04-23 12:53     ` Cyril Hrubis
  1 sibling, 1 reply; 10+ messages in thread
From: Cyril Hrubis @ 2010-04-19 18:41 UTC (permalink / raw)
  To: Garrett Cooper; +Cc: ltp-list

[-- Attachment #1: Type: text/plain, Size: 702 bytes --]

Hi!

Okay, did some work on this and here comes the result:

* tst_get_path() function is introduced for looking for
  binaries in $PATH. Notice that there is allready
  search_path() however this one tries to figure out path
  to the current runnig binary and has a little strange
  interface (is used only in some fcntl tests so should be
  easy to fix).

* fs_test now tries to execute two different files instead
  of one. First one is empty and executed by execlp().
  Second one contains shebang and is executed by execl().
  This way we cover both kernel and libc codepath.

+ Various small fixups.

Patch attached.

Signed-off-by: Cyril Hrubis chrubis@suse.cz

-- 
Cyril Hrubis
chrubis@suse.cz

[-- Attachment #2: fix_fs_permsII.patch --]
[-- Type: text/x-patch, Size: 24324 bytes --]

diff --git a/include/test.h b/include/test.h
index e291b36..7ac182a 100644
--- a/include/test.h
+++ b/include/test.h
@@ -262,6 +262,11 @@ int ltp_clone_quick(unsigned long clone_flags, int (*fn)(void *arg),
 char *get_block_device(const char *path);
 char *get_mountpoint(const char *path);
 
+/*
+ * Function from lib/get_path.c
+ */
+int tst_get_path(const char *prog_name, char *buf, size_t buf_len);
+
 #ifdef TST_USE_COMPAT16_SYSCALL
 #define TCID_BIT_SUFFIX "_16"
 #elif  TST_USE_NEWER64_SYSCALL
diff --git a/lib/get_path.c b/lib/get_path.c
new file mode 100644
index 0000000..c82fcea
--- /dev/null
+++ b/lib/get_path.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2010 Cyril Hrubis chrubis@suse.cz
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 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., 59
+ */
+
+ /*
+  * Looks for binary prog_name in $PATH. 
+  *
+  * If such file exists and if you are able at least to read it, zero is
+  * returned and absolute path to the file is filled into buf. In case buf is
+  * too short to hold the absolute path + prog_name for the file we are looking
+  * for -1 is returned as well as when there is no such file in all paths in
+  * $PATH.
+  */
+
+#include "test.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+static int file_exist(const char *path)
+{
+	struct stat st;
+
+	if (!access(path, R_OK) && !stat(path, &st) && S_ISREG(st.st_mode))
+		return 1;
+
+	return 0;
+}
+
+int tst_get_path(const char *prog_name, char *buf, size_t buf_len)
+{
+	const char *path = (const char*) getenv("PATH");
+	int i;
+
+	if (path == NULL)
+		return -1;
+
+	do {
+		/* copy path */
+		for (i = 0; i < buf_len && path[i] != '\0' && path[i] != ':'; i++)
+			buf[i] = path[i];
+		
+		/* add slash at the end if needed */
+		if (buf[i - 1] != '/')
+			buf[i++] = '/';
+
+		/* copy the program name */
+		strncpy(buf + i, prog_name, buf_len - i);
+		
+		/* path + pname fits into buf *
+		 * look if such file exists   */
+		if (buf[buf_len - 1] == '\0') {
+			if (file_exist(buf))
+				return 0;
+		}
+
+		/* eat all to the next delimiter */
+		while (*path != '\0' && *path != ':')
+			path++;
+		
+		/* eat all delimiters */
+		while (*path != '\0' && *path == ':')
+			path++;
+		
+	} while (*path != '\0');
+
+	return -1;
+}
+
diff --git a/runltp b/runltp
index b848a7f..097e32e 100755
--- a/runltp
+++ b/runltp
@@ -557,6 +557,7 @@ main()
 
         for SCENFILES in ${LTPROOT}/runtest/syscalls                \
                          ${LTPROOT}/runtest/fs                      \
+                         ${LTPROOT}/runtest/fs_perms_simple         \
                          ${LTPROOT}/runtest/fsx                     \
                          ${LTPROOT}/runtest/dio                     \
                          ${LTPROOT}/runtest/io                      \
diff --git a/runtest/fs b/runtest/fs
index 75c5e38..2de871d 100644
--- a/runtest/fs
+++ b/runtest/fs
@@ -64,9 +64,6 @@ writetest01	writetest
 #Also run the fs_di (Data Integrity tests)
 fs_di fs_di -d $TMPDIR
 
-#Also run the fs_perms (File System Permission Tests)
-fs_perms fs_perms_simpletest.sh
-
 # Read every file in /proc. Not likely to crash, but does enough 
 # to disturb the kernel. A good kernel latency killer too.
 # Was not sure why it should reside in runtest/crashme and won´t get tested ever
diff --git a/runtest/fs_perms_simple b/runtest/fs_perms_simple
new file mode 100644
index 0000000..cc986bd
--- /dev/null
+++ b/runtest/fs_perms_simple
@@ -0,0 +1,26 @@
+#
+# These tests are setting file permissions/group/uid and are trying to
+# open/write/execute the file.
+#
+#
+#
+# fs_perms file_mode file_uid file_gid test_uid test_gid mode (r|w|x) expected_result
+#
+fs_perms01 fs_perms 001 99 99 12 100 x 0
+fs_perms02 fs_perms 010 99 99 200 99 x 0
+fs_perms03 fs_perms 100 99 99 99 500 x 0
+fs_perms04 fs_perms 002 99 99 12 100 w 0
+fs_perms05 fs_perms 020 99 99 200 99 w 0
+fs_perms06 fs_perms 200 99 99 99 500 w 0
+fs_perms07 fs_perms 004 99 99 12 100 r 0
+fs_perms08 fs_perms 040 99 99 200 99 r 0
+fs_perms09 fs_perms 400 99 99 99 500 r 0
+fs_perms10 fs_perms 000 99 99 99 99  r 1
+fs_perms11 fs_perms 000 99 99 99 99  w 1
+fs_perms12 fs_perms 000 99 99 99 99  x 1
+fs_perms13 fs_perms 010 99 99 99 500 x 1
+fs_perms14 fs_perms 100 99 99 200 99 x 1
+fs_perms15 fs_perms 020 99 99 99 500 w 1
+fs_perms16 fs_perms 200 99 99 200 99 w 1
+fs_perms17 fs_perms 040 99 99 99 500 r 1
+fs_perms18 fs_perms 400 99 99 200 99 r 1
diff --git a/testcases/kernel/fs/fs_perms/Makefile b/testcases/kernel/fs/fs_perms/Makefile
index 48aa7d6..c0377cc 100644
--- a/testcases/kernel/fs/fs_perms/Makefile
+++ b/testcases/kernel/fs/fs_perms/Makefile
@@ -23,7 +23,4 @@
 top_srcdir			?= ../../../..
 
 include $(top_srcdir)/include/mk/testcases.mk
-
-INSTALL_TARGETS			:= fs_perms_simpletest.sh
-
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/fs/fs_perms/fs_perms.c b/testcases/kernel/fs/fs_perms/fs_perms.c
index ad44028..14a9d1a 100644
--- a/testcases/kernel/fs/fs_perms/fs_perms.c
+++ b/testcases/kernel/fs/fs_perms/fs_perms.c
@@ -1,5 +1,6 @@
 /*
  *   Copyright (c) International Business Machines  Corp., 2000
+ *   Copyright (c) 2010 Cyril Hrubis chrubis@suse.cz
  *
  *   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
@@ -25,9 +26,12 @@
  *     (04/19/01)v1.0  Added test for execute bit.
  *     (05/23/01)v1.1  Added command line parameter to specify test file.
  *     (07/12/01)v1.2  Removed conf file and went to command line parameters.
+ *     (10/19/04)      Rewritten to fit ltp test interface.
+ *                     Also now we try to run two different files, one is executed by execl,
+ *                     has shebang and should end up executed by kernel, other one is empty
+ *                     is executed by execlp and should end up executed by libc.
  */
 
-#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
@@ -39,114 +43,173 @@
 
 #include "test.h"
 
+#define TEST_FILE_NAME1 "./test.file1"
+#define TEST_FILE_NAME2 "./test.file2"
+#define MAX_PATH 1024
+
 char *TCID = "fs_perms";
 int TST_TOTAL = 1;
 
-static int testsetup(mode_t mode, int cuserId, int cgroupId)
-{
-	int ret;
-	char cmd_str[256];
-
-	sprintf(cmd_str, "cp %s/testx test.file", getcwd(NULL, 0));
-	tst_tmpdir();
-
-	ret = unlink("test.file");
-	if (ret && errno != ENOENT)
-		goto done;
-	ret = system(cmd_str);
-	if (ret)
-		goto done;
-	ret = chmod("test.file", mode);
-	if (ret)
-		goto done;
-	ret = chown("test.file", cuserId, cgroupId);
-
- done:
-	return ret;
-}
-
-void cleanup(void)
+static void cleanup(void)
 {
+	seteuid(0);
+	setegid(0);
+	
 	tst_rmdir();
 	tst_exit();
 }
 
-static int testfperm(int userId, int groupId, char *fperm)
+/*
+ * Create file and set permissions, user id, group id.
+ *
+ * If flag is non zero, the file contains #!/PATH/sh shebang otherwise it's
+ * empty.
+ */
+static void testsetup(const char *file_name, int flag, mode_t mode, 
+                      int user_id, int group_id)
 {
-	/* SET CURRENT USER/GROUP PERMISSIONS */
-	if (setegid(groupId)) {
-		tst_brkm(TBROK, cleanup, "could not setegid to %d: %s", groupId, strerror(errno));
-		seteuid(0);
-		setegid(0);
-		return -1;
-	}
-	if (seteuid(userId)) {
-		tst_brkm(TBROK, cleanup, "could not seteuid to %d: %s", userId, strerror(errno));
-		seteuid(0);
-		setegid(0);
-		return -1;
+	FILE *file;
+
+	file = fopen(file_name, "w");
+	
+	if (file == NULL)
+		tst_brkm(TBROK | TERRNO, cleanup,
+		         "Could not create test file %s.", file_name);
+	
+	/* create file with shebang */
+	if (flag) {
+		char buf[MAX_PATH];
+
+		if (tst_get_path("sh", buf, MAX_PATH))
+			tst_brkm(TBROK, cleanup,
+			         "Could not find path to sh in $PATH.");
+
+		if (fprintf(file, "#!%s\n", buf) < 0)
+			tst_brkm(TBROK, cleanup, "Syscall fprintf failed.");
 	}
 
-	switch (tolower(fperm[0])) {
-	case 'x': {
+	if (fclose(file))
+		tst_brkm(TBROK | TERRNO, cleanup, "Syscall fclose failed.");
+
+	if (chmod(file_name, mode))
+		tst_brkm(TBROK | TERRNO, cleanup,
+		         "Could not chmod test file %s.", file_name); 
+
+	if (chown(file_name, user_id, group_id))
+		tst_brkm(TBROK | TERRNO, cleanup,
+		         "Could not chown test file %s.", file_name); 
+}
+
+/*
+ * Test permissions.
+ */
+static int testfperm(const char *file_name, int flag, int user_id,
+                     int group_id, char *fperm)
+
+{
+	FILE *file;
+	int ret;
+	
+	if (setegid(group_id))
+		tst_brkm(TBROK | TERRNO, cleanup, "Could not setegid to %d.",
+		         group_id);
+
+	if (seteuid(user_id))
+		tst_brkm(TBROK | TERRNO, cleanup, "Could not seteuid to %d.",
+		         user_id);
+
+	if (tolower(fperm[0]) == 'x') {
 		int status;
+		
 		if (fork() == 0) {
-			execlp("./test.file", "test.file", NULL);
+			/*
+			 * execlp runs file with sh in case kernel has
+			 * no binmft handler for it, execl does not.
+			 */
+			if (flag)
+				execl(file_name, file_name, NULL);
+			else
+				execlp(file_name, "test", NULL);
+	
 			exit(1);
 		}
+		
 		wait(&status);
+		
 		seteuid(0);
 		setegid(0);
+		
 		return WEXITSTATUS(status);
 	}
-	default: {
-		FILE *testfile;
-		if ((testfile = fopen("test.file", fperm))) {
-			fclose(testfile);
-			seteuid(0);
-			setegid(0);
-			return 0;
-		} else {
-			seteuid(0);
-			setegid(0);
-			return 1;
-		}
-	}
-	}
+
+	if ((file = fopen(file_name, fperm)) != NULL) {
+		fclose(file);
+		ret = 0;
+	} else
+		ret = 1;
+
+	seteuid(0);
+	setegid(0);
+
+	return ret;
+}
+
+static void print_usage(const char *bname)
+{
+	char *usage = "<file mode> <file UID> <file GID> "
+                      "<tester UID> <tester GID> <permission "
+                      "to test r|w|x> <expected result 0|1>";
+
+	printf("Usage: %s %s\n", bname, usage);
 }
 
 int main(int argc, char *argv[])
 {
 	char *fperm;
-	int result, exresult = 0, cuserId = 0, cgroupId = 0, userId = 0, groupId = 0;
+	int exp_res, cuser_id, cgroup_id, user_id, group_id;
+	int res1, res2 = 1;
 	mode_t mode;
 
 	tst_require_root(tst_exit);
 
-	switch (argc) {
-	case 8:
-		mode = strtol(argv[1], (char **)NULL, 010);
-		cuserId = atoi(argv[2]);
-		cgroupId = atoi(argv[3]);
-		userId = atoi(argv[4]);
-		groupId = atoi(argv[5]);
-		fperm = argv[6];
-		exresult = atoi(argv[7]);
-		break;
-	default:
-		printf("Usage: %s <mode of file> <UID of file> <GID of file> <UID of tester> <GID of tester> <permission to test r|w|x> <expected result as 0|1>\n", argv[0]);
-		return 1;
+	if (argc != 8) {
+		print_usage(argv[0]);
+		tst_exit();
 	}
 
-	result = testsetup(mode, cuserId, cgroupId);
-	if (result) {
-		tst_brkm(TBROK, cleanup, "testsetup() failed: %s", strerror(errno));
+	if (strlen(argv[6]) > 1) {
+		print_usage(argv[0]);
+		tst_exit();
 	}
 
-	result = testfperm(userId, groupId, fperm);
-	unlink("test.file");
-	tst_resm(exresult == result ? TPASS : TFAIL, "%c a %03o file owned by (%d/%d) as user/group(%d/%d)",
-		fperm[0], mode, cuserId, cgroupId, userId, groupId);
-	cleanup();
-	return 0;
+	mode      = strtol(argv[1], NULL, 10);
+	cuser_id  = atoi(argv[2]);
+	cgroup_id = atoi(argv[3]);
+	user_id   = atoi(argv[4]);
+	group_id  = atoi(argv[5]);
+	fperm     = argv[6];
+	exp_res   = atoi(argv[7]);
+
+	tst_tmpdir();
+	testsetup(TEST_FILE_NAME1, 0, mode, cuser_id, cgroup_id);
+	
+	/* more tests for 'x' flag */
+	if (tolower(fperm[0]) == 'x') {
+		testsetup(TEST_FILE_NAME2, 1, mode, cuser_id, cgroup_id);
+		res2 = testfperm(TEST_FILE_NAME2, 1, user_id, group_id, fperm);
+
+		if (res2 == exp_res)
+			res2 = 1;
+		else
+			res2 = 0;
+	}
+
+	res1 = testfperm(TEST_FILE_NAME1, 0, user_id, group_id, fperm);
+
+	tst_resm((exp_res == res1) && res2 ? TPASS : TFAIL,
+	         "%c a %03o file owned by (%d/%d) as user/group(%d/%d)",
+	         fperm[0], mode, cuser_id, cgroup_id, user_id, group_id);
+
+	tst_rmdir();
+	tst_exit();
 }
diff --git a/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh b/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh
deleted file mode 100755
index 5a8df8b..0000000
--- a/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/sh
-
-Code=0
-
-test()
-{
-    arg=${1}; shift
-    res=${1}
-
-    ./fs_perms ${arg} ${res}
-    if [ $? -ne 0 ]; then
-       Code=$((Code + 1))
-    fi
-}
-
-test "001 99 99 12 100 x" 0
-test "010 99 99 200 99 x" 0
-test "100 99 99 99 500 x" 0
-test "002 99 99 12 100 w" 0
-test "020 99 99 200 99 w" 0
-test "200 99 99 99 500 w" 0
-test "004 99 99 12 100 r" 0
-test "040 99 99 200 99 r" 0
-test "400 99 99 99 500 r" 0
-test "000 99 99 99 99 r" 1
-test "000 99 99 99 99 w" 1
-test "000 99 99 99 99 x" 1
-test "010 99 99 99 500 x" 1
-test "100 99 99 200 99 x" 1
-test "020 99 99 99 500 w" 1
-test "200 99 99 200 99 w" 1
-test "040 99 99 99 500 r" 1
-test "400 99 99 200 99 r" 1
-
-exit ${Code}
diff --git a/testcases/kernel/fs/fs_perms/testx.c b/testcases/kernel/fs/fs_perms/testx.c
deleted file mode 100644
index 5944ce0..0000000
--- a/testcases/kernel/fs/fs_perms/testx.c
+++ /dev/null
@@ -1,4 +0,0 @@
-#include <stdio.h>
-int main(void) {
-	return 0;
-}
diff --git a/testcases/kernel/fs/ftest/ftest01.c b/testcases/kernel/fs/ftest/ftest01.c
index c4dc5c8..41b14de 100644
--- a/testcases/kernel/fs/ftest/ftest01.c
+++ b/testcases/kernel/fs/ftest/ftest01.c
@@ -90,9 +90,6 @@ static int parent_pid;
 static int pidlist[MAXCHILD];
 static char test_name[2];
 
-static char fuss[40];         /* directory to do this in */
-static char homedir[200];     /* where we started */
-
 static int local_flag;
 
 int main(int ac, char *av[])
@@ -130,18 +127,8 @@ static void setup(void)
 	 * Save starting directory.
 	 */
 	tst_tmpdir();
-	getcwd(homedir, sizeof(homedir));
 	parent_pid = getpid();
 
-	if (!fuss[0])
-		sprintf(fuss, "./ftest1.%d", getpid());
-
-	mkdir(fuss, 0755);
-
-	if (chdir(fuss) < 0) {
-		tst_brkm(TBROK,0,"Can't chdir(%s): %s", fuss, strerror(errno));
-	}
-
 	/*
 	 * Default values for run conditions.
 	 */
@@ -162,16 +149,16 @@ static void setup(void)
 
 static void runtest(void)
 {
-	int i, pid, child, status, count;
+	int i, child, status, count;
 
-	for(i = 0; i < nchild; i++) {
+	for (i = 0; i < nchild; i++) {
 
 		test_name[0] = 'a' + i;
 		test_name[1] = '\0';
 		fd = open(test_name, O_RDWR|O_CREAT|O_TRUNC, 0666);
 
 		if (fd < 0)
-			tst_brkm(TBROK,0, "Can't creating %s/%s: %s", fuss, test_name, strerror(errno));
+			tst_brkm(TBROK,0, "Can't creating %s: %s", test_name, strerror(errno));
 
 		if ((child = fork()) == 0) {
 			dotest(nchild, i, fd);
@@ -221,29 +208,6 @@ static void runtest(void)
 	else
 		tst_resm(TFAIL, "Test failed in fork and wait.");
 
-	chdir(homedir);
-	pid = fork();
-
-	if (pid < 0) {
-
-		tst_resm(TINFO, "System resource may be too low, fork() malloc()"
-		          " etc are likely to fail.");
-
-		tst_resm(TBROK, "Can not remove '%s' due to inability of fork.",fuss);
-		sync();
-		tst_exit();
-	}
-
-	if (pid == 0) {
-		execl("/bin/rm", "rm", "-rf", fuss, NULL);
-		tst_exit();
-	}
-
-	wait(&status);
-
-	if (status)
-		tst_resm(TINFO, "CAUTION - ftest1, '%s' may not be removed", fuss);
-
 	sync();
 }
 
diff --git a/testcases/kernel/fs/ftest/ftest03.c b/testcases/kernel/fs/ftest/ftest03.c
index 1cb6d6f..0f0eccc 100644
--- a/testcases/kernel/fs/ftest/ftest03.c
+++ b/testcases/kernel/fs/ftest/ftest03.c
@@ -96,12 +96,9 @@ static int parent_pid;
 static int pidlist[MAXCHILD];
 static char test_name[2];     /* childs test directory name */
 
-static char fuss[40];         /* directory to do this in */
-static char homedir[200];     /* where we started */
-
 static int local_flag;
 
-int main (int ac, char *av[])
+int main(int ac, char *av[])
 {
         int lc;
         char *msg;
@@ -138,31 +135,14 @@ int main (int ac, char *av[])
 
 static void setup(void)
 {
-	char wdbuf[MAXPATHLEN];
-
 	/*
 	 * Make a directory to do this in; ignore error if already exists.
 	 * Save starting directory.
 	 */
 	tst_tmpdir();
 
-	if (getcwd(homedir, sizeof(homedir)) == NULL) {
-		tst_resm(TBROK, "getcwd() failed");
-		tst_exit();
-	}
-
 	parent_pid = getpid();
 
-	if (!fuss[0])
-		sprintf(fuss, "%s/ftest03.%d", getcwd(wdbuf, sizeof( wdbuf)), getpid());
-
-	mkdir(fuss, 0755);
-
-	if (chdir(fuss) < 0) {
-		tst_resm(TBROK,"\tCan't chdir(%s), error %d.", fuss, errno);
-		tst_exit() ;
-	}
-
 	/*
 	 * Default values for run conditions.
 	 */
@@ -181,9 +161,9 @@ static void setup(void)
 
 static void runtest(void)
 {
-	int i, pid, child, status, count;
+	int i, child, status, count;
 
-	for(i = 0; i < nchild; i++) {
+	for (i = 0; i < nchild; i++) {
 
 		test_name[0] = 'a' + i;
 		test_name[1] = '\0';
@@ -191,7 +171,7 @@ static void runtest(void)
 		fd = open(test_name, O_RDWR|O_CREAT|O_TRUNC, 0666);
 
 		if (fd < 0) {
-			tst_resm(TBROK, "\tError %d creating %s/%s.", errno, fuss, test_name);
+			tst_resm(TBROK, "Error %d creating %s.", errno, test_name);
 			tst_exit();
 		}
 
@@ -241,30 +221,6 @@ static void runtest(void)
 		local_flag = FAILED;
 	}
 
-	chdir(homedir);
-
-	pid = fork();
-
-	if (pid < 0) {
-		tst_resm(TINFO, "System resource may be too low, fork() malloc()"
-                              " etc are likely to fail.");
-                tst_resm(TBROK, "Test broken due to inability of fork.");
-		sync();
-		tst_exit();
-	}
-
-	if (pid == 0) {
-		execl("/bin/rm", "rm", "-rf", fuss, NULL);
-		tst_exit();
-	} else
-		wait(&status);
-
-	if (status) {
-		tst_resm(TINFO, "CAUTION - ftest03, '%s' may not be removed", fuss);
-		tst_resm(TINFO, "CAUTION - ftest03, '%s' may not be removed",
-		  fuss);
-	}
-
 	sync();
 }
 
diff --git a/testcases/kernel/fs/ftest/ftest05.c b/testcases/kernel/fs/ftest/ftest05.c
index 220d9fd..3c66ab0 100644
--- a/testcases/kernel/fs/ftest/ftest05.c
+++ b/testcases/kernel/fs/ftest/ftest05.c
@@ -94,9 +94,6 @@ static int parent_pid;
 static int pidlist[MAXCHILD];
 static char test_name[2];     /* childs test directory name */
 
-static char fuss[40];         /* directory to do this in */
-static char homedir[200];     /* where we started */
-
 static int local_flag;
 
 int main(int ac, char *av[])
@@ -135,19 +132,9 @@ static void setup(void)
 	 * Save starting directory.
 	 */
 	tst_tmpdir();
-	getcwd(homedir, sizeof (homedir));
+	
 	parent_pid = getpid();
 
-	if (!fuss[0])
-		sprintf(fuss, "./ftest05.%d", getpid());
-
-	mkdir(fuss, 0755);
-
-	if (chdir(fuss) < 0) {
-		tst_resm(TBROK,"\tCan't chdir(%s), error %d.", fuss, errno);
-		tst_exit();
-	}
-
 	/*
 	 * Default values for run conditions.
 	 */
@@ -167,7 +154,7 @@ static void setup(void)
 
 static void runtest(void)
 {
-	int i, pid, child, status, count;
+	int i, child, status, count;
 
 	for (i = 0; i < nchild; i++) {
 		test_name[0] = 'a' + i;
@@ -175,7 +162,7 @@ static void runtest(void)
 		fd = open(test_name, O_RDWR|O_CREAT|O_TRUNC, 0666);
 
 		if (fd < 0) {
-			tst_resm(TBROK, "\tError %d creating %s/%s.", errno, fuss, test_name);
+			tst_resm(TBROK, "Error %d creating %s.", errno, test_name);
 			tst_exit();
 		}
 
@@ -221,28 +208,6 @@ static void runtest(void)
 		local_flag = FAILED;
 	}
 
-	chdir(homedir);
-	pid = fork();
-
-	if (pid < 0) {
-		tst_resm(TINFO, "System resource may be too low, fork() malloc()"
-                                 " etc are likely to fail.");
-                tst_resm(TBROK, "Test broken due to inability of fork.");
-		sync();
-                tst_exit();
-	}
-
-	if (pid == 0) {
-		execl("/bin/rm", "rm", "-rf", fuss, NULL);
-		tst_exit();
-	}
-
-	wait(&status);
-
-	if (status) {
-		tst_resm(TINFO,"CAUTION - ftest05, '%s' may not be removed", fuss);
-	}
-
 	sync();
 }
 
diff --git a/testcases/kernel/fs/ftest/ftest07.c b/testcases/kernel/fs/ftest/ftest07.c
index 8cda511..ef42daf 100644
--- a/testcases/kernel/fs/ftest/ftest07.c
+++ b/testcases/kernel/fs/ftest/ftest07.c
@@ -86,6 +86,7 @@ int TST_TOTAL = 1;
 #define	MAXIOVCNT	16
 
 static void setup(void);
+static void cleanup(void);
 static void runtest(void);
 static void dotest(int, int, int);
 static void domisc(int, int, char*);
@@ -102,9 +103,6 @@ static int parent_pid;
 static int pidlist[MAXCHILD];
 static char test_name[2];     /* childs test directory name */
 
-static char fuss[40];         /* directory to do this in */
-static char homedir[200];     /* where we started */
-
 static int local_flag;
 
 int main(int ac, char *av[])
@@ -141,58 +139,45 @@ int main(int ac, char *av[])
 	return 0;
 }
 
-static void setup(void)
+static void cleanup(void)
 {
-	char wdbuf[MAXPATHLEN], *cwd;
+	tst_rmdir();
+	tst_exit();
+}
 
+static void setup(void)
+{
 	/*
 	 * Make a directory to do this in; ignore error if already exists.
 	 * Save starting directory.
 	 */
-	if ((cwd = getcwd(homedir, sizeof (homedir))) == NULL ) {
-		tst_resm(TBROK,"Failed to get corrent directory") ;
-		tst_exit();
-	}
-
 	parent_pid = getpid();
 	tst_tmpdir();
-	if (!fuss[0])
-		sprintf(fuss, "%s/ftest07.%d", getcwd(wdbuf, sizeof( wdbuf)), getpid());
-
-	mkdir(fuss, 0755);
-
-	if (chdir(fuss) < 0) {
-		tst_resm(TBROK,"\tCan't chdir(%s), error %d.", fuss, errno);
-		tst_exit() ;
-	}
-
+	
 	/*
 	 * Default values for run conditions.
 	 */
-
 	iterations = 10;
 	nchild = 5;
 	csize = K_2;		/* should run with 1, 2, and 4 K sizes */
 	max_size = K_1 * K_1;
 	misc_intvl = 10;
 
-	if (sigset(SIGTERM, term) == SIG_ERR) {
-		tst_resm(TBROK, " sigset failed: signo = 15") ;
-		tst_exit() ;
-	}
-
+	if (sigset(SIGTERM, term) == SIG_ERR)
+		tst_brkm(TBROK, cleanup,  " sigset failed: signo = 15");
 }
 
 static void runtest(void)
 {
-	int pid, child, status, count, i;
+	int child, status, count, i;
 
 	for (i = 0; i < nchild; i++) {
 		test_name[0] = 'a' + i;
 		test_name[1] = '\0';
 		fd = open(test_name, O_RDWR|O_CREAT|O_TRUNC, 0666);
+		
 		if (fd < 0) {
-			tst_resm(TBROK, "\tError %d creating %s/%s.", errno, fuss, test_name);
+			tst_resm(TBROK, "Error %d creating %s.", errno, test_name);
 			tst_exit();
 		}
 
@@ -241,25 +226,6 @@ static void runtest(void)
 		local_flag = FAILED;
 	}
 
-	chdir(homedir);
-
-	pid = fork();
-	if (pid < 0) {
-		tst_resm(TINFO, "System resource may be too low, fork() malloc()"
-                                    " etc are likely to fail.");
-                tst_resm(TBROK, "Test broken due to inability of fork.");
-                tst_exit();
-	}
-
-	if (pid == 0) {
-		execl("/bin/rm", "rm", "-rf", fuss, NULL);
-			exit(1);
-		} else
-			wait(&status);
-	if (status) {
-		tst_resm(TINFO, "CAUTION - ftest07, '%s' may not be removed", fuss);
-	}
-
 	sync();
 }
 

[-- Attachment #3: Type: text/plain, Size: 345 bytes --]

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev

[-- Attachment #4: Type: text/plain, Size: 155 bytes --]

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [LTP] [PATCH] fix fs_perms tests
  2010-04-19 18:41   ` Cyril Hrubis
@ 2010-04-23 12:53     ` Cyril Hrubis
       [not found]       ` <n2s364299f41004231253offfe856amfa09260ba50cf18b@mail.gmail.com>
  0 siblings, 1 reply; 10+ messages in thread
From: Cyril Hrubis @ 2010-04-23 12:53 UTC (permalink / raw)
  To: Garrett Cooper; +Cc: ltp-list

[-- Attachment #1: Type: text/plain, Size: 816 bytes --]

Hi!
> Okay, did some work on this and here comes the result:
> 
> * tst_get_path() function is introduced for looking for
>   binaries in $PATH. Notice that there is allready
>   search_path() however this one tries to figure out path
>   to the current runnig binary and has a little strange
>   interface (is used only in some fcntl tests so should be
>   easy to fix).
> 
> * fs_test now tries to execute two different files instead
>   of one. First one is empty and executed by execlp().
>   Second one contains shebang and is executed by execl().
>   This way we cover both kernel and libc codepath.
> 
> + Various small fixups.
> 
> Patch attached.
> 
> Signed-off-by: Cyril Hrubis chrubis@suse.cz
> 

Uff, the patch get mixed with ftestXX patch. This one should
be correct.

-- 
Cyril Hrubis
chrubis@suse.cz

[-- Attachment #2: fix_fs_permsII.patch --]
[-- Type: text/x-patch, Size: 14587 bytes --]

diff --git a/include/test.h b/include/test.h
index e291b36..7ac182a 100644
--- a/include/test.h
+++ b/include/test.h
@@ -262,6 +262,11 @@ int ltp_clone_quick(unsigned long clone_flags, int (*fn)(void *arg),
 char *get_block_device(const char *path);
 char *get_mountpoint(const char *path);
 
+/*
+ * Function from lib/get_path.c
+ */
+int tst_get_path(const char *prog_name, char *buf, size_t buf_len);
+
 #ifdef TST_USE_COMPAT16_SYSCALL
 #define TCID_BIT_SUFFIX "_16"
 #elif  TST_USE_NEWER64_SYSCALL
diff --git a/lib/get_path.c b/lib/get_path.c
new file mode 100644
index 0000000..c82fcea
--- /dev/null
+++ b/lib/get_path.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2010 Cyril Hrubis chrubis@suse.cz
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 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., 59
+ */
+
+ /*
+  * Looks for binary prog_name in $PATH. 
+  *
+  * If such file exists and if you are able at least to read it, zero is
+  * returned and absolute path to the file is filled into buf. In case buf is
+  * too short to hold the absolute path + prog_name for the file we are looking
+  * for -1 is returned as well as when there is no such file in all paths in
+  * $PATH.
+  */
+
+#include "test.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+static int file_exist(const char *path)
+{
+	struct stat st;
+
+	if (!access(path, R_OK) && !stat(path, &st) && S_ISREG(st.st_mode))
+		return 1;
+
+	return 0;
+}
+
+int tst_get_path(const char *prog_name, char *buf, size_t buf_len)
+{
+	const char *path = (const char*) getenv("PATH");
+	int i;
+
+	if (path == NULL)
+		return -1;
+
+	do {
+		/* copy path */
+		for (i = 0; i < buf_len && path[i] != '\0' && path[i] != ':'; i++)
+			buf[i] = path[i];
+		
+		/* add slash at the end if needed */
+		if (buf[i - 1] != '/')
+			buf[i++] = '/';
+
+		/* copy the program name */
+		strncpy(buf + i, prog_name, buf_len - i);
+		
+		/* path + pname fits into buf *
+		 * look if such file exists   */
+		if (buf[buf_len - 1] == '\0') {
+			if (file_exist(buf))
+				return 0;
+		}
+
+		/* eat all to the next delimiter */
+		while (*path != '\0' && *path != ':')
+			path++;
+		
+		/* eat all delimiters */
+		while (*path != '\0' && *path == ':')
+			path++;
+		
+	} while (*path != '\0');
+
+	return -1;
+}
+
diff --git a/runltp b/runltp
index b848a7f..097e32e 100755
--- a/runltp
+++ b/runltp
@@ -557,6 +557,7 @@ main()
 
         for SCENFILES in ${LTPROOT}/runtest/syscalls                \
                          ${LTPROOT}/runtest/fs                      \
+                         ${LTPROOT}/runtest/fs_perms_simple         \
                          ${LTPROOT}/runtest/fsx                     \
                          ${LTPROOT}/runtest/dio                     \
                          ${LTPROOT}/runtest/io                      \
diff --git a/runtest/fs b/runtest/fs
index 75c5e38..2de871d 100644
--- a/runtest/fs
+++ b/runtest/fs
@@ -64,9 +64,6 @@ writetest01	writetest
 #Also run the fs_di (Data Integrity tests)
 fs_di fs_di -d $TMPDIR
 
-#Also run the fs_perms (File System Permission Tests)
-fs_perms fs_perms_simpletest.sh
-
 # Read every file in /proc. Not likely to crash, but does enough 
 # to disturb the kernel. A good kernel latency killer too.
 # Was not sure why it should reside in runtest/crashme and won´t get tested ever
diff --git a/runtest/fs_perms_simple b/runtest/fs_perms_simple
new file mode 100644
index 0000000..cc986bd
--- /dev/null
+++ b/runtest/fs_perms_simple
@@ -0,0 +1,26 @@
+#
+# These tests are setting file permissions/group/uid and are trying to
+# open/write/execute the file.
+#
+#
+#
+# fs_perms file_mode file_uid file_gid test_uid test_gid mode (r|w|x) expected_result
+#
+fs_perms01 fs_perms 001 99 99 12 100 x 0
+fs_perms02 fs_perms 010 99 99 200 99 x 0
+fs_perms03 fs_perms 100 99 99 99 500 x 0
+fs_perms04 fs_perms 002 99 99 12 100 w 0
+fs_perms05 fs_perms 020 99 99 200 99 w 0
+fs_perms06 fs_perms 200 99 99 99 500 w 0
+fs_perms07 fs_perms 004 99 99 12 100 r 0
+fs_perms08 fs_perms 040 99 99 200 99 r 0
+fs_perms09 fs_perms 400 99 99 99 500 r 0
+fs_perms10 fs_perms 000 99 99 99 99  r 1
+fs_perms11 fs_perms 000 99 99 99 99  w 1
+fs_perms12 fs_perms 000 99 99 99 99  x 1
+fs_perms13 fs_perms 010 99 99 99 500 x 1
+fs_perms14 fs_perms 100 99 99 200 99 x 1
+fs_perms15 fs_perms 020 99 99 99 500 w 1
+fs_perms16 fs_perms 200 99 99 200 99 w 1
+fs_perms17 fs_perms 040 99 99 99 500 r 1
+fs_perms18 fs_perms 400 99 99 200 99 r 1
diff --git a/testcases/kernel/fs/fs_perms/Makefile b/testcases/kernel/fs/fs_perms/Makefile
index 48aa7d6..c0377cc 100644
--- a/testcases/kernel/fs/fs_perms/Makefile
+++ b/testcases/kernel/fs/fs_perms/Makefile
@@ -23,7 +23,4 @@
 top_srcdir			?= ../../../..
 
 include $(top_srcdir)/include/mk/testcases.mk
-
-INSTALL_TARGETS			:= fs_perms_simpletest.sh
-
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/fs/fs_perms/fs_perms.c b/testcases/kernel/fs/fs_perms/fs_perms.c
index ad44028..14a9d1a 100644
--- a/testcases/kernel/fs/fs_perms/fs_perms.c
+++ b/testcases/kernel/fs/fs_perms/fs_perms.c
@@ -1,5 +1,6 @@
 /*
  *   Copyright (c) International Business Machines  Corp., 2000
+ *   Copyright (c) 2010 Cyril Hrubis chrubis@suse.cz
  *
  *   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
@@ -25,9 +26,12 @@
  *     (04/19/01)v1.0  Added test for execute bit.
  *     (05/23/01)v1.1  Added command line parameter to specify test file.
  *     (07/12/01)v1.2  Removed conf file and went to command line parameters.
+ *     (10/19/04)      Rewritten to fit ltp test interface.
+ *                     Also now we try to run two different files, one is executed by execl,
+ *                     has shebang and should end up executed by kernel, other one is empty
+ *                     is executed by execlp and should end up executed by libc.
  */
 
-#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
@@ -39,114 +43,173 @@
 
 #include "test.h"
 
+#define TEST_FILE_NAME1 "./test.file1"
+#define TEST_FILE_NAME2 "./test.file2"
+#define MAX_PATH 1024
+
 char *TCID = "fs_perms";
 int TST_TOTAL = 1;
 
-static int testsetup(mode_t mode, int cuserId, int cgroupId)
-{
-	int ret;
-	char cmd_str[256];
-
-	sprintf(cmd_str, "cp %s/testx test.file", getcwd(NULL, 0));
-	tst_tmpdir();
-
-	ret = unlink("test.file");
-	if (ret && errno != ENOENT)
-		goto done;
-	ret = system(cmd_str);
-	if (ret)
-		goto done;
-	ret = chmod("test.file", mode);
-	if (ret)
-		goto done;
-	ret = chown("test.file", cuserId, cgroupId);
-
- done:
-	return ret;
-}
-
-void cleanup(void)
+static void cleanup(void)
 {
+	seteuid(0);
+	setegid(0);
+	
 	tst_rmdir();
 	tst_exit();
 }
 
-static int testfperm(int userId, int groupId, char *fperm)
+/*
+ * Create file and set permissions, user id, group id.
+ *
+ * If flag is non zero, the file contains #!/PATH/sh shebang otherwise it's
+ * empty.
+ */
+static void testsetup(const char *file_name, int flag, mode_t mode, 
+                      int user_id, int group_id)
 {
-	/* SET CURRENT USER/GROUP PERMISSIONS */
-	if (setegid(groupId)) {
-		tst_brkm(TBROK, cleanup, "could not setegid to %d: %s", groupId, strerror(errno));
-		seteuid(0);
-		setegid(0);
-		return -1;
-	}
-	if (seteuid(userId)) {
-		tst_brkm(TBROK, cleanup, "could not seteuid to %d: %s", userId, strerror(errno));
-		seteuid(0);
-		setegid(0);
-		return -1;
+	FILE *file;
+
+	file = fopen(file_name, "w");
+	
+	if (file == NULL)
+		tst_brkm(TBROK | TERRNO, cleanup,
+		         "Could not create test file %s.", file_name);
+	
+	/* create file with shebang */
+	if (flag) {
+		char buf[MAX_PATH];
+
+		if (tst_get_path("sh", buf, MAX_PATH))
+			tst_brkm(TBROK, cleanup,
+			         "Could not find path to sh in $PATH.");
+
+		if (fprintf(file, "#!%s\n", buf) < 0)
+			tst_brkm(TBROK, cleanup, "Syscall fprintf failed.");
 	}
 
-	switch (tolower(fperm[0])) {
-	case 'x': {
+	if (fclose(file))
+		tst_brkm(TBROK | TERRNO, cleanup, "Syscall fclose failed.");
+
+	if (chmod(file_name, mode))
+		tst_brkm(TBROK | TERRNO, cleanup,
+		         "Could not chmod test file %s.", file_name); 
+
+	if (chown(file_name, user_id, group_id))
+		tst_brkm(TBROK | TERRNO, cleanup,
+		         "Could not chown test file %s.", file_name); 
+}
+
+/*
+ * Test permissions.
+ */
+static int testfperm(const char *file_name, int flag, int user_id,
+                     int group_id, char *fperm)
+
+{
+	FILE *file;
+	int ret;
+	
+	if (setegid(group_id))
+		tst_brkm(TBROK | TERRNO, cleanup, "Could not setegid to %d.",
+		         group_id);
+
+	if (seteuid(user_id))
+		tst_brkm(TBROK | TERRNO, cleanup, "Could not seteuid to %d.",
+		         user_id);
+
+	if (tolower(fperm[0]) == 'x') {
 		int status;
+		
 		if (fork() == 0) {
-			execlp("./test.file", "test.file", NULL);
+			/*
+			 * execlp runs file with sh in case kernel has
+			 * no binmft handler for it, execl does not.
+			 */
+			if (flag)
+				execl(file_name, file_name, NULL);
+			else
+				execlp(file_name, "test", NULL);
+	
 			exit(1);
 		}
+		
 		wait(&status);
+		
 		seteuid(0);
 		setegid(0);
+		
 		return WEXITSTATUS(status);
 	}
-	default: {
-		FILE *testfile;
-		if ((testfile = fopen("test.file", fperm))) {
-			fclose(testfile);
-			seteuid(0);
-			setegid(0);
-			return 0;
-		} else {
-			seteuid(0);
-			setegid(0);
-			return 1;
-		}
-	}
-	}
+
+	if ((file = fopen(file_name, fperm)) != NULL) {
+		fclose(file);
+		ret = 0;
+	} else
+		ret = 1;
+
+	seteuid(0);
+	setegid(0);
+
+	return ret;
+}
+
+static void print_usage(const char *bname)
+{
+	char *usage = "<file mode> <file UID> <file GID> "
+                      "<tester UID> <tester GID> <permission "
+                      "to test r|w|x> <expected result 0|1>";
+
+	printf("Usage: %s %s\n", bname, usage);
 }
 
 int main(int argc, char *argv[])
 {
 	char *fperm;
-	int result, exresult = 0, cuserId = 0, cgroupId = 0, userId = 0, groupId = 0;
+	int exp_res, cuser_id, cgroup_id, user_id, group_id;
+	int res1, res2 = 1;
 	mode_t mode;
 
 	tst_require_root(tst_exit);
 
-	switch (argc) {
-	case 8:
-		mode = strtol(argv[1], (char **)NULL, 010);
-		cuserId = atoi(argv[2]);
-		cgroupId = atoi(argv[3]);
-		userId = atoi(argv[4]);
-		groupId = atoi(argv[5]);
-		fperm = argv[6];
-		exresult = atoi(argv[7]);
-		break;
-	default:
-		printf("Usage: %s <mode of file> <UID of file> <GID of file> <UID of tester> <GID of tester> <permission to test r|w|x> <expected result as 0|1>\n", argv[0]);
-		return 1;
+	if (argc != 8) {
+		print_usage(argv[0]);
+		tst_exit();
 	}
 
-	result = testsetup(mode, cuserId, cgroupId);
-	if (result) {
-		tst_brkm(TBROK, cleanup, "testsetup() failed: %s", strerror(errno));
+	if (strlen(argv[6]) > 1) {
+		print_usage(argv[0]);
+		tst_exit();
 	}
 
-	result = testfperm(userId, groupId, fperm);
-	unlink("test.file");
-	tst_resm(exresult == result ? TPASS : TFAIL, "%c a %03o file owned by (%d/%d) as user/group(%d/%d)",
-		fperm[0], mode, cuserId, cgroupId, userId, groupId);
-	cleanup();
-	return 0;
+	mode      = strtol(argv[1], NULL, 10);
+	cuser_id  = atoi(argv[2]);
+	cgroup_id = atoi(argv[3]);
+	user_id   = atoi(argv[4]);
+	group_id  = atoi(argv[5]);
+	fperm     = argv[6];
+	exp_res   = atoi(argv[7]);
+
+	tst_tmpdir();
+	testsetup(TEST_FILE_NAME1, 0, mode, cuser_id, cgroup_id);
+	
+	/* more tests for 'x' flag */
+	if (tolower(fperm[0]) == 'x') {
+		testsetup(TEST_FILE_NAME2, 1, mode, cuser_id, cgroup_id);
+		res2 = testfperm(TEST_FILE_NAME2, 1, user_id, group_id, fperm);
+
+		if (res2 == exp_res)
+			res2 = 1;
+		else
+			res2 = 0;
+	}
+
+	res1 = testfperm(TEST_FILE_NAME1, 0, user_id, group_id, fperm);
+
+	tst_resm((exp_res == res1) && res2 ? TPASS : TFAIL,
+	         "%c a %03o file owned by (%d/%d) as user/group(%d/%d)",
+	         fperm[0], mode, cuser_id, cgroup_id, user_id, group_id);
+
+	tst_rmdir();
+	tst_exit();
 }
diff --git a/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh b/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh
deleted file mode 100755
index 5a8df8b..0000000
--- a/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/sh
-
-Code=0
-
-test()
-{
-    arg=${1}; shift
-    res=${1}
-
-    ./fs_perms ${arg} ${res}
-    if [ $? -ne 0 ]; then
-       Code=$((Code + 1))
-    fi
-}
-
-test "001 99 99 12 100 x" 0
-test "010 99 99 200 99 x" 0
-test "100 99 99 99 500 x" 0
-test "002 99 99 12 100 w" 0
-test "020 99 99 200 99 w" 0
-test "200 99 99 99 500 w" 0
-test "004 99 99 12 100 r" 0
-test "040 99 99 200 99 r" 0
-test "400 99 99 99 500 r" 0
-test "000 99 99 99 99 r" 1
-test "000 99 99 99 99 w" 1
-test "000 99 99 99 99 x" 1
-test "010 99 99 99 500 x" 1
-test "100 99 99 200 99 x" 1
-test "020 99 99 99 500 w" 1
-test "200 99 99 200 99 w" 1
-test "040 99 99 99 500 r" 1
-test "400 99 99 200 99 r" 1
-
-exit ${Code}
diff --git a/testcases/kernel/fs/fs_perms/testx.c b/testcases/kernel/fs/fs_perms/testx.c
deleted file mode 100644
index 5944ce0..0000000
--- a/testcases/kernel/fs/fs_perms/testx.c
+++ /dev/null
@@ -1,4 +0,0 @@
-#include <stdio.h>
-int main(void) {
-	return 0;
-}

[-- Attachment #3: Type: text/plain, Size: 79 bytes --]

------------------------------------------------------------------------------

[-- Attachment #4: Type: text/plain, Size: 155 bytes --]

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [LTP] [PATCH] fix fs_perms tests
       [not found]       ` <n2s364299f41004231253offfe856amfa09260ba50cf18b@mail.gmail.com>
@ 2010-04-23 20:43         ` Cyril Hrubis
       [not found]           ` <m2i364299f41004231439kbe4017dayfc57d5d8b622a744@mail.gmail.com>
  0 siblings, 1 reply; 10+ messages in thread
From: Cyril Hrubis @ 2010-04-23 20:43 UTC (permalink / raw)
  To: Garrett Cooper; +Cc: ltp-list

Hi!
> 
> 2. MAX_PATH should be PATHNAME_MAX.
>

Hmm, could not find PATHNAME_MAX in my /usr/include/ and it seems that posix
says that this should be determined by fpathconf(). IMHO it is reasonable to
assume that path to sh is shorter than 1023 bytes as it is defined now.

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [LTP] [PATCH] fix fs_perms tests
       [not found]           ` <m2i364299f41004231439kbe4017dayfc57d5d8b622a744@mail.gmail.com>
@ 2010-04-26 13:04             ` Cyril Hrubis
       [not found]               ` <g2o364299f41004260623kb1627f65ld8765f98d8be1790@mail.gmail.com>
  0 siblings, 1 reply; 10+ messages in thread
From: Cyril Hrubis @ 2010-04-26 13:04 UTC (permalink / raw)
  To: Garrett Cooper; +Cc: ltp-list

[-- Attachment #1: Type: text/plain, Size: 107 bytes --]

Hi!
Fixed version attached.

Signed-off-by: Cyril Hrubis chrubis@suse.cz

-- 
Cyril Hrubis
chrubis@suse.cz

[-- Attachment #2: fix_fs_permsIII.patch --]
[-- Type: text/x-patch, Size: 15042 bytes --]

diff --git a/include/test.h b/include/test.h
index e291b36..7ac182a 100644
--- a/include/test.h
+++ b/include/test.h
@@ -262,6 +262,11 @@ int ltp_clone_quick(unsigned long clone_flags, int (*fn)(void *arg),
 char *get_block_device(const char *path);
 char *get_mountpoint(const char *path);
 
+/*
+ * Function from lib/get_path.c
+ */
+int tst_get_path(const char *prog_name, char *buf, size_t buf_len);
+
 #ifdef TST_USE_COMPAT16_SYSCALL
 #define TCID_BIT_SUFFIX "_16"
 #elif  TST_USE_NEWER64_SYSCALL
diff --git a/lib/get_path.c b/lib/get_path.c
new file mode 100644
index 0000000..c82fcea
--- /dev/null
+++ b/lib/get_path.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2010 Cyril Hrubis chrubis@suse.cz
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 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., 59
+ */
+
+ /*
+  * Looks for binary prog_name in $PATH. 
+  *
+  * If such file exists and if you are able at least to read it, zero is
+  * returned and absolute path to the file is filled into buf. In case buf is
+  * too short to hold the absolute path + prog_name for the file we are looking
+  * for -1 is returned as well as when there is no such file in all paths in
+  * $PATH.
+  */
+
+#include "test.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+static int file_exist(const char *path)
+{
+	struct stat st;
+
+	if (!access(path, R_OK) && !stat(path, &st) && S_ISREG(st.st_mode))
+		return 1;
+
+	return 0;
+}
+
+int tst_get_path(const char *prog_name, char *buf, size_t buf_len)
+{
+	const char *path = (const char*) getenv("PATH");
+	int i;
+
+	if (path == NULL)
+		return -1;
+
+	do {
+		/* copy path */
+		for (i = 0; i < buf_len && path[i] != '\0' && path[i] != ':'; i++)
+			buf[i] = path[i];
+		
+		/* add slash at the end if needed */
+		if (buf[i - 1] != '/')
+			buf[i++] = '/';
+
+		/* copy the program name */
+		strncpy(buf + i, prog_name, buf_len - i);
+		
+		/* path + pname fits into buf *
+		 * look if such file exists   */
+		if (buf[buf_len - 1] == '\0') {
+			if (file_exist(buf))
+				return 0;
+		}
+
+		/* eat all to the next delimiter */
+		while (*path != '\0' && *path != ':')
+			path++;
+		
+		/* eat all delimiters */
+		while (*path != '\0' && *path == ':')
+			path++;
+		
+	} while (*path != '\0');
+
+	return -1;
+}
+
diff --git a/runltp b/runltp
index b848a7f..097e32e 100755
--- a/runltp
+++ b/runltp
@@ -557,6 +557,7 @@ main()
 
         for SCENFILES in ${LTPROOT}/runtest/syscalls                \
                          ${LTPROOT}/runtest/fs                      \
+                         ${LTPROOT}/runtest/fs_perms_simple         \
                          ${LTPROOT}/runtest/fsx                     \
                          ${LTPROOT}/runtest/dio                     \
                          ${LTPROOT}/runtest/io                      \
diff --git a/runtest/fs b/runtest/fs
index 75c5e38..2de871d 100644
--- a/runtest/fs
+++ b/runtest/fs
@@ -64,9 +64,6 @@ writetest01	writetest
 #Also run the fs_di (Data Integrity tests)
 fs_di fs_di -d $TMPDIR
 
-#Also run the fs_perms (File System Permission Tests)
-fs_perms fs_perms_simpletest.sh
-
 # Read every file in /proc. Not likely to crash, but does enough 
 # to disturb the kernel. A good kernel latency killer too.
 # Was not sure why it should reside in runtest/crashme and won´t get tested ever
diff --git a/runtest/fs_perms_simple b/runtest/fs_perms_simple
new file mode 100644
index 0000000..cc986bd
--- /dev/null
+++ b/runtest/fs_perms_simple
@@ -0,0 +1,26 @@
+#
+# These tests are setting file permissions/group/uid and are trying to
+# open/write/execute the file.
+#
+#
+#
+# fs_perms file_mode file_uid file_gid test_uid test_gid mode (r|w|x) expected_result
+#
+fs_perms01 fs_perms 001 99 99 12 100 x 0
+fs_perms02 fs_perms 010 99 99 200 99 x 0
+fs_perms03 fs_perms 100 99 99 99 500 x 0
+fs_perms04 fs_perms 002 99 99 12 100 w 0
+fs_perms05 fs_perms 020 99 99 200 99 w 0
+fs_perms06 fs_perms 200 99 99 99 500 w 0
+fs_perms07 fs_perms 004 99 99 12 100 r 0
+fs_perms08 fs_perms 040 99 99 200 99 r 0
+fs_perms09 fs_perms 400 99 99 99 500 r 0
+fs_perms10 fs_perms 000 99 99 99 99  r 1
+fs_perms11 fs_perms 000 99 99 99 99  w 1
+fs_perms12 fs_perms 000 99 99 99 99  x 1
+fs_perms13 fs_perms 010 99 99 99 500 x 1
+fs_perms14 fs_perms 100 99 99 200 99 x 1
+fs_perms15 fs_perms 020 99 99 99 500 w 1
+fs_perms16 fs_perms 200 99 99 200 99 w 1
+fs_perms17 fs_perms 040 99 99 99 500 r 1
+fs_perms18 fs_perms 400 99 99 200 99 r 1
diff --git a/testcases/kernel/fs/fs_perms/Makefile b/testcases/kernel/fs/fs_perms/Makefile
index 48aa7d6..c0377cc 100644
--- a/testcases/kernel/fs/fs_perms/Makefile
+++ b/testcases/kernel/fs/fs_perms/Makefile
@@ -23,7 +23,4 @@
 top_srcdir			?= ../../../..
 
 include $(top_srcdir)/include/mk/testcases.mk
-
-INSTALL_TARGETS			:= fs_perms_simpletest.sh
-
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/fs/fs_perms/fs_perms.c b/testcases/kernel/fs/fs_perms/fs_perms.c
index ad44028..5892f22 100644
--- a/testcases/kernel/fs/fs_perms/fs_perms.c
+++ b/testcases/kernel/fs/fs_perms/fs_perms.c
@@ -1,5 +1,6 @@
 /*
  *   Copyright (c) International Business Machines  Corp., 2000
+ *   Copyright (c) 2010 Cyril Hrubis chrubis@suse.cz
  *
  *   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
@@ -25,9 +26,12 @@
  *     (04/19/01)v1.0  Added test for execute bit.
  *     (05/23/01)v1.1  Added command line parameter to specify test file.
  *     (07/12/01)v1.2  Removed conf file and went to command line parameters.
+ *     (10/19/04)      Rewritten to fit ltp test interface.
+ *                     Also now we try to run two different files, one is executed by execl,
+ *                     has shebang and should end up executed by kernel, other one is empty
+ *                     is executed by execlp and should end up executed by libc.
  */
 
-#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
@@ -36,117 +40,190 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <wait.h>
+#include <linux/limits.h>
 
 #include "test.h"
 
+#define TEST_FILE_NAME1 "./test.file1"
+#define TEST_FILE_NAME2 "./test.file2"
+
 char *TCID = "fs_perms";
 int TST_TOTAL = 1;
 
-static int testsetup(mode_t mode, int cuserId, int cgroupId)
-{
-	int ret;
-	char cmd_str[256];
-
-	sprintf(cmd_str, "cp %s/testx test.file", getcwd(NULL, 0));
-	tst_tmpdir();
-
-	ret = unlink("test.file");
-	if (ret && errno != ENOENT)
-		goto done;
-	ret = system(cmd_str);
-	if (ret)
-		goto done;
-	ret = chmod("test.file", mode);
-	if (ret)
-		goto done;
-	ret = chown("test.file", cuserId, cgroupId);
-
- done:
-	return ret;
-}
-
-void cleanup(void)
+static void cleanup(void)
 {
+	seteuid(0);
+	setegid(0);
+	
 	tst_rmdir();
 	tst_exit();
 }
 
-static int testfperm(int userId, int groupId, char *fperm)
+/*
+ * Create file and set permissions, user id, group id.
+ *
+ * If flag is non zero, the file contains #!/PATH/sh shebang otherwise it's
+ * empty.
+ */
+static void testsetup(const char *file_name, int flag, mode_t mode, 
+                      int user_id, int group_id)
 {
-	/* SET CURRENT USER/GROUP PERMISSIONS */
-	if (setegid(groupId)) {
-		tst_brkm(TBROK, cleanup, "could not setegid to %d: %s", groupId, strerror(errno));
-		seteuid(0);
-		setegid(0);
-		return -1;
-	}
-	if (seteuid(userId)) {
-		tst_brkm(TBROK, cleanup, "could not seteuid to %d: %s", userId, strerror(errno));
-		seteuid(0);
-		setegid(0);
-		return -1;
+	FILE *file;
+
+	file = fopen(file_name, "w");
+	
+	if (file == NULL)
+		tst_brkm(TBROK | TERRNO, cleanup,
+		         "Could not create test file %s.", file_name);
+	
+	/* create file with shebang */
+	if (flag) {
+		char buf[PATH_MAX];
+
+		if (tst_get_path("sh", buf, PATH_MAX))
+			tst_brkm(TBROK, cleanup,
+			         "Could not find path to sh in $PATH.");
+
+		if (fprintf(file, "#!%s\n", buf) < 0)
+			tst_brkm(TBROK, cleanup, "Calling fprintf failed.");
 	}
 
-	switch (tolower(fperm[0])) {
-	case 'x': {
+	if (fclose(file))
+		tst_brkm(TBROK | TERRNO, cleanup, "Calling fclose failed.");
+
+	if (chmod(file_name, mode))
+		tst_brkm(TBROK | TERRNO, cleanup,
+		         "Could not chmod test file %s.", file_name); 
+
+	if (chown(file_name, user_id, group_id))
+		tst_brkm(TBROK | TERRNO, cleanup,
+		         "Could not chown test file %s.", file_name); 
+}
+
+/*
+ * Test permissions.
+ */
+static int testfperm(const char *file_name, int flag, int user_id,
+                     int group_id, char *fperm)
+
+{
+	FILE *file;
+	int ret;
+	
+	if (setegid(group_id))
+		tst_brkm(TBROK | TERRNO, cleanup, "Could not setegid to %d.",
+		         group_id);
+
+	if (seteuid(user_id))
+		tst_brkm(TBROK | TERRNO, cleanup, "Could not seteuid to %d.",
+		         user_id);
+
+	if (tolower(fperm[0]) == 'x') {
 		int status;
+		
 		if (fork() == 0) {
-			execlp("./test.file", "test.file", NULL);
+			/*
+			 * execlp runs file with sh in case kernel has
+			 * no binmft handler for it, execl does not.
+			 */
+			if (flag)
+				execl(file_name, file_name, NULL);
+			else
+				execlp(file_name, "test", NULL);
+	
 			exit(1);
 		}
+		
 		wait(&status);
+		
 		seteuid(0);
 		setegid(0);
+		
 		return WEXITSTATUS(status);
 	}
-	default: {
-		FILE *testfile;
-		if ((testfile = fopen("test.file", fperm))) {
-			fclose(testfile);
-			seteuid(0);
-			setegid(0);
-			return 0;
-		} else {
-			seteuid(0);
-			setegid(0);
-			return 1;
-		}
-	}
-	}
+
+	if ((file = fopen(file_name, fperm)) != NULL) {
+		fclose(file);
+		ret = 0;
+	} else
+		ret = 1;
+
+	seteuid(0);
+	setegid(0);
+
+	return ret;
+}
+
+static void print_usage(const char *bname)
+{
+	char *usage = "<file mode> <file UID> <file GID> "
+                      "<tester UID> <tester GID> <permission "
+                      "to test r|w|x> <expected result 0|1>";
+
+	printf("Usage: %s %s\n", bname, usage);
+}
+
+static long str_to_l(const char *str, const char *name)
+{
+	char *end;
+	long i = strtol(str, &end, 10);
+
+	if (*end != '\0')
+		tst_brkm(TBROK, tst_exit, "Invalid parameter '%s' passed. (%s)",
+		         name, str);
+
+	return i;
 }
 
 int main(int argc, char *argv[])
 {
 	char *fperm;
-	int result, exresult = 0, cuserId = 0, cgroupId = 0, userId = 0, groupId = 0;
-	mode_t mode;
+	gid_t fgroup_id, group_id;
+	uid_t fuser_id, user_id;
+	mode_t fmode;
+	int exp_res;
+	int res1, res2 = 1;
 
 	tst_require_root(tst_exit);
 
-	switch (argc) {
-	case 8:
-		mode = strtol(argv[1], (char **)NULL, 010);
-		cuserId = atoi(argv[2]);
-		cgroupId = atoi(argv[3]);
-		userId = atoi(argv[4]);
-		groupId = atoi(argv[5]);
-		fperm = argv[6];
-		exresult = atoi(argv[7]);
-		break;
-	default:
-		printf("Usage: %s <mode of file> <UID of file> <GID of file> <UID of tester> <GID of tester> <permission to test r|w|x> <expected result as 0|1>\n", argv[0]);
-		return 1;
+	if (argc != 8) {
+		print_usage(argv[0]);
+		tst_exit();
 	}
 
-	result = testsetup(mode, cuserId, cgroupId);
-	if (result) {
-		tst_brkm(TBROK, cleanup, "testsetup() failed: %s", strerror(errno));
+	if (strlen(argv[6]) > 1) {
+		print_usage(argv[0]);
+		tst_exit();
 	}
 
-	result = testfperm(userId, groupId, fperm);
-	unlink("test.file");
-	tst_resm(exresult == result ? TPASS : TFAIL, "%c a %03o file owned by (%d/%d) as user/group(%d/%d)",
-		fperm[0], mode, cuserId, cgroupId, userId, groupId);
-	cleanup();
-	return 0;
+	fmode     = str_to_l(argv[1], "file mode");
+	fuser_id  = str_to_l(argv[2], "file uid");
+	fgroup_id = str_to_l(argv[3], "file gid");
+	user_id   = str_to_l(argv[4], "tester uid");
+	group_id  = str_to_l(argv[5], "tester gid");
+	fperm     = argv[6];
+	exp_res   = str_to_l(argv[7], "expected result");
+
+	tst_tmpdir();
+	testsetup(TEST_FILE_NAME1, 0, fmode, fuser_id, fgroup_id);
+	
+	/* more tests for 'x' flag */
+	if (tolower(fperm[0]) == 'x') {
+		testsetup(TEST_FILE_NAME2, 1, fmode, fuser_id, fgroup_id);
+		res2 = testfperm(TEST_FILE_NAME2, 1, user_id, group_id, fperm);
+
+		if (res2 == exp_res)
+			res2 = 1;
+		else
+			res2 = 0;
+	}
+
+	res1 = testfperm(TEST_FILE_NAME1, 0, user_id, group_id, fperm);
+
+	tst_resm((exp_res == res1) && res2 ? TPASS : TFAIL,
+	         "%c a %03o file owned by (%d/%d) as user/group (%d/%d)",
+	         fperm[0], fmode, fuser_id, fgroup_id, user_id, group_id);
+
+	tst_rmdir();
+	tst_exit();
 }
diff --git a/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh b/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh
deleted file mode 100755
index 5a8df8b..0000000
--- a/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/sh
-
-Code=0
-
-test()
-{
-    arg=${1}; shift
-    res=${1}
-
-    ./fs_perms ${arg} ${res}
-    if [ $? -ne 0 ]; then
-       Code=$((Code + 1))
-    fi
-}
-
-test "001 99 99 12 100 x" 0
-test "010 99 99 200 99 x" 0
-test "100 99 99 99 500 x" 0
-test "002 99 99 12 100 w" 0
-test "020 99 99 200 99 w" 0
-test "200 99 99 99 500 w" 0
-test "004 99 99 12 100 r" 0
-test "040 99 99 200 99 r" 0
-test "400 99 99 99 500 r" 0
-test "000 99 99 99 99 r" 1
-test "000 99 99 99 99 w" 1
-test "000 99 99 99 99 x" 1
-test "010 99 99 99 500 x" 1
-test "100 99 99 200 99 x" 1
-test "020 99 99 99 500 w" 1
-test "200 99 99 200 99 w" 1
-test "040 99 99 99 500 r" 1
-test "400 99 99 200 99 r" 1
-
-exit ${Code}
diff --git a/testcases/kernel/fs/fs_perms/testx.c b/testcases/kernel/fs/fs_perms/testx.c
deleted file mode 100644
index 5944ce0..0000000
--- a/testcases/kernel/fs/fs_perms/testx.c
+++ /dev/null
@@ -1,4 +0,0 @@
-#include <stdio.h>
-int main(void) {
-	return 0;
-}

[-- Attachment #3: Type: text/plain, Size: 79 bytes --]

------------------------------------------------------------------------------

[-- Attachment #4: Type: text/plain, Size: 155 bytes --]

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [LTP] [PATCH] fix fs_perms tests
       [not found]               ` <g2o364299f41004260623kb1627f65ld8765f98d8be1790@mail.gmail.com>
@ 2010-04-26 14:04                 ` Cyril Hrubis
       [not found]                   ` <u2n364299f41004261925z2722bfb1j62b19d010fd52513@mail.gmail.com>
  0 siblings, 1 reply; 10+ messages in thread
From: Cyril Hrubis @ 2010-04-26 14:04 UTC (permalink / raw)
  To: Garrett Cooper; +Cc: ltp-list

Hi!
> 2. Why do you feel this is required?

Well, accordingly to POSIX you can't realy rely on having /bin/sh or even
/usr/bin/sh. On the other hand I haven't seen any linux system that has no
/bin/sh. And accordingly to FSH /bin/sh is required to exist. So this really
depends on how much we want to be compatible with POSIX and strange unixes out
there (if there are any).

* FSH http://www.pathname.com/fhs/
* POSIX http://www.opengroup.org/onlinepubs/000095399/utilities/sh.html
        (paragraph "application usage")

> 3. This should really be a single snprintf call:
> 
> +		/* copy path */
> +		for (i = 0; i < buf_len && path[i] != '\0' && path[i] != ':'; i++)
> +			buf[i] = path[i];
> +
> +		/* add slash at the end if needed */
> +		if (buf[i - 1] != '/')
> +			buf[i++] = '/';
> +		/* copy the program name */
> +		strncpy(buf + i, prog_name, buf_len - i);
> 
>     similar to the following:
> 
> if (snprintf(buf, buf_len, "%s/%s", path_element, prog_name) > buf_len)
>     /* error out */
> else if (file_exist(buf))
>     return 0; /* etc... */
> /* ... */

This way I would need either to copy the path element into temporary
path_element[] array each time before snprintf is called or duplicate the
string returned by getenv("PATH") so that I could insert '\0' in it.

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [LTP] [PATCH] fix fs_perms tests
       [not found]                   ` <u2n364299f41004261925z2722bfb1j62b19d010fd52513@mail.gmail.com>
@ 2010-05-13 14:17                     ` Cyril Hrubis
       [not found]                       ` <1274126766.5106.16.camel@subratamodak.linux.ibm.com>
  0 siblings, 1 reply; 10+ messages in thread
From: Cyril Hrubis @ 2010-05-13 14:17 UTC (permalink / raw)
  To: Garrett Cooper; +Cc: ltp-list

[-- Attachment #1: Type: text/plain, Size: 136 bytes --]

Hi!
Hope that this version is final. See attached patch.

Signed-off-by: Cyril Hrubis chrubis@suse.cz

-- 
Cyril Hrubis
chrubis@suse.cz

[-- Attachment #2: fix_fs_permsIV.patch --]
[-- Type: text/x-patch, Size: 15290 bytes --]

diff --git a/include/test.h b/include/test.h
index e291b36..7ac182a 100644
--- a/include/test.h
+++ b/include/test.h
@@ -262,6 +262,11 @@ int ltp_clone_quick(unsigned long clone_flags, int (*fn)(void *arg),
 char *get_block_device(const char *path);
 char *get_mountpoint(const char *path);
 
+/*
+ * Function from lib/get_path.c
+ */
+int tst_get_path(const char *prog_name, char *buf, size_t buf_len);
+
 #ifdef TST_USE_COMPAT16_SYSCALL
 #define TCID_BIT_SUFFIX "_16"
 #elif  TST_USE_NEWER64_SYSCALL
diff --git a/lib/get_path.c b/lib/get_path.c
new file mode 100644
index 0000000..89334a8
--- /dev/null
+++ b/lib/get_path.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 Cyril Hrubis chrubis@suse.cz
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 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., 59
+ */
+
+ /*
+  * Looks for binary prog_name in $PATH. 
+  *
+  * If such file exists and if you are able at least to read it, zero is
+  * returned and absolute path to the file is filled into buf. In case buf is
+  * too short to hold the absolute path + prog_name for the file we are looking
+  * for -1 is returned as well as when there is no such file in all paths in
+  * $PATH.
+  */
+
+#include "test.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define MIN(a, b) ((a)<(b)?(a):(b))
+
+static int file_exist(const char *path)
+{
+	struct stat st;
+
+	if (!access(path, R_OK) && !stat(path, &st) && S_ISREG(st.st_mode))
+		return 1;
+
+	return 0;
+}
+
+int tst_get_path(const char *prog_name, char *buf, size_t buf_len)
+{
+	const char *path = (const char*) getenv("PATH");
+	const char *start = path;
+	const char *end;
+	size_t size, ret;
+
+
+	if (path == NULL)
+		return -1;
+
+	do {
+		end = strchr(start, ':');
+
+		if (end != NULL)
+			snprintf(buf, MIN(buf_len, (size_t)(end - start + 1)), "%s", start);
+		else
+			snprintf(buf, buf_len, "%s", start);
+
+		size = strlen(buf);
+
+		/*
+		 * "::" inside $PATH, $PATH ending with ':' or $PATH strarting
+		 * with ':' should be expanded into current working directory.
+		 */
+		if (size == 0) {
+			snprintf(buf, buf_len, ".");
+			size = strlen(buf);
+		}
+
+		/*
+		 * If there is no '/' ad the end of path from $PATH add it.
+		 */
+		if (buf[size - 1] != '/')
+			ret = snprintf(buf + size, buf_len - size, "/%s", prog_name);
+		else
+			ret = snprintf(buf + size, buf_len - size, "%s", prog_name);
+
+		if (buf_len - size > ret && file_exist(buf))
+			return 0;
+
+		start = end + 1;
+
+	} while (end != NULL);
+
+	return -1;
+}
diff --git a/runltp b/runltp
index 07994e9..7a8ac28 100755
--- a/runltp
+++ b/runltp
@@ -570,6 +570,7 @@ main()
 
         for SCENFILES in ${LTPROOT}/runtest/syscalls                \
                          ${LTPROOT}/runtest/fs                      \
+                         ${LTPROOT}/runtest/fs_perms_simple         \
                          ${LTPROOT}/runtest/fsx                     \
                          ${LTPROOT}/runtest/dio                     \
                          ${LTPROOT}/runtest/io                      \
diff --git a/runtest/fs b/runtest/fs
index 75c5e38..2de871d 100644
--- a/runtest/fs
+++ b/runtest/fs
@@ -64,9 +64,6 @@ writetest01	writetest
 #Also run the fs_di (Data Integrity tests)
 fs_di fs_di -d $TMPDIR
 
-#Also run the fs_perms (File System Permission Tests)
-fs_perms fs_perms_simpletest.sh
-
 # Read every file in /proc. Not likely to crash, but does enough 
 # to disturb the kernel. A good kernel latency killer too.
 # Was not sure why it should reside in runtest/crashme and won´t get tested ever
diff --git a/runtest/fs_perms_simple b/runtest/fs_perms_simple
new file mode 100644
index 0000000..cc986bd
--- /dev/null
+++ b/runtest/fs_perms_simple
@@ -0,0 +1,26 @@
+#
+# These tests are setting file permissions/group/uid and are trying to
+# open/write/execute the file.
+#
+#
+#
+# fs_perms file_mode file_uid file_gid test_uid test_gid mode (r|w|x) expected_result
+#
+fs_perms01 fs_perms 001 99 99 12 100 x 0
+fs_perms02 fs_perms 010 99 99 200 99 x 0
+fs_perms03 fs_perms 100 99 99 99 500 x 0
+fs_perms04 fs_perms 002 99 99 12 100 w 0
+fs_perms05 fs_perms 020 99 99 200 99 w 0
+fs_perms06 fs_perms 200 99 99 99 500 w 0
+fs_perms07 fs_perms 004 99 99 12 100 r 0
+fs_perms08 fs_perms 040 99 99 200 99 r 0
+fs_perms09 fs_perms 400 99 99 99 500 r 0
+fs_perms10 fs_perms 000 99 99 99 99  r 1
+fs_perms11 fs_perms 000 99 99 99 99  w 1
+fs_perms12 fs_perms 000 99 99 99 99  x 1
+fs_perms13 fs_perms 010 99 99 99 500 x 1
+fs_perms14 fs_perms 100 99 99 200 99 x 1
+fs_perms15 fs_perms 020 99 99 99 500 w 1
+fs_perms16 fs_perms 200 99 99 200 99 w 1
+fs_perms17 fs_perms 040 99 99 99 500 r 1
+fs_perms18 fs_perms 400 99 99 200 99 r 1
diff --git a/testcases/kernel/fs/fs_perms/Makefile b/testcases/kernel/fs/fs_perms/Makefile
index 48aa7d6..c0377cc 100644
--- a/testcases/kernel/fs/fs_perms/Makefile
+++ b/testcases/kernel/fs/fs_perms/Makefile
@@ -23,7 +23,4 @@
 top_srcdir			?= ../../../..
 
 include $(top_srcdir)/include/mk/testcases.mk
-
-INSTALL_TARGETS			:= fs_perms_simpletest.sh
-
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/fs/fs_perms/fs_perms.c b/testcases/kernel/fs/fs_perms/fs_perms.c
index ad44028..9fbe9ec 100644
--- a/testcases/kernel/fs/fs_perms/fs_perms.c
+++ b/testcases/kernel/fs/fs_perms/fs_perms.c
@@ -1,5 +1,6 @@
 /*
  *   Copyright (c) International Business Machines  Corp., 2000
+ *   Copyright (c) 2010 Cyril Hrubis chrubis@suse.cz
  *
  *   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
@@ -25,9 +26,12 @@
  *     (04/19/01)v1.0  Added test for execute bit.
  *     (05/23/01)v1.1  Added command line parameter to specify test file.
  *     (07/12/01)v1.2  Removed conf file and went to command line parameters.
+ *     (10/19/04)      Rewritten to fit ltp test interface.
+ *                     Also now we try to run two different files, one is executed by execl,
+ *                     has shebang and should end up executed by kernel, other one is empty
+ *                     is executed by execlp and should end up executed by libc.
  */
 
-#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
@@ -36,117 +40,190 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <wait.h>
+#include <linux/limits.h>
 
 #include "test.h"
 
+#define TEST_FILE_NAME1 "./test.file1"
+#define TEST_FILE_NAME2 "./test.file2"
+
 char *TCID = "fs_perms";
 int TST_TOTAL = 1;
 
-static int testsetup(mode_t mode, int cuserId, int cgroupId)
-{
-	int ret;
-	char cmd_str[256];
-
-	sprintf(cmd_str, "cp %s/testx test.file", getcwd(NULL, 0));
-	tst_tmpdir();
-
-	ret = unlink("test.file");
-	if (ret && errno != ENOENT)
-		goto done;
-	ret = system(cmd_str);
-	if (ret)
-		goto done;
-	ret = chmod("test.file", mode);
-	if (ret)
-		goto done;
-	ret = chown("test.file", cuserId, cgroupId);
-
- done:
-	return ret;
-}
-
-void cleanup(void)
+static void cleanup(void)
 {
+	seteuid(0);
+	setegid(0);
+	
 	tst_rmdir();
 	tst_exit();
 }
 
-static int testfperm(int userId, int groupId, char *fperm)
+/*
+ * Create file and set permissions, user id, group id.
+ *
+ * If flag is non zero, the file contains #!/PATH/sh shebang otherwise it's
+ * empty.
+ */
+static void testsetup(const char *file_name, int flag, mode_t mode, 
+                      int user_id, int group_id)
 {
-	/* SET CURRENT USER/GROUP PERMISSIONS */
-	if (setegid(groupId)) {
-		tst_brkm(TBROK, cleanup, "could not setegid to %d: %s", groupId, strerror(errno));
-		seteuid(0);
-		setegid(0);
-		return -1;
-	}
-	if (seteuid(userId)) {
-		tst_brkm(TBROK, cleanup, "could not seteuid to %d: %s", userId, strerror(errno));
-		seteuid(0);
-		setegid(0);
-		return -1;
+	FILE *file;
+
+	file = fopen(file_name, "w");
+	
+	if (file == NULL)
+		tst_brkm(TBROK | TERRNO, cleanup,
+		         "Could not create test file %s.", file_name);
+	
+	/* create file with shebang */
+	if (flag) {
+		char buf[PATH_MAX];
+
+		if (tst_get_path("sh", buf, PATH_MAX))
+			tst_brkm(TBROK, cleanup,
+			         "Could not find path to sh in $PATH.");
+
+		if (fprintf(file, "#!%s\n", buf) < 0)
+			tst_brkm(TBROK, cleanup, "Calling fprintf failed.");
 	}
 
-	switch (tolower(fperm[0])) {
-	case 'x': {
+	if (fclose(file))
+		tst_brkm(TBROK | TERRNO, cleanup, "Calling fclose failed.");
+
+	if (chmod(file_name, mode))
+		tst_brkm(TBROK | TERRNO, cleanup,
+		         "Could not chmod test file %s.", file_name); 
+
+	if (chown(file_name, user_id, group_id))
+		tst_brkm(TBROK | TERRNO, cleanup,
+		         "Could not chown test file %s.", file_name); 
+}
+
+/*
+ * Test permissions.
+ */
+static int testfperm(const char *file_name, int flag, int user_id,
+                     int group_id, char *fperm)
+
+{
+	FILE *file;
+	int ret;
+	
+	if (setegid(group_id))
+		tst_brkm(TBROK | TERRNO, cleanup, "Could not setegid to %d.",
+		         group_id);
+
+	if (seteuid(user_id))
+		tst_brkm(TBROK | TERRNO, cleanup, "Could not seteuid to %d.",
+		         user_id);
+
+	if (tolower(fperm[0]) == 'x') {
 		int status;
+		
 		if (fork() == 0) {
-			execlp("./test.file", "test.file", NULL);
+			/*
+			 * execlp runs file with sh in case kernel has
+			 * no binmft handler for it, execl does not.
+			 */
+			if (flag)
+				execl(file_name, file_name, NULL);
+			else
+				execlp(file_name, "test", NULL);
+	
 			exit(1);
 		}
+		
 		wait(&status);
+		
 		seteuid(0);
 		setegid(0);
+		
 		return WEXITSTATUS(status);
 	}
-	default: {
-		FILE *testfile;
-		if ((testfile = fopen("test.file", fperm))) {
-			fclose(testfile);
-			seteuid(0);
-			setegid(0);
-			return 0;
-		} else {
-			seteuid(0);
-			setegid(0);
-			return 1;
-		}
-	}
-	}
+
+	if ((file = fopen(file_name, fperm)) != NULL) {
+		fclose(file);
+		ret = 0;
+	} else
+		ret = 1;
+
+	seteuid(0);
+	setegid(0);
+
+	return ret;
+}
+
+static void print_usage(const char *bname)
+{
+	char *usage = "<file mode> <file UID> <file GID> "
+                      "<tester UID> <tester GID> <permission "
+                      "to test r|w|x> <expected result 0|1>";
+
+	printf("Usage: %s %s\n", bname, usage);
+}
+
+static long str_to_l(const char *str, const char *name)
+{
+	char *end;
+	long i = strtol(str, &end, 10);
+
+	if (*end != '\0')
+		tst_brkm(TBROK, tst_exit, "Invalid parameter '%s' passed. (%s)",
+		         name, str);
+
+	return i;
 }
 
 int main(int argc, char *argv[])
 {
 	char *fperm;
-	int result, exresult = 0, cuserId = 0, cgroupId = 0, userId = 0, groupId = 0;
-	mode_t mode;
+	gid_t fgroup_id, group_id;
+	uid_t fuser_id, user_id;
+	mode_t fmode;
+	int exp_res;
+	int res1, res2 = 1;
 
 	tst_require_root(tst_exit);
 
-	switch (argc) {
-	case 8:
-		mode = strtol(argv[1], (char **)NULL, 010);
-		cuserId = atoi(argv[2]);
-		cgroupId = atoi(argv[3]);
-		userId = atoi(argv[4]);
-		groupId = atoi(argv[5]);
-		fperm = argv[6];
-		exresult = atoi(argv[7]);
-		break;
-	default:
-		printf("Usage: %s <mode of file> <UID of file> <GID of file> <UID of tester> <GID of tester> <permission to test r|w|x> <expected result as 0|1>\n", argv[0]);
-		return 1;
+	if (argc != 8) {
+		print_usage(argv[0]);
+		tst_exit();
 	}
 
-	result = testsetup(mode, cuserId, cgroupId);
-	if (result) {
-		tst_brkm(TBROK, cleanup, "testsetup() failed: %s", strerror(errno));
+	if (strlen(argv[6]) > 1) {
+		print_usage(argv[0]);
+		tst_exit();
 	}
 
-	result = testfperm(userId, groupId, fperm);
-	unlink("test.file");
-	tst_resm(exresult == result ? TPASS : TFAIL, "%c a %03o file owned by (%d/%d) as user/group(%d/%d)",
-		fperm[0], mode, cuserId, cgroupId, userId, groupId);
-	cleanup();
-	return 0;
+	fmode     = str_to_l(argv[1], "file mode");
+	fuser_id  = str_to_l(argv[2], "file uid");
+	fgroup_id = str_to_l(argv[3], "file gid");
+	user_id   = str_to_l(argv[4], "tester uid");
+	group_id  = str_to_l(argv[5], "tester gid");
+	fperm     = argv[6];
+	exp_res   = str_to_l(argv[7], "expected result");
+
+	tst_tmpdir();
+	testsetup(TEST_FILE_NAME1, 0, fmode, fuser_id, fgroup_id);
+	
+	/* more tests for 'x' flag */
+	if (tolower(fperm[0]) == 'x') {
+		testsetup(TEST_FILE_NAME2, 1, fmode, fuser_id, fgroup_id);
+		res2 = testfperm(TEST_FILE_NAME2, 1, user_id, group_id, fperm);
+
+		if (res2 == exp_res)
+			res2 = 1;
+		else
+			res2 = 0;
+	}
+
+	res1 = testfperm(TEST_FILE_NAME1, 0, user_id, group_id, fperm);
+
+	tst_resm((exp_res == res1) && res2 ? TPASS : TFAIL,
+	         "%c a %03o file owned by (%d/%d) as user/group (%d/%d)",
+	         fperm[0], fmode, fuser_id, fgroup_id, user_id, group_id);
+
+	tst_rmdir();
+	tst_exit();
 }
diff --git a/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh b/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh
deleted file mode 100755
index 5a8df8b..0000000
--- a/testcases/kernel/fs/fs_perms/fs_perms_simpletest.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/sh
-
-Code=0
-
-test()
-{
-    arg=${1}; shift
-    res=${1}
-
-    ./fs_perms ${arg} ${res}
-    if [ $? -ne 0 ]; then
-       Code=$((Code + 1))
-    fi
-}
-
-test "001 99 99 12 100 x" 0
-test "010 99 99 200 99 x" 0
-test "100 99 99 99 500 x" 0
-test "002 99 99 12 100 w" 0
-test "020 99 99 200 99 w" 0
-test "200 99 99 99 500 w" 0
-test "004 99 99 12 100 r" 0
-test "040 99 99 200 99 r" 0
-test "400 99 99 99 500 r" 0
-test "000 99 99 99 99 r" 1
-test "000 99 99 99 99 w" 1
-test "000 99 99 99 99 x" 1
-test "010 99 99 99 500 x" 1
-test "100 99 99 200 99 x" 1
-test "020 99 99 99 500 w" 1
-test "200 99 99 200 99 w" 1
-test "040 99 99 99 500 r" 1
-test "400 99 99 200 99 r" 1
-
-exit ${Code}
diff --git a/testcases/kernel/fs/fs_perms/testx.c b/testcases/kernel/fs/fs_perms/testx.c
deleted file mode 100644
index 5944ce0..0000000
--- a/testcases/kernel/fs/fs_perms/testx.c
+++ /dev/null
@@ -1,4 +0,0 @@
-#include <stdio.h>
-int main(void) {
-	return 0;
-}

[-- Attachment #3: Type: text/plain, Size: 80 bytes --]

------------------------------------------------------------------------------


[-- Attachment #4: Type: text/plain, Size: 155 bytes --]

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [LTP] [PATCH] fix fs_perms tests
       [not found]                       ` <1274126766.5106.16.camel@subratamodak.linux.ibm.com>
@ 2010-05-27 17:03                         ` Cyril Hrubis
       [not found]                           ` <1275031961.5418.25.camel@subratamodak.linux.ibm.com>
  0 siblings, 1 reply; 10+ messages in thread
From: Cyril Hrubis @ 2010-05-27 17:03 UTC (permalink / raw)
  To: Subrata Modak; +Cc: ltp-list

Hi!
> 
> Thanks.
> 

It seems like file runtest/fs_perms_simple doesn't made it into ltp-dev git
tree (also it seems to be included in the patch).

see:

http://ltp.git.sourceforge.net/git/gitweb.cgi?p=ltp/ltp-dev.git;a=commit;h=ca758b73afff8200df5e1a24e9abe8a6468c9e06

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [LTP] [PATCH] fix fs_perms tests
       [not found]                           ` <1275031961.5418.25.camel@subratamodak.linux.ibm.com>
@ 2010-06-03 12:07                             ` Cyril Hrubis
  0 siblings, 0 replies; 10+ messages in thread
From: Cyril Hrubis @ 2010-06-03 12:07 UTC (permalink / raw)
  To: Subrata Modak; +Cc: ltp-list

Hi!
> > It seems like file runtest/fs_perms_simple doesn't made it into ltp-dev git
> > tree (also it seems to be included in the patch).
> 
> Sorry, i noticed it now and added it immediately. Let me know if you can
> see it :-)

Seems to be fixed now. Thanks!

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
ThinkGeek and WIRED's GeekDad team up for the Ultimate 
GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the 
lucky parental unit.  See the prize list and enter to win: 
http://p.sf.net/sfu/thinkgeek-promo
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2010-06-03 11:56 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-02 18:59 [LTP] [PATCH] fix fs_perms tests Cyril Hrubis
     [not found] ` <g2x364299f41004021212z6e85833ybccad62e6780ec26@mail.gmail.com>
2010-04-08 15:48   ` Cyril Hrubis
2010-04-19 18:41   ` Cyril Hrubis
2010-04-23 12:53     ` Cyril Hrubis
     [not found]       ` <n2s364299f41004231253offfe856amfa09260ba50cf18b@mail.gmail.com>
2010-04-23 20:43         ` Cyril Hrubis
     [not found]           ` <m2i364299f41004231439kbe4017dayfc57d5d8b622a744@mail.gmail.com>
2010-04-26 13:04             ` Cyril Hrubis
     [not found]               ` <g2o364299f41004260623kb1627f65ld8765f98d8be1790@mail.gmail.com>
2010-04-26 14:04                 ` Cyril Hrubis
     [not found]                   ` <u2n364299f41004261925z2722bfb1j62b19d010fd52513@mail.gmail.com>
2010-05-13 14:17                     ` Cyril Hrubis
     [not found]                       ` <1274126766.5106.16.camel@subratamodak.linux.ibm.com>
2010-05-27 17:03                         ` Cyril Hrubis
     [not found]                           ` <1275031961.5418.25.camel@subratamodak.linux.ibm.com>
2010-06-03 12:07                             ` Cyril Hrubis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.