Skip to content

Commit

Permalink
sandbox: deny newfstatat used by newer glibc.
Browse files Browse the repository at this point in the history
The Linux system call 'newfstatat' provides a single interface that
can be used to implement stat(), lstat(), fstat(), or fstatat().

stat(), lstat(), and fstat() are safe to use in the sandbox.
LightWAVE doesn't use these functions directly, but other libraries
may use fstat() internally.  The general fstatat() is not safe for the
same reasons that openat() is not safe.

Unfortunately, the system call interface doesn't allow seccomp to
permit fstat-equivalent newfstatat without permitting the more general
and dangerous fstatat-equivalent.

Recent versions of glibc now use newfstatat, instead of fstat, to
implement fstat(), as well as calling newfstatat whenever a stdio
stream is used for the first time.  We can't avoid these calls (short
of patching glibc, or using the signal handler to emulate the system
call.)  Fortunately, glibc will still work if the call fails (it might
be a tiny bit less efficient.)
  • Loading branch information
Benjamin Moody committed Jul 26, 2023
1 parent dd55ff3 commit dcb99fb
Showing 1 changed file with 12 additions and 0 deletions.
12 changes: 12 additions & 0 deletions server/sandbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/capability.h>
#include <sys/mman.h>
#include <sys/resource.h>
Expand Down Expand Up @@ -206,6 +207,17 @@ void lightwave_sandbox()
SCMP_A0(SCMP_CMP_EQ, (uint32_t) AT_FDCWD),
SCMP_A2(SCMP_CMP_EQ, O_RDONLY));

/* deny newfstatat(fd, ..., ..., AT_EMPTY_PATH)
(could allow a local attacker to examine files outside an outer
chroot environment; unfortunately seccomp can't distinguish
empty from non-empty paths. If a working fstat() function is
actually needed, it must be implemented using the fstat system
call rather than newfstatat.) */
seccomp_rule_add_exact
(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(newfstatat), 2,
SCMP_A0(SCMP_CMP_NE, (uint32_t) AT_FDCWD),
SCMP_A3(SCMP_CMP_EQ, AT_EMPTY_PATH));

/* permit mmap(..., PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, ...)
(typically lightwave doesn't allocate any huge blocks of memory
that would make this necessary, but it's good future-proofing) */
Expand Down

0 comments on commit dcb99fb

Please sign in to comment.