summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2011-03-09 22:39:10 +0000
committerpjd <pjd@FreeBSD.org>2011-03-09 22:39:10 +0000
commit7d5541f691c2d9dfe361a513cc553fef55089903 (patch)
tree9c531f195426d3ab376508e617cf5d40d96cc44c /tools
parent21e47fa1c9740702dcb4dc6dde3f25e61f2d6fa7 (diff)
downloadFreeBSD-src-7d5541f691c2d9dfe361a513cc553fef55089903.zip
FreeBSD-src-7d5541f691c2d9dfe361a513cc553fef55089903.tar.gz
Add support for the following syscalls:
- fchmod(2), - fchown(2), - fchflags(2), - fstat(2), - ftruncate(2), - fpathconf(2), - lpathconf(2). Make write(2) syscall to take descriptor instead of file name. We implement descriptors by keeping track of open files and allowing to reference them by the following syscalls. Because pjdfstest already supports executing multiple syscalls from one command it works pretty well. For example, the following command: pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444 is equivalent of (error checking omitted): int fd[2]; fd[0] = open("foo", O_CREAT | O_RDWR, 0); fd[1] = open("bar", O_CREAT | O_RDONLY, 0640); fchmod(fd[0], 0666); fchown(fd[0], -1, 20); fchmod(fd[1], 0444);
Diffstat (limited to 'tools')
-rw-r--r--tools/regression/pjdfstest/Makefile2
-rw-r--r--tools/regression/pjdfstest/pjdfstest.c101
-rw-r--r--tools/regression/pjdfstest/tests/chmod/12.t4
3 files changed, 94 insertions, 13 deletions
diff --git a/tools/regression/pjdfstest/Makefile b/tools/regression/pjdfstest/Makefile
index 3764aa9..ca789fe 100644
--- a/tools/regression/pjdfstest/Makefile
+++ b/tools/regression/pjdfstest/Makefile
@@ -6,7 +6,7 @@ ${PROG}: ${PROG}.c
@OSTYPE=`uname`; \
CFLAGS=-D__OS_$${OSTYPE}__; \
if [ $$OSTYPE = "FreeBSD" ]; then \
- CFLAGS="$$CFLAGS -DHAS_LCHMOD -DHAS_CHFLAGS -DHAS_LCHFLAGS -DHAS_FREEBSD_ACL"; \
+ CFLAGS="$$CFLAGS -DHAS_LCHMOD -DHAS_CHFLAGS -DHAS_FCHFLAGS -DHAS_LCHFLAGS -DHAS_FREEBSD_ACL"; \
elif [ $$OSTYPE = "SunOS" ]; then \
CFLAGS="$$CFLAGS -DHAS_TRUNCATE64 -DHAS_STAT64"; \
CFLAGS="$$CFLAGS -lsocket"; \
diff --git a/tools/regression/pjdfstest/pjdfstest.c b/tools/regression/pjdfstest/pjdfstest.c
index b6a3c09..9c4ec1d 100644
--- a/tools/regression/pjdfstest/pjdfstest.c
+++ b/tools/regression/pjdfstest/pjdfstest.c
@@ -47,9 +47,11 @@
#ifndef HAS_TRUNCATE64
#define truncate64 truncate
+#define ftruncate64 ftruncate
#endif
#ifndef HAS_STAT64
#define stat64 stat
+#define fstat64 fstat
#define lstat64 lstat
#endif
#ifdef HAS_FREEBSD_ACL
@@ -74,21 +76,30 @@ enum action {
ACTION_BIND,
ACTION_CONNECT,
ACTION_CHMOD,
+ ACTION_FCHMOD,
#ifdef HAS_LCHMOD
ACTION_LCHMOD,
#endif
ACTION_CHOWN,
+ ACTION_FCHOWN,
ACTION_LCHOWN,
#ifdef HAS_CHFLAGS
ACTION_CHFLAGS,
#endif
+#ifdef HAS_FCHFLAGS
+ ACTION_FCHFLAGS,
+#endif
#ifdef HAS_LCHFLAGS
ACTION_LCHFLAGS,
#endif
ACTION_TRUNCATE,
+ ACTION_FTRUNCATE,
ACTION_STAT,
+ ACTION_FSTAT,
ACTION_LSTAT,
ACTION_PATHCONF,
+ ACTION_FPATHCONF,
+ ACTION_LPATHCONF,
#ifdef HAS_FREEBSD_ACL
ACTION_PREPENDACL,
ACTION_READACL,
@@ -124,26 +135,35 @@ static struct syscall_desc syscalls[] = {
{ "bind", ACTION_BIND, { TYPE_STRING, TYPE_NONE } },
{ "connect", ACTION_CONNECT, { TYPE_STRING, TYPE_NONE } },
{ "chmod", ACTION_CHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
+ { "fchmod", ACTION_FCHMOD, { TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
#ifdef HAS_LCHMOD
{ "lchmod", ACTION_LCHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
#endif
{ "chown", ACTION_CHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
+ { "fchown", ACTION_FCHOWN, { TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
{ "lchown", ACTION_LCHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
#ifdef HAS_CHFLAGS
{ "chflags", ACTION_CHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
#endif
+#ifdef HAS_FCHFLAGS
+ { "fchflags", ACTION_FCHFLAGS, { TYPE_NUMBER, TYPE_STRING, TYPE_NONE } },
+#endif
#ifdef HAS_LCHFLAGS
{ "lchflags", ACTION_LCHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
#endif
{ "truncate", ACTION_TRUNCATE, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
+ { "ftruncate", ACTION_FTRUNCATE, { TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
{ "stat", ACTION_STAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
+ { "fstat", ACTION_FSTAT, { TYPE_NUMBER, TYPE_STRING, TYPE_NONE } },
{ "lstat", ACTION_LSTAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
{ "pathconf", ACTION_PATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
+ { "fpathconf", ACTION_FPATHCONF, { TYPE_NUMBER, TYPE_STRING, TYPE_NONE } },
+ { "lpathconf", ACTION_LPATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
#ifdef HAS_FREEBSD_ACL
{ "prependacl", ACTION_PREPENDACL, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
{ "readacl", ACTION_READACL, { TYPE_STRING, TYPE_NONE } },
#endif
- { "write", ACTION_WRITE, { TYPE_STRING, TYPE_NONE } },
+ { "write", ACTION_WRITE, { TYPE_NUMBER, TYPE_NONE } },
{ NULL, -1, { TYPE_NONE } }
};
@@ -260,6 +280,9 @@ static struct name pathconf_names[] = {
static const char *err2str(int error);
+static int *descriptors;
+static int ndescriptors;
+
static void
usage(void)
{
@@ -415,6 +438,33 @@ show_stats(struct stat64 *sp, char *what)
printf("\n");
}
+static void
+descriptor_add(int fd)
+{
+
+ ndescriptors++;
+ if (descriptors == NULL) {
+ descriptors = malloc(sizeof(descriptors[0]) * ndescriptors);
+ } else {
+ descriptors = realloc(descriptors,
+ sizeof(descriptors[0]) * ndescriptors);
+ }
+ assert(descriptors != NULL);
+ descriptors[ndescriptors - 1] = fd;
+}
+
+static int
+descriptor_get(int pos)
+{
+
+ if (pos < 0 || pos >= ndescriptors) {
+ fprintf(stderr, "invalid descriptor %d\n", pos);
+ exit(1);
+ }
+
+ return (descriptors[pos]);
+}
+
static unsigned int
call_syscall(struct syscall_desc *scall, char *argv[])
{
@@ -470,6 +520,7 @@ call_syscall(struct syscall_desc *scall, char *argv[])
*/
#define NUM(n) (args[(n)].num)
#define STR(n) (args[(n)].str)
+#define DESC(n) (descriptor_get((int)NUM(n)))
switch (scall->sd_action) {
case ACTION_OPEN:
flags = str2flags(open_flags, STR(1));
@@ -486,6 +537,8 @@ call_syscall(struct syscall_desc *scall, char *argv[])
}
rval = open(STR(0), (int)flags);
}
+ if (rval >= 0)
+ descriptor_add(rval);
break;
case ACTION_CREATE:
rval = open(STR(0), O_CREAT | O_EXCL, (mode_t)NUM(1));
@@ -565,6 +618,9 @@ call_syscall(struct syscall_desc *scall, char *argv[])
case ACTION_CHMOD:
rval = chmod(STR(0), (mode_t)NUM(1));
break;
+ case ACTION_FCHMOD:
+ rval = fchmod(DESC(0), (mode_t)NUM(1));
+ break;
#ifdef HAS_LCHMOD
case ACTION_LCHMOD:
rval = lchmod(STR(0), (mode_t)NUM(1));
@@ -573,6 +629,9 @@ call_syscall(struct syscall_desc *scall, char *argv[])
case ACTION_CHOWN:
rval = chown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
break;
+ case ACTION_FCHOWN:
+ rval = fchown(DESC(0), (uid_t)NUM(1), (gid_t)NUM(2));
+ break;
case ACTION_LCHOWN:
rval = lchown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
break;
@@ -581,6 +640,11 @@ call_syscall(struct syscall_desc *scall, char *argv[])
rval = chflags(STR(0), (unsigned long)str2flags(chflags_flags, STR(1)));
break;
#endif
+#ifdef HAS_FCHFLAGS
+ case ACTION_FCHFLAGS:
+ rval = fchflags(DESC(0), (unsigned long)str2flags(chflags_flags, STR(1)));
+ break;
+#endif
#ifdef HAS_LCHFLAGS
case ACTION_LCHFLAGS:
rval = lchflags(STR(0), (int)str2flags(chflags_flags, STR(1)));
@@ -589,6 +653,9 @@ call_syscall(struct syscall_desc *scall, char *argv[])
case ACTION_TRUNCATE:
rval = truncate64(STR(0), NUM(1));
break;
+ case ACTION_FTRUNCATE:
+ rval = ftruncate64(DESC(0), NUM(1));
+ break;
case ACTION_STAT:
rval = stat64(STR(0), &sb);
if (rval == 0) {
@@ -596,6 +663,13 @@ call_syscall(struct syscall_desc *scall, char *argv[])
return (i);
}
break;
+ case ACTION_FSTAT:
+ rval = fstat64(DESC(0), &sb);
+ if (rval == 0) {
+ show_stats(&sb, STR(1));
+ return (i);
+ }
+ break;
case ACTION_LSTAT:
rval = lstat64(STR(0), &sb);
if (rval == 0) {
@@ -604,6 +678,8 @@ call_syscall(struct syscall_desc *scall, char *argv[])
}
break;
case ACTION_PATHCONF:
+ case ACTION_FPATHCONF:
+ case ACTION_LPATHCONF:
{
long lrval;
@@ -613,7 +689,19 @@ call_syscall(struct syscall_desc *scall, char *argv[])
exit(1);
}
errno = 0;
- lrval = pathconf(STR(0), name);
+ switch (scall->sd_action) {
+ case ACTION_PATHCONF:
+ lrval = pathconf(STR(0), name);
+ break;
+ case ACTION_FPATHCONF:
+ lrval = fpathconf(DESC(0), name);
+ break;
+ case ACTION_LPATHCONF:
+ lrval = lpathconf(STR(0), name);
+ break;
+ default:
+ abort();
+ }
if (lrval == -1 && errno == 0) {
printf("unlimited\n");
return (i);
@@ -648,7 +736,6 @@ call_syscall(struct syscall_desc *scall, char *argv[])
rval = acl_set_file(STR(0), ACL_TYPE_NFS4, acl);
break;
-
case ACTION_READACL:
acl = acl_get_file(STR(0), ACL_TYPE_NFS4);
if (acl == NULL)
@@ -657,15 +744,9 @@ call_syscall(struct syscall_desc *scall, char *argv[])
rval = 0;
break;
#endif
-
case ACTION_WRITE:
- rval = open(STR(0), O_WRONLY);
- if (rval < 0)
- break;
-
- rval = write(rval, "x", 1);
+ rval = write(DESC(0), "x", 1);
break;
-
default:
fprintf(stderr, "unsupported syscall\n");
exit(1);
diff --git a/tools/regression/pjdfstest/tests/chmod/12.t b/tools/regression/pjdfstest/tests/chmod/12.t
index db8c9b8..0c72bd7 100644
--- a/tools/regression/pjdfstest/tests/chmod/12.t
+++ b/tools/regression/pjdfstest/tests/chmod/12.t
@@ -18,13 +18,13 @@ cd ${n2}
# Check whether writing to the file by non-owner clears the SUID.
expect 0 create ${n0} 04777
-expect 0 -u 65534 -g 65534 write ${n0}
+expect 0 -u 65534 -g 65534 write ${n0} x
expect 0777 stat ${n0} mode
expect 0 unlink ${n0}
# Check whether writing to the file by non-owner clears the SGID.
expect 0 create ${n0} 02777
-expect 0 -u 65534 -g 65534 write ${n0}
+expect 0 -u 65534 -g 65534 write ${n0} x
expect 0777 stat ${n0} mode
expect 0 unlink ${n0}
OpenPOWER on IntegriCloud