bwrap 1.1.1 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +21 -0
- data/README.md +9 -0
- data/lib/bwrap/args/args.rb +33 -4
- data/lib/bwrap/args/bind/device.rb +48 -0
- data/lib/bwrap/args/bind/library.rb +63 -47
- data/lib/bwrap/args/bind.rb +39 -41
- data/lib/bwrap/args/construct.rb +27 -36
- data/lib/bwrap/args/environment.rb +5 -1
- data/lib/bwrap/args/features/ruby_binds.rb +3 -1
- data/lib/bwrap/args/features.rb +3 -4
- data/lib/bwrap/args/mount.rb +1 -7
- data/lib/bwrap/args/namespace.rb +25 -0
- data/lib/bwrap/args/network.rb +7 -2
- data/lib/bwrap/args/user.rb +36 -0
- data/lib/bwrap/bwrap.rb +58 -26
- data/lib/bwrap/config.rb +52 -9
- data/lib/bwrap/exceptions.rb +1 -0
- data/lib/bwrap/execution/exec.rb +78 -0
- data/lib/bwrap/execution/execute.rb +25 -43
- data/lib/bwrap/execution/execution.rb +77 -50
- data/lib/bwrap/execution/logging.rb +49 -0
- data/lib/bwrap/execution/popen2e.rb +84 -12
- data/lib/bwrap/execution.rb +1 -0
- data/lib/bwrap/resolvers/executable.rb +70 -0
- data/lib/bwrap/resolvers/library/base.rb +22 -0
- data/lib/bwrap/resolvers/library/library.rb +74 -0
- data/lib/bwrap/resolvers/library/llvm_readelf.rb +133 -0
- data/lib/bwrap/resolvers/library/musl.rb +54 -0
- data/lib/bwrap/resolvers/library.rb +12 -0
- data/lib/bwrap/resolvers/mime.rb +75 -0
- data/lib/bwrap/resolvers/resolvers.rb +7 -0
- data/lib/bwrap/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +29 -18
- metadata.gz.sig +0 -0
- data/lib/bwrap/args/bind/mime.rb +0 -65
- data/lib/bwrap/args/library.rb +0 -135
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 2d50d32e5158e20f7a5a1f75124c8b657a12b54b3392612d5aa11e9717add289
         | 
| 4 | 
            +
              data.tar.gz: 7ac4aede1519880cd7c4e48d233688d1fb0d2ade75e8dc202bd27969d9c28428
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 88dfdab0abd2342289724060107c1a8fcc681eac5a4b24f402e316cc8d4470e33cb9fe11f7be1072b2dc0b97f3b1fc10e7df92bce192f0de9de9978f423237c0
         | 
| 7 | 
            +
              data.tar.gz: 76fc0bd2dc04e98b3254a540813212a6b9fb7cba1b7c0f64f49a19577106eb0dc8efac79215e4f689a229e1bfce57e9b9ca0926347d552d28000aa815697892f
         | 
    
        checksums.yaml.gz.sig
    CHANGED
    
    | Binary file | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,26 @@ | |
| 1 1 | 
             
            # Changes
         | 
| 2 2 |  | 
| 3 | 
            +
            ## 1.3.1 (06.01.2023)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Renewed expired key
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            ## 1.3.0 (06.01.2023)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            NOTE: No gem was released due expired key.
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            * Introduced llvm-readelf as additional dependency for library resolution.
         | 
| 12 | 
            +
            * Fix library resolution on newer systems.
         | 
| 13 | 
            +
            * Made resolv.conf binding to require a configuration option.
         | 
| 14 | 
            +
            * Added option for --unshare-all (enabled by default, which is previous behaviour).
         | 
| 15 | 
            +
            * Return output of the command with Bwrap#run
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            ## 1.2.0 (20.07.2022)
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            * Properly throw execution failure exception
         | 
| 20 | 
            +
            * Config is now optional argument for Bwrap#initialize
         | 
| 21 | 
            +
            * Allow passing kwargs to Bwrap#run
         | 
| 22 | 
            +
            * Allow passing config to execute
         | 
| 23 | 
            +
             | 
| 3 24 | 
             
            ## 1.1.1 (07.06.2022)
         | 
| 4 25 |  | 
| 5 26 | 
             
            * Added Bwrap::Execution.popen2e
         | 
    
        data/README.md
    CHANGED
    
    | @@ -20,6 +20,15 @@ Or install it yourself as: | |
| 20 20 |  | 
| 21 21 | 
             
                $ gem install bwrap
         | 
| 22 22 |  | 
| 23 | 
            +
            Running system must have following executables present:
         | 
| 24 | 
            +
              - scanelf (from pax-utils)
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            Additionally, for musl executables and libraries, following are necessary:
         | 
| 27 | 
            +
              - ldd
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            Additionally, for glibc executables and libraries, following are necessary:
         | 
| 30 | 
            +
              - llvm-readelf
         | 
| 31 | 
            +
             | 
| 23 32 | 
             
            ## Usage
         | 
| 24 33 |  | 
| 25 34 | 
             
            For now this is under ongoing development, though semantic versioning will apply.
         | 
    
        data/lib/bwrap/args/args.rb
    CHANGED
    
    | @@ -10,12 +10,12 @@ require "bwrap/version" | |
| 10 10 | 
             
            module Bwrap::Args
         | 
| 11 11 | 
             
              # Used as container for arguments constructed via {Construct}.
         | 
| 12 12 | 
             
              #
         | 
| 13 | 
            -
              # Where  | 
| 14 | 
            -
              #  | 
| 13 | 
            +
              # Where `Hash` defaults to nil as default argument, {Args} defaults to
         | 
| 14 | 
            +
              # `Array`.
         | 
| 15 15 | 
             
              class Args < Hash
         | 
| 16 16 | 
             
                # Creates new instance of a hash for storing arguments.
         | 
| 17 17 | 
             
                #
         | 
| 18 | 
            -
                # Where  | 
| 18 | 
            +
                # Where `Hash` defaults to nil as default argument, {Args} defaults to
         | 
| 19 19 | 
             
                # `[]`.
         | 
| 20 20 | 
             
                #
         | 
| 21 21 | 
             
                # @see Hash#initialize
         | 
| @@ -31,9 +31,10 @@ module Bwrap::Args | |
| 31 31 | 
             
                #
         | 
| 32 32 | 
             
                # Following types are meant to be used, though everything is accepted:
         | 
| 33 33 | 
             
                # - :mount
         | 
| 34 | 
            +
                # - (and many others, they are not documented here)
         | 
| 34 35 | 
             
                #
         | 
| 35 36 | 
             
                # @param type [Symbol] Type of the argument
         | 
| 36 | 
            -
                # @ | 
| 37 | 
            +
                # @return self
         | 
| 37 38 | 
             
                def add(type, *data)
         | 
| 38 39 | 
             
                  if data.respond_to? :each
         | 
| 39 40 | 
             
                    self[type] += data.flatten
         | 
| @@ -43,5 +44,33 @@ module Bwrap::Args | |
| 43 44 |  | 
| 44 45 | 
             
                  self
         | 
| 45 46 | 
             
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                # Adds ugiven data to array identified by given type if they
         | 
| 49 | 
            +
                # have not been already added.
         | 
| 50 | 
            +
                #
         | 
| 51 | 
            +
                # Following types are meant to be used, though everything is accepted:
         | 
| 52 | 
            +
                # - :mount
         | 
| 53 | 
            +
                # - (and many others, they are not documented here)
         | 
| 54 | 
            +
                #
         | 
| 55 | 
            +
                # @param type [Symbol] Type of the argument
         | 
| 56 | 
            +
                # @return self
         | 
| 57 | 
            +
                def add_uniq(type, *data)
         | 
| 58 | 
            +
                  if data.respond_to? :each
         | 
| 59 | 
            +
                    self[type] |= data
         | 
| 60 | 
            +
                  else
         | 
| 61 | 
            +
                    self[type] << data unless include? data
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  self
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                # Adds a read-only bind to bind given path from host to same path inside sandbox.
         | 
| 68 | 
            +
                #
         | 
| 69 | 
            +
                # @see bwrap argument `--ro-bind`.
         | 
| 70 | 
            +
                #
         | 
| 71 | 
            +
                # TODO: doc for params
         | 
| 72 | 
            +
                def ro_bind(type, path)
         | 
| 73 | 
            +
                  add(type, %W{ --ro-bind #{path} #{path} })
         | 
| 74 | 
            +
                end
         | 
| 46 75 | 
             
              end
         | 
| 47 76 | 
             
            end
         | 
| @@ -0,0 +1,48 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "bwrap/output"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class Bwrap::Args::Bind
         | 
| 6 | 
            +
              # Device related binds.
         | 
| 7 | 
            +
              class Device
         | 
| 8 | 
            +
                include Bwrap::Output
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                # Instance of {Config}.
         | 
| 11 | 
            +
                attr_writer :config
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                # @param args [Args] Args created by {Construct}
         | 
| 14 | 
            +
                def initialize args
         | 
| 15 | 
            +
                  @args = args
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                # Arguments for mounting devtmpfs to /dev.
         | 
| 19 | 
            +
                def dev_mount
         | 
| 20 | 
            +
                  return unless @config&.dev_mount
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  debug "Mounting new devtmpfs to /dev"
         | 
| 23 | 
            +
                  @args.add :dev_mounts, "--dev", "/dev"
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                # Arguments to bind /dev/dri from host to sandbox.
         | 
| 27 | 
            +
                def bind_dev_dri
         | 
| 28 | 
            +
                  return unless @config&.graphics_acceleration
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  @args.add :dev_mounts, %w{ --dev-bind /dev/dri /dev/dri }
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                # Arguments to bind /sys/dev/char from host to sandbox.
         | 
| 34 | 
            +
                def bind_sys_dev_char
         | 
| 35 | 
            +
                  return unless @config&.graphics_acceleration
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  @args.add :dev_mounts, %w{ --ro-bind /sys/dev/char /sys/dev/char }
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                # Arguments to bind /sys/devices/pci0000:00 from host to sandbox.
         | 
| 41 | 
            +
                def bind_pci_devices
         | 
| 42 | 
            +
                  return unless @config&.graphics_acceleration
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  @args.add :dev_mounts, %w{ --ro-bind /sys/devices/pci0000:00 /sys/devices/pci0000:00 }
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
            end
         | 
| 48 | 
            +
             | 
| @@ -2,8 +2,9 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            require "bwrap/execution/path"
         | 
| 4 4 | 
             
            require "bwrap/output"
         | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 5 | 
            +
            require "bwrap/resolvers/executable"
         | 
| 6 | 
            +
            require "bwrap/resolvers/library"
         | 
| 7 | 
            +
            require "bwrap/resolvers/mime"
         | 
| 7 8 |  | 
| 8 9 | 
             
            class Bwrap::Args::Bind
         | 
| 9 10 | 
             
              # TODO: documentation
         | 
| @@ -21,22 +22,20 @@ class Bwrap::Args::Bind | |
| 21 22 | 
             
                include Bwrap::Execution::Path
         | 
| 22 23 | 
             
                include Bwrap::Output
         | 
| 23 24 |  | 
| 24 | 
            -
                # The command given to {Bwrap#run}.
         | 
| 25 | 
            -
                #
         | 
| 26 | 
            -
                # @see Bwrap::Args::Construct#command=
         | 
| 27 | 
            -
                #
         | 
| 28 | 
            -
                # @see (see Bwrap::Args::Construct#command=)
         | 
| 29 | 
            -
                attr_writer :command
         | 
| 30 | 
            -
             | 
| 31 25 | 
             
                # Instance of {Bwrap::Config}.
         | 
| 32 26 | 
             
                attr_writer :config
         | 
| 33 27 |  | 
| 34 28 | 
             
                # Instance of {Bwrap::Args::Environment}.
         | 
| 35 29 | 
             
                attr_writer :environment
         | 
| 36 30 |  | 
| 37 | 
            -
                 | 
| 31 | 
            +
                # Instance of {Bwrap::Resolvers::Executable}.
         | 
| 32 | 
            +
                attr_writer :executable
         | 
| 38 33 |  | 
| 39 | 
            -
                 | 
| 34 | 
            +
                # TODO: Remove?
         | 
| 35 | 
            +
                #attr_writer :executable_name
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                # TODO: Remove?
         | 
| 38 | 
            +
                #attr_writer :executable_path
         | 
| 40 39 |  | 
| 41 40 | 
             
                def initialize args
         | 
| 42 41 | 
             
                  @args = args
         | 
| @@ -45,29 +44,15 @@ class Bwrap::Args::Bind | |
| 45 44 | 
             
                def extra_executables_mounts
         | 
| 46 45 | 
             
                  return unless @config&.extra_executables
         | 
| 47 46 |  | 
| 48 | 
            -
                  @config.extra_executables.each do | | 
| 49 | 
            -
                     | 
| 50 | 
            -
                    @executable_path = resolve_executable_path @executable_name, not_inside_root: true
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                    @args.add :extra_executable_mounts, %W{ --ro-bind #{@executable_path} #{@executable_path} }
         | 
| 47 | 
            +
                  @config.extra_executables.each do |extra_executable|
         | 
| 48 | 
            +
                    executable = Bwrap::Resolvers::Executable.new extra_executable
         | 
| 53 49 |  | 
| 54 | 
            -
                     | 
| 50 | 
            +
                    generate_binds_for_command :extra_executable_mounts, executable, inside_root: false
         | 
| 55 51 | 
             
                  end
         | 
| 56 52 | 
             
                end
         | 
| 57 53 |  | 
| 58 | 
            -
                # Checks the command given to {Bwrap#run} and adds the libraries it needs.
         | 
| 59 | 
            -
                #
         | 
| 60 | 
            -
                # Convenience method to call {#resolve_executable_libraries}.
         | 
| 61 54 | 
             
                def handle_given_command
         | 
| 62 | 
            -
                   | 
| 63 | 
            -
                  @executable_path = resolve_executable_path @executable_name
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                  # Actually add the executable to be bound to the sandbox.
         | 
| 66 | 
            -
                  unless @config&.command_inside_root
         | 
| 67 | 
            -
                    @args.add :given_command, %W{ --ro-bind #{@executable_path} #{@executable_path} }
         | 
| 68 | 
            -
                  end
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                  resolve_executable_libraries
         | 
| 55 | 
            +
                  generate_binds_for_command :given_command, @executable
         | 
| 71 56 | 
             
                end
         | 
| 72 57 |  | 
| 73 58 | 
             
                # Does some inspection to find out libraries given executable needs in order to work.
         | 
| @@ -77,14 +62,15 @@ class Bwrap::Args::Bind | |
| 77 62 | 
             
                #
         | 
| 78 63 | 
             
                # @todo Ensure scanelf is available (and throw proper error if it is not, telling to not use
         | 
| 79 64 | 
             
                #   full_system_mounts option.)
         | 
| 80 | 
            -
                 | 
| 81 | 
            -
             | 
| 65 | 
            +
                #
         | 
| 66 | 
            +
                # @param executable_name [String] Executable to be run inside bwrap
         | 
| 67 | 
            +
                def resolve_executable_libraries executable_name, executable_path
         | 
| 68 | 
            +
                  debug "Resolving executable libraries of #{executable_path}"
         | 
| 82 69 |  | 
| 83 | 
            -
                   | 
| 84 | 
            -
                   | 
| 70 | 
            +
                  mime = Bwrap::Resolvers::Mime.new executable_name, executable_path
         | 
| 71 | 
            +
                  mime.resolve_mime_type
         | 
| 85 72 |  | 
| 86 | 
            -
                   | 
| 87 | 
            -
                  return unless mime.resolve_mime_type
         | 
| 73 | 
            +
                  return if shell_executable_binds mime
         | 
| 88 74 |  | 
| 89 75 | 
             
                  # TODO: Ideally mime stuff should be handled as config,
         | 
| 90 76 | 
             
                  # but then shebang parsing logic would be necessary to move to config classes.
         | 
| @@ -101,7 +87,7 @@ class Bwrap::Args::Bind | |
| 101 87 |  | 
| 102 88 | 
             
                  library_mounts = []
         | 
| 103 89 |  | 
| 104 | 
            -
                  library_object = ::Bwrap:: | 
| 90 | 
            +
                  library_object = ::Bwrap::Resolvers::Library.new
         | 
| 105 91 | 
             
                  libraries = library_object.libraries_needed_by mime.executable_path
         | 
| 106 92 |  | 
| 107 93 | 
             
                  # TODO: following is bad?
         | 
| @@ -110,7 +96,7 @@ class Bwrap::Args::Bind | |
| 110 96 | 
             
                    library_mounts << "--ro-bind" << library << library
         | 
| 111 97 | 
             
                  end
         | 
| 112 98 |  | 
| 113 | 
            -
                  @args. | 
| 99 | 
            +
                  @args.add_uniq :extra_executable_libraries, library_mounts
         | 
| 114 100 | 
             
                end
         | 
| 115 101 |  | 
| 116 102 | 
             
                # Some features, like {Bwrap::Config::Features::Nscd}, requires some binds
         | 
| @@ -124,22 +110,52 @@ class Bwrap::Args::Bind | |
| 124 110 | 
             
                  ruby_binds_for_features
         | 
| 125 111 | 
             
                end
         | 
| 126 112 |  | 
| 127 | 
            -
                private def  | 
| 128 | 
            -
                   | 
| 129 | 
            -
             | 
| 130 | 
            -
                  end
         | 
| 113 | 
            +
                private def shell_executable_binds mime
         | 
| 114 | 
            +
                  # TODO: Put this behind additional flag for extra control/sanity.
         | 
| 115 | 
            +
                  # Some executables are shell scripts and similar. For them we need to use the interpreter.
         | 
| 131 116 |  | 
| 132 | 
            -
                   | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 117 | 
            +
                  if mime.mime_type[0..6] != "text/x-"
         | 
| 118 | 
            +
                    # All is good as this is not an interpreter.
         | 
| 119 | 
            +
                  elsif mime.interpreter?
         | 
| 120 | 
            +
                    # TODO: For less unmessiness, this should be done before actual
         | 
| 121 | 
            +
                    #   handle_given_command() and extra_executable_mounts() are run.
         | 
| 122 | 
            +
                    #   I guess that needs some refactoring...
         | 
| 123 | 
            +
                    mime_executable = Bwrap::Resolvers::Executable.new mime.resolve_real_executable
         | 
| 124 | 
            +
                    generate_binds_for_command :extra_executable_mounts, mime_executable
         | 
| 125 | 
            +
                  else
         | 
| 126 | 
            +
                    warn "Executable #{mime.executable_name} was recognized as #{mime.mime_type} but does not have " \
         | 
| 127 | 
            +
                         "proper shebang line. Skipping automatic library mounts."
         | 
| 128 | 
            +
                    return true
         | 
| 135 129 | 
             
                  end
         | 
| 136 130 |  | 
| 137 | 
            -
                   | 
| 131 | 
            +
                  false
         | 
| 132 | 
            +
                end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                # @param executable [Bwrap::Resolvers::Executable] Executable to be resolved
         | 
| 135 | 
            +
                private def generate_binds_for_command args_flag, executable, inside_root: true
         | 
| 136 | 
            +
                  # Type can be :path or :symlink. It is not used for now.
         | 
| 137 | 
            +
                  executable.executable_paths.each do |path, _type|
         | 
| 138 | 
            +
                    executable_path = resolve_executable_path path, inside_root: inside_root
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                    # Actually add the executable to be bound to the sandbox.
         | 
| 141 | 
            +
                    if @config and !@config.command_inside_root
         | 
| 142 | 
            +
                      # Avoid double-binding the executable.
         | 
| 143 | 
            +
                      executable_dir = File.dirname(executable_path)
         | 
| 144 | 
            +
                      unless @config.binaries_from&.include? executable_dir
         | 
| 145 | 
            +
                        @args.ro_bind args_flag, executable_path
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                        # Also add the directory where the executable is to PATH, for convenience.
         | 
| 148 | 
            +
                        @environment.add_to_path executable_dir unless executable.absolute_path?
         | 
| 149 | 
            +
                      end
         | 
| 150 | 
            +
                    end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                    resolve_executable_libraries path, executable_path
         | 
| 153 | 
            +
                  end
         | 
| 138 154 | 
             
                end
         | 
| 139 155 |  | 
| 140 156 | 
             
                # @warning Requires environment paths to be resolved beforehand.
         | 
| 141 | 
            -
                private def resolve_executable_path executable_name,  | 
| 142 | 
            -
                  if @config&.command_inside_root.nil? or  | 
| 157 | 
            +
                private def resolve_executable_path executable_name, inside_root: true
         | 
| 158 | 
            +
                  if @config&.command_inside_root.nil? or !inside_root
         | 
| 143 159 | 
             
                    return which executable_name
         | 
| 144 160 | 
             
                  end
         | 
| 145 161 |  | 
    
        data/lib/bwrap/args/bind.rb
    CHANGED
    
    | @@ -3,6 +3,7 @@ | |
| 3 3 | 
             
            require "bwrap/execution"
         | 
| 4 4 | 
             
            require "bwrap/output"
         | 
| 5 5 | 
             
            require_relative "args"
         | 
| 6 | 
            +
            require_relative "bind/device"
         | 
| 6 7 | 
             
            require_relative "bind/library"
         | 
| 7 8 |  | 
| 8 9 | 
             
            # Bind arguments for bwrap.
         | 
| @@ -13,40 +14,21 @@ class Bwrap::Args::Bind | |
| 13 14 | 
             
              # Array of parameters passed to bwrap.
         | 
| 14 15 | 
             
              attr_writer :args
         | 
| 15 16 |  | 
| 16 | 
            -
              # The command given to {Bwrap#run}.
         | 
| 17 | 
            -
              #
         | 
| 18 | 
            -
              # @see Bwrap::Args::Construct#command=
         | 
| 19 | 
            -
              #
         | 
| 20 | 
            -
              # @see (see Bwrap::Args::Construct#command=)
         | 
| 21 | 
            -
              attr_writer :command
         | 
| 22 | 
            -
             | 
| 23 17 | 
             
              # Instance of {Bwrap::Config}.
         | 
| 24 18 | 
             
              attr_writer :config
         | 
| 25 19 |  | 
| 26 20 | 
             
              # Instance of {Bwrap::Args::Environment}.
         | 
| 27 21 | 
             
              attr_writer :environment
         | 
| 28 22 |  | 
| 29 | 
            -
              #  | 
| 30 | 
            -
               | 
| 31 | 
            -
                @args.add :dev_mounts, %w{ --dev-bind /dev/dri /dev/dri }
         | 
| 32 | 
            -
              end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
              # Arguments to bind /sys/dev/char from host to sandbox.
         | 
| 35 | 
            -
              def bind_sys_dev_char
         | 
| 36 | 
            -
                @args.add :dev_mounts, %w{ --ro-bind /sys/dev/char /sys/dev/char }
         | 
| 37 | 
            -
              end
         | 
| 38 | 
            -
             | 
| 39 | 
            -
              # Arguments to bind /sys/devices/pci0000:00 from host to sandbox.
         | 
| 40 | 
            -
              def bind_pci_devices
         | 
| 41 | 
            -
                @args.add :dev_mounts, %w{ --ro-bind /sys/devices/pci0000:00 /sys/devices/pci0000:00 }
         | 
| 42 | 
            -
              end
         | 
| 23 | 
            +
              # Instance of {Bwrap::Resolvers::Executable}.
         | 
| 24 | 
            +
              attr_writer :executable
         | 
| 43 25 |  | 
| 44 26 | 
             
              # Arguments to bind home directory from sandbox directory (`#{@config.sandbox_directory}/home`)
         | 
| 45 27 | 
             
              # as `/home/#{@config.user}`.
         | 
| 46 28 | 
             
              #
         | 
| 47 29 | 
             
              # @note Requires @config.user to be set.
         | 
| 48 30 | 
             
              def bind_home_directory
         | 
| 49 | 
            -
                return unless @config | 
| 31 | 
            +
                return unless @config&.user
         | 
| 50 32 |  | 
| 51 33 | 
             
                home_directory = "#{@config.sandbox_directory}/home"
         | 
| 52 34 |  | 
| @@ -71,28 +53,16 @@ class Bwrap::Args::Bind | |
| 71 53 | 
             
                #
         | 
| 72 54 | 
             
                # Or maybe the data should be calculated and these are excluded in
         | 
| 73 55 | 
             
                # Construct#bwrap_arguments?
         | 
| 74 | 
            -
                return  | 
| 56 | 
            +
                return if @config && !@config&.full_system_mounts
         | 
| 75 57 |  | 
| 76 58 | 
             
                @library_bind.handle_given_command
         | 
| 77 59 | 
             
              end
         | 
| 78 60 |  | 
| 79 61 | 
             
              # Arguments to read-only bind whole system inside sandbox.
         | 
| 80 62 | 
             
              def handle_system_mounts
         | 
| 81 | 
            -
                 | 
| 82 | 
            -
                binaries_from = @config.binaries_from
         | 
| 83 | 
            -
                binaries_from.each do |path|
         | 
| 84 | 
            -
                  bindir_mounts << "--ro-bind" << path << path
         | 
| 85 | 
            -
                end
         | 
| 86 | 
            -
                @environment.add_to_path binaries_from
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                @args.add :bindir, bindir_mounts
         | 
| 89 | 
            -
             | 
| 90 | 
            -
                if debug?
         | 
| 91 | 
            -
                  debug "Using following bindir mounts:\n" \
         | 
| 92 | 
            -
                        "#{bindir_mounts}\n" \
         | 
| 93 | 
            -
                        "(Odd is key, even is value)"
         | 
| 94 | 
            -
                end
         | 
| 63 | 
            +
                return unless @config&.binaries_from
         | 
| 95 64 |  | 
| 65 | 
            +
                bindir_mounts
         | 
| 96 66 | 
             
                libdir_mounts
         | 
| 97 67 |  | 
| 98 68 | 
             
                binds_for_features
         | 
| @@ -100,9 +70,19 @@ class Bwrap::Args::Bind | |
| 100 70 | 
             
                @library_bind.extra_executables_mounts
         | 
| 101 71 | 
             
              end
         | 
| 102 72 |  | 
| 73 | 
            +
              def device_binds
         | 
| 74 | 
            +
                device = Bwrap::Args::Bind::Device.new @args
         | 
| 75 | 
            +
                device.config = @config
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                device.dev_mount
         | 
| 78 | 
            +
                device.bind_dev_dri
         | 
| 79 | 
            +
                device.bind_sys_dev_char
         | 
| 80 | 
            +
                device.bind_pci_devices
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
             | 
| 103 83 | 
             
              # These are something user can specify to do custom --ro-bind binds.
         | 
| 104 84 | 
             
              def custom_read_only_binds
         | 
| 105 | 
            -
                return unless @config | 
| 85 | 
            +
                return unless @config&.ro_binds
         | 
| 106 86 |  | 
| 107 87 | 
             
                binds = []
         | 
| 108 88 | 
             
                @config.ro_binds.each do |source_path, destination_path|
         | 
| @@ -114,12 +94,30 @@ class Bwrap::Args::Bind | |
| 114 94 |  | 
| 115 95 | 
             
              # Performs cleanup operations after execution.
         | 
| 116 96 | 
             
              def cleanup
         | 
| 117 | 
            -
                Bwrap:: | 
| 97 | 
            +
                Bwrap::Resolvers::Library.clear_needed_libraries_cache
         | 
| 98 | 
            +
              end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              # Used by {#handle_system_mounts}.
         | 
| 101 | 
            +
              private def bindir_mounts
         | 
| 102 | 
            +
                bindir_mounts = []
         | 
| 103 | 
            +
                binaries_from = @config.binaries_from
         | 
| 104 | 
            +
                binaries_from.each do |path|
         | 
| 105 | 
            +
                  bindir_mounts << "--ro-bind" << path << path
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
                @environment.add_to_path binaries_from
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                @args.add :bindir, bindir_mounts
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                return unless debug? and !bindir_mounts.empty?
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                debug "Using following bindir mounts:\n" \
         | 
| 114 | 
            +
                      "#{bindir_mounts}\n" \
         | 
| 115 | 
            +
                      "(Odd is key, even is value)"
         | 
| 118 116 | 
             
              end
         | 
| 119 117 |  | 
| 120 118 | 
             
              # Used by {#handle_system_mounts}.
         | 
| 121 119 | 
             
              private def libdir_mounts
         | 
| 122 | 
            -
                return unless @config | 
| 120 | 
            +
                return unless @config&.libdir_mounts
         | 
| 123 121 |  | 
| 124 122 | 
             
                libdir_mounts = %w{
         | 
| 125 123 | 
             
                  --ro-bind /lib /lib
         | 
| @@ -139,9 +137,9 @@ class Bwrap::Args::Bind | |
| 139 137 |  | 
| 140 138 | 
             
              private def construct_library_bind
         | 
| 141 139 | 
             
                library_bind = Bwrap::Args::Bind::Library.new @args
         | 
| 142 | 
            -
                library_bind.command = @command
         | 
| 143 140 | 
             
                library_bind.config = @config
         | 
| 144 141 | 
             
                library_bind.environment = @environment
         | 
| 142 | 
            +
                library_bind.executable = @executable
         | 
| 145 143 |  | 
| 146 144 | 
             
                @library_bind = library_bind
         | 
| 147 145 | 
             
              end
         | 
    
        data/lib/bwrap/args/construct.rb
    CHANGED
    
    | @@ -3,13 +3,16 @@ | |
| 3 3 | 
             
            require "tempfile"
         | 
| 4 4 |  | 
| 5 5 | 
             
            require "bwrap/output"
         | 
| 6 | 
            +
            require "bwrap/resolvers/executable"
         | 
| 6 7 | 
             
            require_relative "args"
         | 
| 7 8 | 
             
            require_relative "bind"
         | 
| 8 9 | 
             
            require_relative "environment"
         | 
| 9 10 | 
             
            require_relative "features"
         | 
| 10 11 | 
             
            require_relative "machine_id"
         | 
| 11 12 | 
             
            require_relative "mount"
         | 
| 13 | 
            +
            require_relative "namespace"
         | 
| 12 14 | 
             
            require_relative "network"
         | 
| 15 | 
            +
            require_relative "user"
         | 
| 13 16 |  | 
| 14 17 | 
             
            # Constructs arguments for bwrap execution.
         | 
| 15 18 | 
             
            class Bwrap::Args::Construct
         | 
| @@ -18,6 +21,13 @@ class Bwrap::Args::Construct | |
| 18 21 |  | 
| 19 22 | 
             
              attr_writer :config
         | 
| 20 23 |  | 
| 24 | 
            +
              def initialize
         | 
| 25 | 
            +
                # If a key is not found, it is initialized with an empty array.
         | 
| 26 | 
            +
                @args = Bwrap::Args::Args.new
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                @executable = Bwrap::Resolvers::Executable.new
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 21 31 | 
             
              # Command that is executed inside bwrap sandbox.
         | 
| 22 32 | 
             
              #
         | 
| 23 33 | 
             
              # @note This is not used for anything vital, but some things, like
         | 
| @@ -25,17 +35,14 @@ class Bwrap::Args::Construct | |
| 25 35 | 
             
              #   additional data.
         | 
| 26 36 | 
             
              #
         | 
| 27 37 | 
             
              # @param value [Array, String] Command with arguments
         | 
| 28 | 
            -
               | 
| 29 | 
            -
             | 
| 30 | 
            -
              def initialize
         | 
| 31 | 
            -
                # If a key is not found, it is initialized with an empty array.
         | 
| 32 | 
            -
                @args = Bwrap::Args::Args.new
         | 
| 38 | 
            +
              def command= value
         | 
| 39 | 
            +
                @executable.command = value
         | 
| 33 40 | 
             
              end
         | 
| 34 41 |  | 
| 35 42 | 
             
              # Parses data given with {Config} so it can be outputted in proper
         | 
| 36 43 | 
             
              # order by {#bwrap_arguments}.
         | 
| 37 44 | 
             
              #
         | 
| 38 | 
            -
              # @note Command given to {Bwrap#run} is set to {Bind#command}.
         | 
| 45 | 
            +
              # @note Command given to {Bwrap#run} is set to {Bind#command=}.
         | 
| 39 46 | 
             
              def calculate
         | 
| 40 47 | 
             
                create_objects
         | 
| 41 48 |  | 
| @@ -51,16 +58,13 @@ class Bwrap::Args::Construct | |
| 51 58 | 
             
                @bind.handle_system_mounts
         | 
| 52 59 | 
             
                @features.feature_binds
         | 
| 53 60 | 
             
                @bind.custom_read_only_binds
         | 
| 54 | 
            -
                create_user_dir
         | 
| 55 | 
            -
                read_only_pulseaudio
         | 
| 56 | 
            -
                 | 
| 57 | 
            -
                @bind.bind_dev_dri
         | 
| 58 | 
            -
                @bind.bind_sys_dev_char
         | 
| 59 | 
            -
                @bind.bind_pci_devices
         | 
| 61 | 
            +
                @user.create_user_dir
         | 
| 62 | 
            +
                @user.read_only_pulseaudio
         | 
| 63 | 
            +
                @bind.device_binds
         | 
| 60 64 | 
             
                proc_mount
         | 
| 61 65 | 
             
                tmp_as_tmpfs
         | 
| 62 66 | 
             
                @bind.bind_home_directory
         | 
| 63 | 
            -
                @ | 
| 67 | 
            +
                @namespace.shares
         | 
| 64 68 | 
             
                @network.share_net
         | 
| 65 69 | 
             
                @network.hostname
         | 
| 66 70 | 
             
                @args.add :environment, @environment.environment_variables
         | 
| @@ -70,7 +74,7 @@ class Bwrap::Args::Construct | |
| 70 74 |  | 
| 71 75 | 
             
              # Returns arguments to pass to bwrap.
         | 
| 72 76 | 
             
              #
         | 
| 73 | 
            -
              # @note Command given to {Bwrap#run} is set to {Bind#command}.
         | 
| 77 | 
            +
              # @note Command given to {Bwrap#run} is set to {Bind#command=}.
         | 
| 74 78 | 
             
              def bwrap_arguments
         | 
| 75 79 | 
             
                args = []
         | 
| 76 80 |  | 
| @@ -124,11 +128,11 @@ class Bwrap::Args::Construct | |
| 124 128 | 
             
                @bind&.cleanup
         | 
| 125 129 | 
             
              end
         | 
| 126 130 |  | 
| 127 | 
            -
              # Used by {# | 
| 131 | 
            +
              # Used by {#calculate}.
         | 
| 128 132 | 
             
              private def create_objects
         | 
| 129 133 | 
             
                @bind = Bwrap::Args::Bind.new
         | 
| 130 134 | 
             
                @bind.args = @args
         | 
| 131 | 
            -
                @bind. | 
| 135 | 
            +
                @bind.executable = @executable
         | 
| 132 136 | 
             
                @bind.config = @config
         | 
| 133 137 |  | 
| 134 138 | 
             
                @environment = Bwrap::Args::Environment.new
         | 
| @@ -142,35 +146,22 @@ class Bwrap::Args::Construct | |
| 142 146 | 
             
                @machine_id = Bwrap::Args::MachineId.new
         | 
| 143 147 | 
             
                @machine_id.config = @config
         | 
| 144 148 |  | 
| 149 | 
            +
                @namespace = Bwrap::Args::Namespace.new @args
         | 
| 150 | 
            +
                @namespace.config = @config
         | 
| 151 | 
            +
             | 
| 145 152 | 
             
                @network = Bwrap::Args::Network.new @args
         | 
| 146 153 | 
             
                @network.config = @config
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                @user = Bwrap::Args::User.new @args
         | 
| 156 | 
            +
                @user.config = @config
         | 
| 147 157 | 
             
              end
         | 
| 148 158 |  | 
| 149 159 | 
             
              # Arguments for generating .Xauthority file.
         | 
| 150 160 | 
             
              private def xauthority_args
         | 
| 151 | 
            -
                return unless @config | 
| 161 | 
            +
                return unless @config&.xorg_application
         | 
| 152 162 |  | 
| 153 163 | 
             
                xauth_args = %W{ --ro-bind #{Dir.home}/.Xauthority #{Dir.home}/.Xauthority }
         | 
| 154 164 | 
             
                debug "Binding following .Xauthority file: #{Dir.home}/.Xauthority"
         | 
| 155 165 | 
             
                @args.add :xauthority, xauth_args
         | 
| 156 166 | 
             
              end
         | 
| 157 | 
            -
             | 
| 158 | 
            -
              # Arguments to create `/run/user/#{uid}`.
         | 
| 159 | 
            -
              private def create_user_dir
         | 
| 160 | 
            -
                trace "Creating directory /run/user/#{uid}"
         | 
| 161 | 
            -
                @args.add :user_dir, %W{ --dir /run/user/#{uid} }
         | 
| 162 | 
            -
              end
         | 
| 163 | 
            -
             | 
| 164 | 
            -
              # Arguments to bind necessary pulseaudio data for audio support.
         | 
| 165 | 
            -
              private def read_only_pulseaudio
         | 
| 166 | 
            -
                return unless @config.audio.include? :pulseaudio
         | 
| 167 | 
            -
             | 
| 168 | 
            -
                debug "Binding pulseaudio"
         | 
| 169 | 
            -
                @args.add :audio, %W{ --ro-bind /run/user/#{uid}/pulse /run/user/#{uid}/pulse }
         | 
| 170 | 
            -
              end
         | 
| 171 | 
            -
             | 
| 172 | 
            -
              # Returns current user id.
         | 
| 173 | 
            -
              private def uid
         | 
| 174 | 
            -
                Process.uid
         | 
| 175 | 
            -
              end
         | 
| 176 167 | 
             
            end
         | 
| @@ -27,6 +27,9 @@ class Bwrap::Args::Environment < Hash | |
| 27 27 |  | 
| 28 28 | 
             
                env_paths
         | 
| 29 29 |  | 
| 30 | 
            +
                # If nothing has been added to path, the map would result to empty --setenv.
         | 
| 31 | 
            +
                return self if empty?
         | 
| 32 | 
            +
             | 
| 30 33 | 
             
                map do |key, value|
         | 
| 31 34 | 
             
                  if key == "PATH" and value.respond_to? :join
         | 
| 32 35 | 
             
                    value = value.join ":"
         | 
| @@ -38,7 +41,7 @@ class Bwrap::Args::Environment < Hash | |
| 38 41 |  | 
| 39 42 | 
             
              # @return [Array] All environment paths added via {Config#add_env_path} and other parsing logic
         | 
| 40 43 | 
             
              def env_paths
         | 
| 41 | 
            -
                if @config.env_paths.respond_to? :each
         | 
| 44 | 
            +
                if @config and @config.env_paths.respond_to? :each
         | 
| 42 45 | 
             
                  self["PATH"] |= @config.env_paths
         | 
| 43 46 | 
             
                end
         | 
| 44 47 |  | 
| @@ -66,6 +69,7 @@ class Bwrap::Args::Environment < Hash | |
| 66 69 |  | 
| 67 70 | 
             
              # Ruby feature specific environment path handling.
         | 
| 68 71 | 
             
              private def ruby_env_paths
         | 
| 72 | 
            +
                return unless @config
         | 
| 69 73 | 
             
                return unless @config.features.ruby.enabled?
         | 
| 70 74 | 
             
                return unless @config.features.ruby.gem_env_paths?
         | 
| 71 75 |  | 
| @@ -1,5 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require "bwrap/resolvers/library"
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
            # Implementation for Ruby feature set.
         | 
| 4 6 | 
             
            #
         | 
| 5 7 | 
             
            # @api private
         | 
| @@ -33,7 +35,7 @@ class Bwrap::Args::Features::RubyBinds < Bwrap::Args::Features::BindsBase | |
| 33 35 | 
             
                ruby_config = @config.features.ruby.ruby_config
         | 
| 34 36 |  | 
| 35 37 | 
             
                library_mounts = []
         | 
| 36 | 
            -
                library = Bwrap:: | 
| 38 | 
            +
                library = Bwrap::Resolvers::Library.new
         | 
| 37 39 | 
             
                stdlib.each do |lib|
         | 
| 38 40 | 
             
                  path = "#{ruby_config["rubyarchdir"]}/#{lib}.so"
         | 
| 39 41 |  |