aboutsummaryrefslogtreecommitdiff
path: root/src/xz/main.c
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2024-02-17 23:07:35 +0200
committerLasse Collin <lasse.collin@tukaani.org>2024-02-17 23:07:35 +0200
commit374868d81d473ab56556a1cfd6b1b36a1fab348b (patch)
tree195da6ba1f931c4ec7783832428ea3c2bbcac2b5 /src/xz/main.c
parentxz: Tweak comments. (diff)
downloadxz-374868d81d473ab56556a1cfd6b1b36a1fab348b.tar.xz
xz: Move sandboxing code to sandbox.c and improve Landlock sandbox.
Landlock is now always used just like pledge(2) is: first in more permissive mode and later (under certain common conditions) in a strict mode that doesn't allow opening more files. I put pledge(2) first in sandbox.c because it's the simplest API to use and still somewhat fine-grained for basic applications. So it's the simplest thing to understand for anyone reading sandbox.c.
Diffstat (limited to '')
-rw-r--r--src/xz/main.c50
1 files changed, 16 insertions, 34 deletions
diff --git a/src/xz/main.c b/src/xz/main.c
index 3d3d11d7..c3e81467 100644
--- a/src/xz/main.c
+++ b/src/xz/main.c
@@ -12,12 +12,6 @@
#include "private.h"
#include <ctype.h>
-// prctl(PR_SET_NO_NEW_PRIVS, ...) is required with Landlock but it can be
-// activated even when conditions for strict sandboxing aren't met.
-#ifdef HAVE_LINUX_LANDLOCK_H
-# include <sys/prctl.h>
-#endif
-
/// Exit status to use. This can be changed with set_exit_status().
static enum exit_status_type exit_status = E_SUCCESS;
@@ -148,32 +142,6 @@ read_name(const args_info *args)
int
main(int argc, char **argv)
{
-#ifdef HAVE_PLEDGE
- // OpenBSD's pledge(2) sandbox
- //
- // Unconditionally enable sandboxing with fairly relaxed promises.
- // This is still way better than having no sandbox at all. :-)
- // More strict promises will be made later in file_io.c if possible.
- if (pledge("stdio rpath wpath cpath fattr", "")) {
- // Don't translate the string or use message_fatal() as
- // those haven't been initialized yet.
- fprintf(stderr, "%s: Failed to enable the sandbox\n", argv[0]);
- return E_ERROR;
- }
-#endif
-
-#ifdef HAVE_LINUX_LANDLOCK_H
- // Prevent the process from gaining new privileges. This must be done
- // before landlock_restrict_self(2) in file_io.c but since we will
- // never need new privileges, this call can be done here already.
- //
- // This is supported since Linux 3.5. Ignore the return value to
- // keep compatibility with old kernels. landlock_restrict_self(2)
- // will fail if the no_new_privs attribute isn't set, thus if prctl()
- // fails here the error will still be detected when it matters.
- (void)prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
-#endif
-
#if defined(_WIN32) && !defined(__CYGWIN__)
InitializeCriticalSection(&exit_status_cs);
#endif
@@ -187,6 +155,20 @@ main(int argc, char **argv)
// even indirectly like locale and gettext initializations.
io_init();
+#ifdef ENABLE_SANDBOX
+ // Enable such sandboxing that can always be enabled.
+ // This requires that progname has been set up.
+ // It's also good that io_init() has been called because it
+ // might need to do things that the initial sandbox won't allow.
+ // Otherwise this should be called as early as possible.
+ //
+ // NOTE: Calling this before tuklib_gettext_init() means that
+ // translated error message won't be available if sandbox
+ // initialization fails. However, sandbox_init() shouldn't
+ // fail and this order simply feels better.
+ sandbox_init();
+#endif
+
// Set up the locale and message translations.
tuklib_gettext_init(PACKAGE, LOCALEDIR);
@@ -241,7 +223,7 @@ main(int argc, char **argv)
signals_init();
#ifdef ENABLE_SANDBOX
- // Set a flag that sandboxing is allowed if all these are true:
+ // Set a flag that strict sandboxing is allowed if all these are true:
// - --files or --files0 wasn't used.
// - There is exactly one input file or we are reading from stdin.
// - We won't create any files: output goes to stdout or --test
@@ -255,7 +237,7 @@ main(int argc, char **argv)
if (args.files_name == NULL && args.arg_count == 1
&& (opt_stdout || strcmp("-", args.arg_names[0]) == 0
|| opt_mode == MODE_LIST))
- io_allow_sandbox();
+ sandbox_allow_strict();
#endif
// coder_run() handles compression, decompression, and testing.