diff options
author | 2021-02-25 20:49:44 +0000 | |
---|---|---|
committer | 2021-02-25 20:49:44 +0000 | |
commit | 2aa17a233d8d2796fcda7895e21d87e55993dc3b (patch) | |
tree | 116868bcd0187d06a9c30b175520223e8c0208dc | |
parent | 68f650726ed970c6a0b0a4b5272da333f783e36e (diff) | |
download | sydbox-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.h | 3 | ||||
-rw-r--r-- | src/syscall-special.c | 64 | ||||
-rw-r--r-- | src/syscall.c | 15 | ||||
-rwxr-xr-x | t/t0003-core-basic.sh | 17 | ||||
-rw-r--r-- | t/test-bin/Makefile.am | 2 | ||||
-rw-r--r-- | t/test-bin/syd-fstatat.c | 22 |
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; +} |