Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
SANDBOXFS(1)		     General Commands Manual		    SANDBOXFS(1)

NAME
     sandboxfs -- A virtual file system for sandboxing

SYNOPSIS
     sandboxfs [--allow who] [--cpu_profile path] [--input path] [--help]
	       [--mapping type:mapping:target] [--node_cache] [--output path]
	       [--reconfig_threads count] [--ttl duration] [--version]
	       [--xattrs] mount_point

DESCRIPTION
     sandboxfs	is  a  FUSE  file  system that exposes a combination of multiple
     files and directories from the host's file system in the form of a  virtual
     tree  with an arbitrary layout.  You can think of a sandbox as an arbitrary
     view into the host's file system with different access privileges	per  di-
     rectory.

     sandboxfs	is designed to allow running commands with limited access to the
     file system by using the virtual tree as their new root, and to do so  con-
     sistently across a variety of platforms.

     The  sandbox  instance  mounted at mount_point is initially configured with
     the mapping specifications provided via repeated  instances  of  --mapping.
     Once  running,  the  mount  point	can be reconfigured any number of times:
     sandboxfs listens for reconfiguration requests on	the  file  specified  by
     --input  and  reconfigures the mappings as requested, emiting a response on
     the file specified by --output.

     The following flags are recognized:

     --allow who
	   Specifies who should have access to the file system.  who must be one
	   of: `other' to indicate that everyone, including root, can access the
	   file system; `root' to indicate that only the current user  and  root
	   can access the file system; and `self' to indicate that only the cur-
	   rent user can access the file system.

	   The	default  value is `self' because the standard FUSE configuration
	   does not allow more relaxed permissions, and it would be  a	pity  if
	   you couldn't run sandboxfs successfully without additional configura-
	   tion.    To	 change   this	 behavior,   add  `user_allow_other'  to
	   /etc/fuse.conf	 on	   Linux	or	  set	     the
	   `vfs.generic.osxfuse.tunables.allow_other'  sysctl(8) tunable to 1 on
	   macOS.

	   Note that, at least on macOS, you  will  need  to  consider	granting
	   `other'  permissions if you intend to run signed binaries through the
	   sandbox.  This is because the amfid(8) daemon, which  implements  the
	   signature  validation,  runs  as a different user and must be able to
	   access the executables.

     --cpu_profile path
	   Enables CPU profiling and stores the pprof log  to  the  given  path.
	   This feature is only available if sandboxfs was built with gperftools
	   support  (i.e.  with  the  compile-time `profiler' feature).  Passing
	   this flag when support is not enabled results in an error.

     --input path
	   Points to the file from which to read new configuration requests,  or
	   `-'	(the  default) for stdin.  See the "Reconfigurations" subsection
	   for details on the contents and behavior of the input file.

     --help
	   Prints global help details and exits.  Specifying  this  flag  causes
	   all other valid flags and arguments to be ignored.

     --mapping type:mapping:target
	   Registers  a new mapping.  This flag can be given an arbitrary number
	   of times as long as the  same  mapping  is  not  repeated.	See  the
	   "Mapping  specifications"  subsection for details on how a mapping is
	   specified.

     --node_cache
	   Enables the path-based node cache, which causes nodes  to  be  reused
	   across  reconfigurations  when they map to the same underlying paths.
	   This should offer a performance boost when the same set of files  are
	   mapped  over  and  over again across different reconfiguration opera-
	   tions.

	   This cache used to be enabled by default but  it  turned  out  to  be
	   problematic.   For  example, on macOS, OSXFUSE seems to keep track of
	   the path where a node first appeared, which	causes	trouble  if  the
	   node disappears and then reappears in a different location (for exam-
	   ple, dladdr(3) returns invalid paths).  For this reason, the cache is
	   now	disabled by default but is still kept around in the code for ex-
	   perimentation.   The  cache	may  be  removed  in  a  future  release
	   altogether if these problems cannot be worked around.

     --output path
	   Points  to  the  file to which to write confirmations of reconfigura-
	   tion, or `-' (the default) for stdout.   See  the  "Reconfigurations"
	   subsection  for  details  on  the contents and behavior of the output
	   file.

     --ttl duration
	   Specifies how long the kernel is allowed to cache file metadata  for.
	   The	duration  is currently specified as a number of seconds followed
	   by the `s' suffix.

     --reconfig_threads count
	   Sets the number of threads to  use  to  process  reconfiguration  re-
	   quests.  Defaults to the number of logical CPUs in the system.

     --version
	   Prints  version  information  and exits.  Specifying this flag causes
	   all other valid flags and arguments to be ignored except for  --help,
	   which has priority over this one.

	   The first line printed to stdout is machine parseable and follows the
	   following structure:

		 sandboxfs MAJOR.MINOR[.ADDITIONAL OPTIONAL QUALIFIERS]

	   Programs automating invocations of sandboxfs can use this information
	   to determine the correct command-line syntax to use.

     --xattrs
	   Enables  support  for  extended attributes, which causes all extended
	   attribute operations to propagate to the underlying files.

	   When disabled (the default), the behavior of extended attribute oper-
	   ations is platform-dependent: they may either fail as  not  supported
	   or  they  may act as no-op stubs.  The reason is that this feature is
	   disabled by telling the kernel that none of these operations are  im-
	   plemented in sandboxfs, which then causes the kernel to never contact
	   the daemon for them.  Keeping extended attributes disabled can result
	   in a performance boost.

   Mapping specifications
     The basic concept behind a sandboxfs instance is the mapping specification.
     A	mapping specification defines how an arbitrary location within the sand-
     box relates to another arbitrary location on the host file system.  Mapping
     specifications have three components: the target, which is a path to a file
     or directory into the host file system (i.e. outside of the  mount  point);
     the  mapping, which is an absolute path within the mount point in which the
     target is exposed; and the type, which specifies  the  permissions  of  the
     mapping.

     The target must exist but the mapping may not: in particular, any path sub-
     components  of  the mapping that have not been previously mapped within the
     sandbox will be created as virtual read-only nodes.  This	means  that  the
     ordering of the mappings matters.

     For  example:  consider  a  sandboxfs  instance mounted onto /mnt that maps
     /my/custom/bin to the /usr/bin target.  With this setup, /mnt/my/custom/bin
     will expose the contents of the real /usr/bin directory.

     The following types are currently supported:

     ro    A read-only mapping.  The contents of the target are exposed verbatim
	   at the mapping point and they cannot be modified  through  the  mount
	   point.  Any write access will result in an EPERM.

     rw    A  read/write mapping.  The contents of the target are exposed verba-
	   tim at the mapping point and they can be modified at will through the
	   mount point.  Writes through the moint point are applied  immediately
	   to the underlying target directory.

   Reconfigurations
     While a mount point is live, sandboxfs listens for reconfiguration requests
     on  the  file  specified by --input and writes reconfiguration responses to
     the file specified by --output.  These two files  essentially  implement  a
     rudimentary RPC system subject to change.

     The  mount point can be configured any number of times while mounted, which
     allows for processes to efficiently change the view of the sandbox at  will
     without  having  to remount it.  Closing the input file causes sandboxfs to
     freeze its configuration and not accept any more requests for  reconfigura-
     tion, but the file system will continue to operate normally until it is ei-
     ther unmounted or signaled.

     Reconfiguration  requests can be issued at any time.  However, it is impos-
     sible for sandboxfs to properly deal with ongoing file system operations or
     with open file handles in a deterministic manner.	Due to this, the  behav-
     ior  of ongoing file system activity while a reconfiguration happens is un-
     specified but can be assumed to be stable (i.e.  sandboxfs will  not  dead-
     lock  nor crash).	As a result, it is highly recommended that you only send
     reconfiguration requests when you know that the file system is quiescent.

     Configuration requests are provided as a stream of JSON objects.  Each  re-
     quest  is	an  object with just one of the following keys: `CreateSandbox',
     which requests the creation of a new top-level directory with a  given  set
     of  mappings; and `DestroySandbox', which requests the deletion of the map-
     pings at an existing top-level directory.

     A `CreateSandbox' operation contains an object with three keys: `id' speci-
     fies the name of the top-level directory to create, `mappings' contains  an
     array  of	all mappings to apply within that directory, and `prefixes' con-
     tains a dictionary of all	new  prefixes  to  register  for  prefix-encoded
     paths.  Each mapping entry is an object with the following keys: `path' and
     `underlying_path',  which	define	the  mapping  paths;  `path_prefix'  and
     `underlying_path_prefix', which identify  the  prefixes  for  the	provided
     paths,  respectively;  and  `writable',  which  if  set to true indicates a
     read/write mapping.  The mapping must not yet exist  in  the  file  system.
     Each  entry in the prefixes dictionary is keyed by the numerical identifier
     of the prefix (supplied as a string due to JSON limitations), and the value
     is the absolute path for that prefix.

     Prefix-encoded paths serve to minimize the size of the requests  but  their
     use  is  optional.   To  specify  a path in its prefix-encoded form, `path'
     and/or  `underlying_path'	must  be  relative  and   `path_prefix'   and/or
     `underlying_path_prefix'  must  indicate  a positive non-zero integer.  The
     referenced prefix must be registered in the same request or a previous  re-
     quest,  but if the prefix is repeated across requests, it must point to the
     same location.  To avoid prefix-encoded form, paths must be  given  as  ab-
     solute and they need to reference the special prefix 0.

     A	`DestroySandbox' operation simply contains the `id' of a previously-cre-
     ated sandbox as a string.	The whole tree hierarchy is unmapped.

     Each configuration request is paired with a response, which are  also  pro-
     vided as a stream of JSON objects.  Each response is a map with an optional
     field, which corresponds to the identifier given in the request, and an op-
     tional `error' field, which is empty if the request was successful and con-
     tains  an error message otherwise.  Responses with a missing identifier in-
     dicate fatal failures during the reconfiguration (e.g. due to a syntax  er-
     ror) and are not recoverable.

     To  minimize  the	size of the requests, all fields support aliases and de-
     fault values as follows:

	   `CreateSandbox'	     Alias: `C'.
	   `DestroySandbox'	     Alias: `D'.
	   `id' 		     Alias: `i'.
	   `mappings'		     Alias: `m'.  Default value: empty array.
	   `prefixes'		     Alias: `q'.  Default value: empty object.
	   `path'		     Alias: `p'.
	   `path_prefix'	     Alias: `x'.  Default value: `0'.
	   `underlying_path'	     Alias: `u'.
	   `underlying_path_prefix'  Alias: `y'.  Default value: `0'.
	   `writable'		     Alias: `w'.  Default value: `false'.

EXIT STATUS
     sandboxfs exits with 0 if the file system was both  mounted  and  unmounted
     cleanly; 1 on a controlled error condition encountered during the execution
     of a command; or 2 on a usage error.

     Sending  a  termination  signal  to sandboxfs will cause the file system to
     exit in a controlled manner, ensuring that the mount point is released.  If
     the file system is busy, the signal will be queued until all open file  de-
     scriptors	on  the  file system are released at which point the file system
     will try to exit cleanly again.  Note that, due to  limitations  in  signal
     handling in Rust (which is the language in which sandboxfs is implemented),
     the  reception of a signal will cause sandboxfs to return 1 instead of ter-
     minating with a signal condition.

ENVIRONMENT
     sandboxfs recognizes the following environment variables:

     RUST_LOG
	   Sets the maximum level of logging messages sent to stderr.	Possible
	   values  include `error', `warn', `info' and `debug', though many more
	   syntaxes  are  supported.	See   the   documentation   for   Rust's
	   `env_logger' crate for more details.

     sandboxfs	may  recognize other standard Rust variables like RUST_BACKTRACE
     but the list above attempts to describe the ones a user may find most  use-
     ful.

EXAMPLES
   Command-line invocation
     This  example  configures	a sandbox that maps the whole host's file system
     but clears /tmp to point into a sandbox-specific writable directory:

	   sandboxfs --mapping=ro:/:/ --mapping=rw:/tmp:/tmp/fresh-tmp /mnt

   Reconfiguration request
     This example creates a new sandbox under /first with a single mapping  that
     will appear as /first/tmp and that is mapped to /tmp/abc; then deletes said
     sandbox,  and  then creates a different sandbox under /second with a single
     mapping that will appear as /foo/bar and that is mapped to /tmp/x/y:

	   [
	       {"CreateSandbox": {
		   "id": "first",
		   "mappings": [
		       {"path": "/tmp", "underlying_path": "/tmp/abc", "writable": true}
		   ]
	       }},
	       {"DestroySandbox": "first"}
	       {"CreateSandbox": {
		   "id": "second",
		   "mappings": [
		       {"path": "/foo/bar", "underlying_path": "/tmp/x/y",
			"writable": false}
		   ]
	       }}
	   ]

     When sending this request, we obtain the following response:

	   {"id": "first", "error": null}
	   {"id": "first", "error": null}
	   {"id": "second", "error": null}

   Prefix-encoded reconfiguration request
     This example is the same as  above,  but  this  time  using  prefix-encoded
     paths:

	   [
	       {"CreateSandbox": {
		   "id": "first",
		   "mappings": [
		       {"path": "", "path_prefix": 1,
			"underlying_path": "abc", "underlying_path_prefix": 1,
			"writable": true}
		   ],
		   "prefixes": {
		       "1": "/tmp"
		   }
	       }},
	       {"DestroySandbox": "first"}
	       {"CreateSandbox": {
		   "id": "second",
		   "mappings": [
		       {"path": "bar", "path_prefix": 2,
			"underlying_path": "x/y", "underlying_path_prefix": 1,
			"writable": false}
		   ],
		   "prefixes": {
		       "2": "/foo"
		   }
	       }}
	   ]

   Minimized reconfiguraton request
     This  example  is	the same as above, but this time using field aliases and
     default values to minimize the message:

	   [
	       {"C": {
		   "i": "first",
		   "m": [
		       {"p": "", "x": 1, "u": "abc", "y": 1, "w": true}
		   ],
		   "q": {
		       "1": "/tmp"
		   }
	       }},
	       {"D": "first"}
	       {"C": {
		   "i": "second",
		   "m": [
		       {"p": "bar", "x": 2, "u": "x/y", "y": 1}
		   ],
		   "q": {
		       "2": "/foo"
		   }
	       }}
	   ]

AUTHORS
     The sandboxfs was originally developed as a Go program  by  Pallav  Agarwal
     <pallavag@google.com>  with  guidance  from Julio Merino <jmmv@google.com>.
     The program was later reimplemented in Rust by the latter.

BUGS
     The following are known limitations of sandboxfs:

     *	 Hard links are not supported.

     *	 Mapping the same external file or directory under two	different  loca-
	 tions within the mount point results in undefined behavior.  Writes may
	 not  be  reflected at both mapped locations at the same time, which can
	 lead to data corruption.  This is true even for read-only mappings  be-
	 cause each separate view within the mount point may have cached differ-
	 ent  contents, returning different data than what's truly on disk.  Us-
	 ing --node_cache may help mitigate this issue but it doesn't always do.

     *	 The --allow root setting does not work on Linux; use --allow  other  as
	 the  alternative.  See https://github.com/bazil/fuse/issues/144 for de-
	 tails.

     *	 It is currently impossible to terminate  sandboxfs  cleanly  while  the
	 file  system is busy.	Signals received while the file system is in use
	 will be queued as described in "EXIT STATUS"  and  fatal  signals  will
	 cause sandboxfs to leak the mount point (possibly irrecoverably without
	 a reboot because of kernel bugs).

     *	 Any  explicitly-mapped  directories and any scaffold directories (those
	 directories that appear to represent intermediate path components  that
	 do  not exist anywhere else in the file system) cannot be removed.  At-
	 tempts to remove them will  result  in  a  "permission  denied"  error.
	 While	it  could be possible to implement some different behavior, this
	 is what sandboxfs currently exposes.  You may or may not consider  this
	 to be a bug.

     *	 If --node_cache is enabled, node data is cached in-memory for all files
	 accessed  through  a  sandboxfs instance in order to offer good perfor-
	 mance across reconfigurations.  However, this cache does not  currently
	 implement any expiration policy, which means that memory usage can grow
	 unboundedly if many different files are mapped and accessed through the
	 sandbox.

     *	 If  a	FIFO  is  used for -input, sandboxfs will block until a separate
	 process opens the FIFO for writing.  This happens even before the  file
	 system  starts serving, which means the file system is not usable until
	 the FIFO is opened.

     *	 While it is possible to reconfigure the entries of the  root  directory
	 of  a	running  file system, it is not possible to reconfigure the root
	 mapping itself to point to  a	different  location  or  to  change  its
	 writability properties.

     *	 Unmapping  entries doesn't fully work.  The FUSE library that sandboxfs
	 currently uses does not support sending cache invalidation requests  to
	 the  kernel,  which  means unmapped entries will not vanish immediately
	 from the file system.	You may be able to mitigate this  by  setting  a
	 low node TTL with the --ttl flag, but this doesn't work on macOS either
	 because OSXFUSE does not honor node TTLs.

     *	 Handling of extended attributes on open-but-deleted-files does not work
	 properly.   Those files will appear as if they didn't have any extended
	 attributes any longer, and attempts to modify them will fail.

FreeBSD ports 15.quarterly	 March 11, 2020 		    SANDBOXFS(1)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=sandboxfs&sektion=1&manpath=FreeBSD+Ports+15.1.quarterly>

home | help