aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ali Polatel <alip@exherbo.org> 2021-02-25 20:49:44 +0000
committerAvatar Ali Polatel <alip@exherbo.org> 2021-02-25 20:49:44 +0000
commit2aa17a233d8d2796fcda7895e21d87e55993dc3b (patch)
tree116868bcd0187d06a9c30b175520223e8c0208dc
parent68f650726ed970c6a0b0a4b5272da333f783e36e (diff)
downloadsydbox-1-2aa17a233d8d2796fcda7895e21d87e55993dc3b.tar.gz
sydbox-1-2aa17a233d8d2796fcda7895e21d87e55993dc3b.tar.xz
basic support for newfstatat to enter magic commands
Signed-off-by: Ali Polatel <alip@exherbo.org>
-rw-r--r--src/sydbox.h3
-rw-r--r--src/syscall-special.c64
-rw-r--r--src/syscall.c15
-rwxr-xr-xt/t0003-core-basic.sh17
-rw-r--r--t/test-bin/Makefile.am2
-rw-r--r--t/test-bin/syd-fstatat.c22
6 files changed, 105 insertions, 18 deletions
diff --git a/src/sydbox.h b/src/sydbox.h
index 645a9d5..8c8da80 100644
--- a/src/sydbox.h
+++ b/src/sydbox.h
@@ -1,7 +1,7 @@
/*
* sydbox/sydbox.h
*
- * Copyright (c) 2010, 2011, 2012, 2013, 2014, 2015 Ali Polatel <alip@exherbo.org>
+ * Copyright (c) 2010, 2011, 2012, 2013, 2014, 2015, 2021 Ali Polatel <alip@exherbo.org>
* Released under the terms of the 3-clause BSD license
*/
@@ -923,6 +923,7 @@ int sys_vfork(syd_process_t *current);
int sys_clone(syd_process_t *current);
int sys_execve(syd_process_t *current);
int sys_stat(syd_process_t *current);
+int sys_fstatat(syd_process_t *current);
int sys_socketcall(syd_process_t *current);
int sys_bind(syd_process_t *current);
diff --git a/src/syscall-special.c b/src/syscall-special.c
index b8277dd..a8ea37b 100644
--- a/src/syscall-special.c
+++ b/src/syscall-special.c
@@ -3,7 +3,7 @@
*
* Special system call handlers
*
- * Copyright (c) 2011, 2012, 2013, 2014, 2015 Ali Polatel <alip@exherbo.org>
+ * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2021 Ali Polatel <alip@exherbo.org>
* Based in part upon strace which is:
* Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
* Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
@@ -158,21 +158,11 @@ int sys_execve(syd_process_t *current)
return r;
}
-int sys_stat(syd_process_t *current)
+static int sys_stat_common(syd_process_t *current, const char *path,
+ unsigned int buf_index)
{
int r;
long addr;
- char path[SYDBOX_PATH_MAX];
-
- if (P_BOX(current)->magic_lock == LOCK_SET) {
- /* No magic allowed! */
- return 0;
- }
-
- if ((r = syd_read_argument(current, 0, &addr)) < 0)
- return r;
- if (syd_read_string(current, addr, path, SYDBOX_PATH_MAX) < 0)
- return errno == EFAULT ? 0 : -errno;
r = magic_cast_string(current, path, 1);
if (r == MAGIC_RET_NOOP) {
@@ -255,7 +245,7 @@ int sys_stat(syd_process_t *current)
bufsize = sizeof(struct stat);
}
- if (pink_read_argument(current->pid, current->regset, 1, &addr) == 0)
+ if (pink_read_argument(current->pid, current->regset, buf_index, &addr) == 0)
pink_write_vm_data(current->pid, current->regset, addr, bufaddr, bufsize);
#if !PINK_ARCH_X86_64
skip_write:
@@ -277,6 +267,52 @@ skip_write:
return r;
}
+int sys_stat(syd_process_t *current)
+{
+ int r;
+ long addr;
+ char path[SYDBOX_PATH_MAX];
+
+ if (P_BOX(current)->magic_lock == LOCK_SET) {
+ /* No magic allowed! */
+ return 0;
+ }
+
+ if ((r = syd_read_argument(current, 0, &addr)) < 0)
+ return r;
+ if (syd_read_string(current, addr, path, SYDBOX_PATH_MAX) < 0)
+ return errno == EFAULT ? 0 : -errno;
+
+ return sys_stat_common(current, path, 1);
+}
+
+int sys_fstatat(syd_process_t *current)
+{
+ int r;
+ long addr;
+ char path[SYDBOX_PATH_MAX];
+
+ if (P_BOX(current)->magic_lock == LOCK_SET) {
+ /* No magic allowed! */
+ return 0;
+ }
+
+ /* We intentionally disregard the first argument, aka `dirfd' here
+ * because the added complexity is not worth adding support for a
+ * usecase that's almost never possible, ie:
+ * cd /dev; fstatat(AT_FDCWD, sydbox/..., 0);
+ * does not work, however
+ * fstatat(AT_FDCWD, /dev/sydbox/..., 0);
+ * does.
+ */
+ if ((r = syd_read_argument(current, 1, &addr)) < 0)
+ return r;
+ if (syd_read_string(current, addr, path, SYDBOX_PATH_MAX) < 0)
+ return errno == EFAULT ? 0 : -errno;
+
+ return sys_stat_common(current, path, 2);
+}
+
int sys_dup(syd_process_t *current)
{
int r;
diff --git a/src/syscall.c b/src/syscall.c
index 6f6459f..4fcece5 100644
--- a/src/syscall.c
+++ b/src/syscall.c
@@ -1,7 +1,7 @@
/*
* sydbox/syscall.c
*
- * Copyright (c) 2010, 2011, 2012, 2013, 2014, 2015 Ali Polatel <alip@exherbo.org>
+ * Copyright (c) 2010, 2011, 2012, 2013, 2014, 2015, 2021 Ali Polatel <alip@exherbo.org>
* Released under the terms of the 3-clause BSD license
*/
@@ -60,6 +60,19 @@ static const sysentry_t syscall_entries[] = {
.name = "lstat64",
.enter = sys_stat,
},
+ {
+ .name = "newfstatat",
+ .enter = sys_fstatat,
+ },
+ /*
+ * TODO: This requires updates in the ABI & struct stat logic in
+ * sys_stat_common function. This system call is i386 only and is very
+ * rarely used so we leave it out for the time being.
+ {
+ .name = "fstatat64",
+ .enter = sys_fstatat,
+ }
+ */
{
.name = "access",
diff --git a/t/t0003-core-basic.sh b/t/t0003-core-basic.sh
index fb87529..03820c5 100755
--- a/t/t0003-core-basic.sh
+++ b/t/t0003-core-basic.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright 2013, 2014 Ali Polatel <alip@exherbo.org>
+# Copyright 2013, 2014, 2021 Ali Polatel <alip@exherbo.org>
# Released under the terms of the GNU General Public License v2
test_description='test the very basics of sydbox'
@@ -137,6 +137,16 @@ test_expect_success_foreach_option 'magic /dev/sydbox API is 1' '
test_expect_code 1 sydbox -- sh -c "test -e /dev/sydbox/0"
'
+test_expect_success_foreach_option 'magic /dev/sydbox API is 1 using fstatat' '
+ sydbox -- syd-fstatat cwd /dev/sydbox &&
+ sydbox -- syd-fstatat cwd /dev/sydbox/1 &&
+ sydbox -- syd-fstatat null /dev/sydbox &&
+ sydbox -- syd-fstatat null /dev/sydbox/1 &&
+ sydbox -- syd-fstatat /dev /dev/sydbox &&
+ sydbox -- syd-fstatat /dev /dev/sydbox/1 &&
+ test_expect_code 22 sydbox -- syd-fstatat cwd /dev/sydbox/0 # EINVAL
+'
+
test_expect_success_foreach_option 'magic /dev/sydbox boolean checking works' '
sydbox -- sh <<-\EOF
test -e /dev/sydbox/core/sandbox/write"?"
@@ -149,6 +159,11 @@ EOF
'
test_expect_success_foreach_option 'magic /dev/sydbox boolean checking works with -m switch' '
+ test_expect_code 2 sydbox -- syd-fstatat cwd /dev/sydbox/core/sandbox/write"?" && # ENOENT
+ sydbox -m core/sandbox/write:deny -- syd-fstatat cwd /dev/sydbox/core/sandbox/write"?"
+'
+
+test_expect_success_foreach_option 'magic /dev/sydbox boolean checking works with -m switch' '
sydbox -m core/sandbox/write:deny -- sh <<-\EOF
test -e /dev/sydbox/core/sandbox/write"?"
EOF
diff --git a/t/test-bin/Makefile.am b/t/test-bin/Makefile.am
index 86e8b3a..973ebce 100644
--- a/t/test-bin/Makefile.am
+++ b/t/test-bin/Makefile.am
@@ -29,7 +29,7 @@ syd_PROGRAMS= wildtest realpath_mode-1 \
syd-true syd-true-static syd-true-fork syd-true-fork-static syd-true-pthread \
syd-false syd-false-static syd-false-fork syd-false-fork-static syd-false-pthread \
syd-abort syd-abort-static syd-abort-fork syd-abort-fork-static \
- syd-abort-pthread syd-abort-pthread-static syd-mkdir-p
+ syd-abort-pthread syd-abort-pthread-static syd-fstatat syd-mkdir-p
check_PROGRAMS= $(syd_PROGRAMS)
diff --git a/t/test-bin/syd-fstatat.c b/t/test-bin/syd-fstatat.c
new file mode 100644
index 0000000..5da349f
--- /dev/null
+++ b/t/test-bin/syd-fstatat.c
@@ -0,0 +1,22 @@
+#include "headers.h"
+
+int main(int argc, char *argv[])
+{
+ int dirfd;
+ const char *path;
+ struct stat buf;
+
+ if (!strcmp(argv[1], "cwd"))
+ dirfd = AT_FDCWD;
+ else if (!strcmp(argv[1], "null"))
+ dirfd = STDERR_FILENO; /* not a directory */
+ else
+ dirfd = atoi(argv[1]);
+ path = argv[2];
+
+ /* Using fstatat(AT_FDCWD, ...) is not a good idea here as the libc may
+ * actually call the stat() system call instead. */
+ errno = 0;
+ syscall(SYS_newfstatat, dirfd, path, &buf, 0);
+ return errno;
+}