aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* libsandbox: fix violations where ENOENT is expectedHEADmasterAliaksei Urbanski2024-06-271-3/+5
| | | | | | | | | These changes revert f7d02c04 that aimed to resolve 921581 and fix it in a way that doesn't cause unwanted sandbox violations. Bug: https://bugs.gentoo.org/921581 Signed-off-by: Aliaksei Urbanski <aliaksei.urbanski@gmail.com> Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* Fix SIGSEGV in gtest death tests due to small stackSv. Lockal2024-01-271-5/+29
| | | | | | | | | | | | | | | | | | | | | | | | In https://github.com/google/googletest/blob/v1.14.0/googletest/src/gtest-death-test.cc#L1307 on x86-64 gtest sallocates 8192 bytes for `clone`: ``` static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { const auto stack_size = static_cast<size_t>(getpagesize() * 2); ... child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); ``` After that attempt to call execv is intercepted by libsandbox.so, which allocates 8192 + more bytes multiple times on stack, causing SIGSEGV (instead of expected types of crashes). This PR moves all allocations for related function to heap, so now call path fits `getpagesize() * 2` with large margin. Bug: https://bugs.gentoo.org/923013 Closes: https://github.com/gentoo/sandbox/pull/26 Signed-off-by: Sv. Lockal <lockalsash@gmail.com> Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* libsandbox: stat the original path for EEXIST hackaroundMike Gilbert2024-01-081-1/+1
| | | | | | | | | | | | Resolves an issue that can occur with paths that contain parent directory references (/../). If part of the path does not exist, the sandboxed program should get ENOENT, not EEXIST. If we use the canonicalized path, intermediate paths will be eliminated and we produce the wrong result. Bug: https://bugs.gentoo.org/921581 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* egetcwd: fix some edge casesOskari Pirhonen2023-08-081-5/+5
| | | | | | | | | | | | | - Ensure all potentially 21 chars + NUL from "/proc/%i/cwd" fit in its buffer - Use snprintf(3) instead of sprintf(3) to fill in the buffer - readlink(2) does not add a NUL terminator, so ensure it only writes up to the allocated length - 1 - Use a more descriptive name for the return value of readlink(2) Signed-off-by: Oskari Pirhonen <xxc3ncoredxx@gmail.com> Closes: https://github.com/gentoo/sandbox/pull/24 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* resolve_dirfd_path: use separate buffer for readlinkMike Gilbert2023-08-051-4/+5
| | | | | | | | | Fixes a compile warning: ``` warning: passing argument 2 to 'restrict'-qualified parameter aliases with argument 1 [-Wrestrict] ``` Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* erealpath: use separate buffer for readlinkMike Gilbert2023-08-051-2/+4
| | | | | | | | | Fixes a compiler warning: ``` warning: passing argument 2 to 'restrict'-qualified parameter aliases with argument 1 [-Wrestrict] ``` Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* erealpath: leave space for a trailing '\0' in readlink's bufferMike Gilbert2023-08-051-1/+1
| | | | Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* erealpath: drop unused path_max variableMike Gilbert2023-08-051-17/+9
| | | | | | The SB_PATH_MAX macro is always defined, so this variable was pointless. Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* Rename multiple personalities featureSam James2023-08-056-16/+16
| | | | | | | | "schizo" isn't a particularly sensitive term, and it's not very clear what it means to non-native English speakers anyway. Name it after what the feature really does: multiple (Linux) personality support using ptrace. Signed-off-by: Sam James <sam@gentoo.org>
* libsbutil: add sbio_faccessat and use it in sb_existsMike Gilbert2023-08-032-0/+3
| | | | | | | | | | | | | sbio_faccessat allows libsbutil to access the unwrapped version of faccessat when called from libsandbox. Using faccessat in place of fstatat seems to give a small boost in performance. Pass AT_EACCESS faccessat to enable a faster path if uid != euid. Bug: https://bugs.gentoo.org/910273 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* libsandbox: skip checking access() without W_OK or R_OK modeMike Gilbert2023-08-031-1/+4
| | | | | | | | If access/faccessat is called with F_OK or X_OK in the mode argument, there is no need to check the path. Bug: https://bugs.gentoo.org/910273 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* libsandbox: always permit access to '/memfd:'Mike Gilbert2023-07-311-0/+6
| | | | | | | | | | | For memfd objects, the kernel populates the target for symlinks under /proc/$PID/fd as "/memfd:name". Said target does not actually exist. It is unfortunate that the kernel includes the leading slash, but we will just have to work around it. Bug: https://bugs.gentoo.org/910561 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* libsandbox/trace: cast NT_ARM_SYSTEM_CALL to avoid warningsMike Gilbert2023-07-101-2/+2
| | | | | Bug: https://bugs.gentoo.org/910195 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* libsandbox/trace: fix syscall cancellation on arm64Mike Gilbert2023-07-071-1/+20
| | | | | | | | arm64 has a dedicated regset to manipulate the system call number. See kernel commit 766a85d7bc5d7f1ddd6de28bdb844eae45ec63b0. Bug: https://bugs.gentoo.org/909416 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* libsandbox: wrap musl time64 functionsMike Gilbert2023-06-225-0/+8
| | | | | | | | musl uses different names from glibc for the time64 symbols. Add them to symbols.h, and use symlinks for the wrapper-func files. Bug: https://bugs.gentoo.org/908970 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* libsandbox: add support for fchown/fchmod on linuxMichael Orlitzky2023-06-226-0/+61
| | | | | | | | | | | | | | | | | | | | The fchown/fchmod functions use a file descriptor obtained from open(), and the sandbox relies on its open() wrapper for safety. But it turns out that fchown/fchmod can operate on a descriptor opened O_RDONLY, which the open() wrapper is happy to give you. Oops. This is bug 599706. There's no POSIX way to map the descriptor to a path once you've got it, but on linux you can use the magic path "/proc/self/fd/%i" which should be a symlink pointing to the path passed to open(). Once we have that path, we can use the existing "is this path safe" machinery in the sandbox. There is precedent for this approach in sandbox, and the SANDBOX_PROC_SELF_FD macro already exists to indicate that the feature is available. Bug: https://bugs.gentoo.org/599706 Signed-off-by: Michael Orlitzky <mjo@gentoo.org> Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* libsbutil: add sb_exists functionMike Gilbert2023-06-212-2/+2
| | | | | | | | | This provides a central place to work around a bug on musl where faccessat sets errno to EINVAL when the kernel does not support faccessat2. Bug: https://bugs.gentoo.org/908765 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* libsandbox: add lutimes to symlink_funcMike Gilbert2023-06-121-0/+1
| | | | | | | | lutimes operates on symlinks, so we should not check for access against the symlink target. Bug: https://bugs.gentoo.org/908105 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
* libsandbox: reduce & inline the __64_{pre,post}.h headersMike Frysinger2021-11-0514-41/+17
| | | | | | | | | | | | | | | | | | Now that we use 64-bit stat & lstat explicitly everywhere, we don't need these dynamic redirects for 64-bit wrappers. The off_t define is only used by one file anymore too, but we can inline that. That leaves the SB64 define which we use inconsistently in places. In some 64-bit modules that include the 32-bit, we use SB64 to switch between the 64-bit & 32-bit APIs. In other places, the 64-bit file is responsible for redefining the few relevant APIs. Let's switch all the files away from SB64 and to defining the single thing that the 64-bit module needs directly. It's either the same or fewer LOC this way, and doesn't seem any more or less difficult to maintain. The __64_{pre,post}.h & SB64 define weren't easily discoverable. Bug: https://bugs.gentoo.org/583282 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* change FS calls to use 64-bit interfaces explicitlyMike Frysinger2021-11-055-17/+17
| | | | | | | | | Make sure we use 64-bit FS interfaces when accessing the FS. This is needed not only to stat or open large files, but even files with 64-bit inodes. Bug: https://bugs.gentoo.org/583282 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox/libsbutil: use faccessat for file-existence testsMike Frysinger2021-11-052-14/+4
| | | | | | | | This is faster than using stat since it doesn't have to gather all the metadata, and should avoid LFS issues as a result. Bug: https://bugs.gentoo.org/583282 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: refine yama check to abort on level 3+Mike Frysinger2021-11-031-9/+21
| | | | | | | | There's no way we can support level 3+ since the kernel blocks it, so give up and inform the user their setup is incompatible. Bug: https://bugs.gentoo.org/771360 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: tweak label/decl code for some compiler settingsMike Frysinger2021-11-031-1/+3
| | | | | | | | | | Looks like gcc is inconsistent in when it chokes on this code: > a label can only be part of a statement and a declaration is not a statement Hoist the decl up to the top of scope to avoid the issue. Bug: https://bugs.gentoo.org/821433 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: add YAMA checks and skip ptrace when activev3.1Mike Frysinger2021-11-031-0/+38
| | | | | | | | | | | | | | The YAMA ptrace_scope knob restricts access to different ptrace calls depending on the capabilities the current process holds. For now, do not try to ptrace processes when the YAMA level is incompatible with the capabilities that we have. This means we basically cannot protect against processes when they get into this state, so for now, we release them rather than abort. Bug: https://bugs.gentoo.org/771360 Bug: https://bugs.gentoo.org/821403 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: merge sandbox settings from tracee end when execingv3.0Mike Frysinger2021-11-021-0/+33
| | | | | | | | | | | | This allows traced children to change their sandox settings on the fly and the out-of-process tracer will react accordingly. We don't try to read the environ all the time as it's kind of impossible to know where the tracee is storing it (since it can point |environ| anywhere). This means turning the sandbox on/off won't work in the current process, only in forked children. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: fix ptracing childrenMike Frysinger2021-11-021-8/+65
| | | | | | | | | | | | | | | | The ptrace logic was largely built around the assumption of execing a single static binary and that's it. But there's nothing stopping it from also forking & creating children. Today, that means children do not get tracked for problems. One major known issue is that the sandbox env is frozen upon launch. So once we switch to ptrace mode, it's not possible for traced code to disable sandboxing or otherwise reconfigure it. Currently that shouldn't be a big deal as we assume the main execution environment (i.e. bash) is dynamic, and that's where the env will be tweaked, but we'll have to address this before we can deploy ptrace more. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: do not use ptrace if it returns ENOSYSMike Frysinger2021-10-311-2/+8
| | | | | | | | QEMU's linux-user does not implement ptrace for any architecture, and any attempt to call it fails with ENOSYS. Detect that scenario. Closes: https://bugs.gentoo.org/648516 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: drop args to trace_mainMike Frysinger2021-10-293-7/+7
| | | | | | | The filename was only used for a single debug print, and the args ignored completely. Don't bother passing them down at all. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: hoist the *at pre-check functions up a levelMike Frysinger2021-10-288-36/+42
| | | | | | | | | | | | | | | | | | | | | | | | | | The reason we put these in wrapper-funcs/ is because we normally dynamically include them when the corresponding symbol is available. For example, if the C library supports symbol foo, and there is a wrapper-funcs/foo_pre_check.c, we'll automatically include it based on the assumption that wrapper-funcs/foo.c needs it. But if the C library doesn't have a symbol foo, we won't include foo.c or the foo_pre_check.c file at all. Sounds fine. The *at family of functions is a bit different because we end up using them both in the wrapper-funcs/ files, and in the trace code, the latter of which we use unconditionally. This lead to a build issue early on (see commit b27df46f349e850067ae388fe067b043abf3aecb ("libsandbox: fix missing *at pre_checks")) whereby we hacked in these *at pre-check symbols all the time. At which point, having them be in wrapper-funcs/ was more out of convention with how we manage all our other APIs. We want to support running ptrace from the sandbox binary directly which requires linking (most of) libsandbox into it, and to that end, hoist these pre-check functions out of wrapper-funcs. This makes it a bit clearer that we always want to compile these. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* build: create libsandbox for trace_syscalls.h tooMike Frysinger2021-10-281-0/+1
| | | | | | | | | Commit ef35a16d1b5dcc1a99d17470799e680879278600 ("build: create libsandbox dir before writing files") added a mkdir call to most targets, but trace_syscalls.h was missed. Bug: https://issuetracker.google.com/issues/204404822 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: fix signal pass through with ptrace main loopv2.28Mike Frysinger2021-10-281-2/+5
| | | | | | | | | | | | | | | When we're notified that the child has received a signal, we need to pass it through since we don't care about signals. We did that, but using PTRACE_CONT which causes the process to just resume, and then we'd call PTRACE_SYSCALL on that resumed state. When the pass thru logic was a signal handler, PTRACE_CONT was correct since it would come in while in the middle of PTRACE_SYSCALL, but after the rewrite of the main loop, it's now the wrong call. Pass the signal back to the existing PTRACE_SYSCALL call so that we stay in the main loop and get notified on the next syscall event. Closes: https://bugs.gentoo.org/820407 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: drop lstat check for symlink funcsMike Frysinger2021-10-271-28/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When checking paths for violations, we need to know whether the path is a symlink, and whether the current function dereferences them. If it dereferences, we have to check the symlink and its target. If it doesn't, we can skip the target check. The helper to see if the function operates on symlinks ends with an lstat on the path itself -- if it exists and is a symlink, we will skip the target check. If it doesn't exist, or isn't a symlink, we check the target. This logic doesn't make sense since (1) if it doesn't exist, or isn't a symlink, there is no "target" and (2) the symlink nature of the function is unchanged. In practice, this largely doesn't matter. If the path wasn't a symlink, and it (as the source) already passed checks, then it's also going to pass checks (as the target) since they're the same path. However, we get into a fun TOCTOU race: if there are multiple things trying to create a symlink at the same path, then we can get into a state where: - process 1 calls a symlink func on a path doesn't exist - lstat fails, so symlink_func() returns false - the kernel contexts switches away from process 1 - process 2 calls a symlink func on the same path - lstat fails, so symlink_func() returns false - the target path is "resolved" and passes validation - process 2 creates the symlink to a place like /usr/bin/foo - process 1 resumes - the target path is resolved since it now actually exists - the target is a bad path (/usr/bin/foo) - sandbox denies the access even though it's a func that only operates on symlinks and never dereferences This scenario too rarely happens (causes it's so weird), but it is possible. A quick way to reproduce is with: while [[ ! -e $SANDBOX_LOG ]] ; do ln -s /bin/bash ./f & ln -s /bin/bash ./f & ln -s /bin/bash ./f & ln -s /bin/bash ./f & ln -s /bin/bash ./f & rm -f f wait done Eventually this will manage to trigger the TOCTOU race. So just delete the lstat check in the symlink_func() helper. If the path doesn't exist, we can safely let it fail. If the path shows up in parallel, either as a symlink or not, we already validated it as being safe, so letting the func be called is safe. Bug: https://issuetracker.google.com/issues/204375293 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: port ptrace to aarch64Mike Frysinger2021-10-252-0/+33
| | | | | | | | Seems to pass (almost all) unittests on Linux 4.19. The unlink_static doesn't seem to actually block the call, but it blocks others. Still, better than nothing at all at this point. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: use PTRACE_GET_SYSCALL_INFO when availableMike Frysinger2021-10-252-0/+26
| | | | | | | | This is a generic interface for all arches, but it only supports reading settings currently. We can at least detect failures which is better than nothing. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: add sparc personality supportMike Frysinger2021-10-241-0/+70
| | | | | | | | | | | This allows tracing of sparc32 in a sparc64 multilib setup. Although it doesn't quite work -- the syscall table needs to be reloaded after the exec commits. We leave that out for now since there isn't actually a sparc32+sparc64 multilib port currently. Bug: https://bugs.gentoo.org/293632 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: port ptrace to sparc64 & re-enable for sparcMike Frysinger2021-10-241-7/+11
| | | | | | | | | | Now that we have a real dev system & userland running sparc64, port the logic to it and make sure tests pass on 32-bit & 64-bit. Hopefully the trace main loop rewrite to avoid signals should address the instability issues we saw. Closes: https://bugs.gentoo.org/293632 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: extend symbols format to specify diff syscall nameMike Frysinger2021-10-232-5/+11
| | | | | | | | This enables support for 64-bit time_t syscalls where the glibc symbol name is not the same as the kernel syscall name. Closes: https://bugs.gentoo.org/751241 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: tweak how undefined symbols are declaredMike Frysinger2021-10-233-6/+10
| | | | | | | | | | Rather than always set undefined symbols to the same constant, expand it to a range of constants, and give every symbol a unique value. For dynamic symbol processing, this isn't a big deal as such symbols will never show up, but when handling syscalls that don't have a matching C library symbol, we need to make sure that we have unique entries. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: move symbols.h.in parsing to scriptsMike Frysinger2021-10-231-2/+1
| | | | | | | | | | | In preparation for extending the symbol format, move parsing out of the makefile (which is a basic sed expression) to the awk scripts. This also has a nice side benefit of removing one automake warning. It is slightly more code, but the scripts will be diverging shortly, so it's unavoidable. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: add 64-bit time_t wrappersMike Frysinger2021-10-2311-5/+85
| | | | | | | | This intercepts the C library 64-bit time_t interfaces. The syscall trace side will need more work first. Bug: https://bugs.gentoo.org/751241 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: fix flags extraction for a few syscallsMike Frysinger2021-10-231-7/+14
| | | | | | | | | | | | | | | While many syscalls follow similar patterns for dirfd & path handling, the flags argument is less consistent -- it tends to be last with all other arguments in between. As a result, a few syscalls were pulling the wrong argument for the flags settings: * fchmodat: the syscall interface has no flags at all * fchownat: the flags come after uid & gid * utimensat: the flags come after the timespec These syscalls haven't been a problem in practice because no one ever tries to chmod/chown/utimes on symlinks themselves. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* build: hoist -Itop_srcdir to common AM_CPPFLAGSMike Frysinger2021-10-231-1/+0
| | | | | | | Every subdir sets this var this way, so might as well unify it. We keep very few files in here, so shouldn't be a future problem. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: only lookup syscall number on entryMike Frysinger2021-10-231-4/+6
| | | | | | | | | The ptrace API does not guarantee the syscall number lookup will be valid on syscall exit (since the underlying register might have been clobbered), so stop trying to look it up then. We only used it when decoding entry anyways, so this is more minor housekeeping. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: regen trace headers when symbols header changesMike Frysinger2021-10-231-2/+2
| | | | | | | Since it uses the symbols header as input, make sure we regen on changes to it so we don't get stuck in weird stale states. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* Revert "Remove leftover generated Makefiles from the repo (sic!)"Mike Frysinger2021-10-221-0/+4
| | | | | | | This reverts commit 53ffbaeb24f6ee22a2dcd70fad29c86a4dd863c2. These files are supposed to be in here. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: fix ppc ptrace return value settingMike Frysinger2021-10-221-2/+8
| | | | | | | Forcing errors in the powerpc interface is a little finicky. Fix it up so all the tests pass now on ppc32 & ppc64. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* Remove leftover generated Makefiles from the repo (sic!)Michał Górny2021-10-221-4/+0
| | | | Signed-off-by: Michał Górny <mgorny@gentoo.org>
* libsandbox: drop old *.py[co] hack #775416Mike Frysinger2021-10-221-14/+0
| | | | | | | | | | With our eclasses & python frameworks responsible for generating these files now, we should be able to reject write attempts to these again. Lets turn it back on and see what blows up. Bug: http://bugs.gentoo.org/256953 Closes: https://bugs.gentoo.org/775416 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: add xattr wrappers #672566Mike Frysinger2021-10-226-9/+63
| | | | | | | These modify the filesystem, so don't let them do their business. Fixes: https://bugs.gentoo.org/672566 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
* libsandbox: use wide readelf outputMike Frysinger2021-10-221-2/+2
| | | | | | | | | | | Newer versions of binutils will truncate symbol output weirdly unless the --wide option is used. This manifests itself as libsandbox not including symbols when their name and symbol version is too long. The new removexattr symbol tests were failing because of this, but it seems the others were either not too long, or we didn't have any test coverage for them (oops). Signed-off-by: Mike Frysinger <vapier@gentoo.org>