xz: Use stricter pledge(2) and Landlock sandbox.
This makes these sandboxing methods stricter when no files are created or deleted. That is, it's a middle ground between the initial sandbox and the strictest single-file-to-stdout sandbox: this allows opening files for reading but output has to go to stdout.
This commit is contained in:
parent
02e3505991
commit
cae9a5e0bf
|
@ -223,21 +223,41 @@ main(int argc, char **argv)
|
||||||
signals_init();
|
signals_init();
|
||||||
|
|
||||||
#ifdef ENABLE_SANDBOX
|
#ifdef ENABLE_SANDBOX
|
||||||
// Set a flag that strict sandboxing is allowed if all these are true:
|
// Read-only sandbox can be enabled if we won't create or delete
|
||||||
// - --files or --files0 wasn't used.
|
// any files:
|
||||||
// - There is exactly one input file or we are reading from stdin.
|
|
||||||
// - We won't create any files: output goes to stdout or --test
|
|
||||||
// or --list was used. Note that --test implies opt_stdout = true
|
|
||||||
// but --list doesn't.
|
|
||||||
//
|
//
|
||||||
// This is obviously not ideal but it was easy to implement and
|
// - --stdout, --test, or --list was used. Note that --test
|
||||||
// it covers the most common use cases.
|
// implies opt_stdout = true but --list doesn't.
|
||||||
//
|
//
|
||||||
// TODO: Make sandboxing work for other situations too.
|
// - Output goes to stdout because --files or --files0 wasn't used
|
||||||
if (args.files_name == NULL && args.arg_count == 1
|
// and no arguments were given on the command line or the
|
||||||
&& (opt_stdout || strcmp("-", args.arg_names[0]) == 0
|
// arguments are all "-" (indicating standard input).
|
||||||
|| opt_mode == MODE_LIST))
|
bool to_stdout_only = opt_stdout || opt_mode == MODE_LIST;
|
||||||
sandbox_allow_strict();
|
if (!to_stdout_only && args.files_name == NULL) {
|
||||||
|
// If all of the filenames provided are "-" (more than one
|
||||||
|
// "-" could be specified), then we are only going to be
|
||||||
|
// writing to standard output. Note that if no filename args
|
||||||
|
// were provided, args.c puts a single "-" in arg_names[0].
|
||||||
|
to_stdout_only = true;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < args.arg_count; ++i) {
|
||||||
|
if (strcmp("-", args.arg_names[i]) != 0) {
|
||||||
|
to_stdout_only = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to_stdout_only) {
|
||||||
|
sandbox_enable_read_only();
|
||||||
|
|
||||||
|
// Allow strict sandboxing if we are processing exactly one
|
||||||
|
// file to standard output. This requires that --files or
|
||||||
|
// --files0 wasn't specified (an unknown number of filenames
|
||||||
|
// could be provided that way).
|
||||||
|
if (args.files_name == NULL && args.arg_count == 1)
|
||||||
|
sandbox_allow_strict();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// coder_run() handles compression, decompression, and testing.
|
// coder_run() handles compression, decompression, and testing.
|
||||||
|
|
|
@ -81,6 +81,18 @@ sandbox_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern void
|
||||||
|
sandbox_enable_read_only(void)
|
||||||
|
{
|
||||||
|
// We will be opening files for reading but
|
||||||
|
// won't create or remove any files.
|
||||||
|
if (pledge("stdio rpath", ""))
|
||||||
|
message_fatal(_("Failed to enable the sandbox"));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
sandbox_enable_strict_if_allowed(int src_fd lzma_attribute((__unused__)),
|
sandbox_enable_strict_if_allowed(int src_fd lzma_attribute((__unused__)),
|
||||||
int pipe_event_fd lzma_attribute((__unused__)),
|
int pipe_event_fd lzma_attribute((__unused__)),
|
||||||
|
@ -89,6 +101,7 @@ sandbox_enable_strict_if_allowed(int src_fd lzma_attribute((__unused__)),
|
||||||
if (!prepare_for_strict_sandbox())
|
if (!prepare_for_strict_sandbox())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// All files that need to be opened have already been opened.
|
||||||
if (pledge("stdio", ""))
|
if (pledge("stdio", ""))
|
||||||
message_fatal(_("Failed to enable the sandbox"));
|
message_fatal(_("Failed to enable the sandbox"));
|
||||||
|
|
||||||
|
@ -222,6 +235,17 @@ sandbox_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern void
|
||||||
|
sandbox_enable_read_only(void)
|
||||||
|
{
|
||||||
|
// We will be opening files for reading but
|
||||||
|
// won't create or remove any files.
|
||||||
|
const uint64_t required_rights = LANDLOCK_ACCESS_FS_READ_FILE;
|
||||||
|
enable_landlock(required_rights);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
sandbox_enable_strict_if_allowed(int src_fd lzma_attribute((__unused__)),
|
sandbox_enable_strict_if_allowed(int src_fd lzma_attribute((__unused__)),
|
||||||
int pipe_event_fd lzma_attribute((__unused__)),
|
int pipe_event_fd lzma_attribute((__unused__)),
|
||||||
|
@ -254,6 +278,14 @@ sandbox_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern void
|
||||||
|
sandbox_enable_read_only(void)
|
||||||
|
{
|
||||||
|
// Nothing to do.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
sandbox_enable_strict_if_allowed(
|
sandbox_enable_strict_if_allowed(
|
||||||
int src_fd, int pipe_event_fd, int pipe_write_fd)
|
int src_fd, int pipe_event_fd, int pipe_write_fd)
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
extern void sandbox_init(void);
|
extern void sandbox_init(void);
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Enable sandboxing that only allows opening files for reading
|
||||||
|
extern void sandbox_enable_read_only(void);
|
||||||
|
|
||||||
|
|
||||||
/// \brief Tell sandboxing code that strict sandboxing can be used
|
/// \brief Tell sandboxing code that strict sandboxing can be used
|
||||||
///
|
///
|
||||||
/// This function only sets a flag which will be read by
|
/// This function only sets a flag which will be read by
|
||||||
|
|
Loading…
Reference in New Issue