From f5acfe67238a331bf8a6e94715163949999f27e7 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 7 May 2021 12:09:41 -0400 Subject: Add a sandbox workaround for Glibc 2.33 This change permits the newfstatat() system call, and fixes issues 40382 (and 40381). This isn't a free change. From the commit: // Libc 2.33 uses this syscall to implement both fstat() and stat(). // // The trouble is that to implement fstat(fd, &st), it calls: // newfstatat(fs, "", &st, AT_EMPTY_PATH) // We can't detect this usage in particular, because "" is a pointer // we don't control. And we can't just look for AT_EMPTY_PATH, since // AT_EMPTY_PATH only has effect when the path string is empty. // // So our only solution seems to be allowing all fstatat calls, which // means that an attacker can stat() anything on the filesystem. That's // not a great solution, but I can't find a better one. --- changes/ticket40382 | 6 ++++++ src/lib/sandbox/sandbox.c | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 changes/ticket40382 diff --git a/changes/ticket40382 b/changes/ticket40382 new file mode 100644 index 0000000000..5ac1b771b9 --- /dev/null +++ b/changes/ticket40382 @@ -0,0 +1,6 @@ + o Minor features (compatibility, Linux seccomp sandbox): + - Add a workaround to enable the Linux sandbox to work correctly + on systems running Glibc 2.33. These versions have started + using the fstatat() system call, which previously our sandbox did not + allow. + Closes ticket 40382; see the ticket for a discussion of tradeoffs. diff --git a/src/lib/sandbox/sandbox.c b/src/lib/sandbox/sandbox.c index 168dfd943c..fc90dbe062 100644 --- a/src/lib/sandbox/sandbox.c +++ b/src/lib/sandbox/sandbox.c @@ -1608,6 +1608,28 @@ add_noparam_filter(scmp_filter_ctx ctx) } } + if (is_libc_at_least(2, 33)) { +#ifdef __NR_newfstatat + // Libc 2.33 uses this syscall to implement both fstat() and stat(). + // + // The trouble is that to implement fstat(fd, &st), it calls: + // newfstatat(fs, "", &st, AT_EMPTY_PATH) + // We can't detect this usage in particular, because "" is a pointer + // we don't control. And we can't just look for AT_EMPTY_PATH, since + // AT_EMPTY_PATH only has effect when the path string is empty. + // + // So our only solution seems to be allowing all fstatat calls, which + // means that an attacker can stat() anything on the filesystem. That's + // not a great solution, but I can't find a better one. + rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(newfstatat)); + if (rc != 0) { + log_err(LD_BUG,"(Sandbox) failed to add newfstatat() syscall; " + "received libseccomp error %d", rc); + return rc; + } +#endif + } + return 0; } -- cgit v1.2.3-54-g00ecf