mirror of
https://git.tukaani.org/xz.git
synced 2024-04-04 12:36:23 +02:00
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
3 changed files with 69 additions and 13 deletions
|
@ -223,21 +223,41 @@ main(int argc, char **argv)
|
|||
signals_init();
|
||||
|
||||
#ifdef ENABLE_SANDBOX
|
||||
// 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
|
||||
// or --list was used. Note that --test implies opt_stdout = true
|
||||
// but --list doesn't.
|
||||
// Read-only sandbox can be enabled if we won't create or delete
|
||||
// any files:
|
||||
//
|
||||
// This is obviously not ideal but it was easy to implement and
|
||||
// it covers the most common use cases.
|
||||
// - --stdout, --test, or --list was used. Note that --test
|
||||
// implies opt_stdout = true but --list doesn't.
|
||||
//
|
||||
// TODO: Make sandboxing work for other situations too.
|
||||
if (args.files_name == NULL && args.arg_count == 1
|
||||
&& (opt_stdout || strcmp("-", args.arg_names[0]) == 0
|
||||
|| opt_mode == MODE_LIST))
|
||||
// - Output goes to stdout because --files or --files0 wasn't used
|
||||
// and no arguments were given on the command line or the
|
||||
// arguments are all "-" (indicating standard input).
|
||||
bool to_stdout_only = opt_stdout || opt_mode == MODE_LIST;
|
||||
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
|
||||
|
||||
// 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
|
||||
sandbox_enable_strict_if_allowed(int src_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())
|
||||
return;
|
||||
|
||||
// All files that need to be opened have already been opened.
|
||||
if (pledge("stdio", ""))
|
||||
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
|
||||
sandbox_enable_strict_if_allowed(int src_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
|
||||
sandbox_enable_strict_if_allowed(
|
||||
int src_fd, int pipe_event_fd, int pipe_write_fd)
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
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
|
||||
///
|
||||
/// This function only sets a flag which will be read by
|
||||
|
|
Loading…
Reference in a new issue