Name

sydbox — ptrace based sandbox

Options

The following options are understood:

-h
Show usage and exit
-v
Show version and exit
-c pathspec
pathspec to the configuration file, may be repeated. See the section called “Configuration” for more information.
-m magic
Run a magic command during init, may be repeated. See the section called “Configuration” for more information.
-E var=val
Put var=val in the environment for command, may be repeated
-E var
Remove var from the environment for command, may be repeated

Configuration

Sydbox is configured through the so-called magic commands. There are three ways to supply magic commands:

  • Sydbox may be configured using a configuration file. The path to the configuration file is speficied using the -c command line switch or the SYDBOX_CONFIG environment variable. More than one configuration file may be specified this way. However, only the initial configuration file can change the core configuration. If path to the configuration file is prefixed with the character '@', Sydbox looks for this configuration file under $sharedir/sydbox/ where $sharedir is usually /usr/share. The command line switch has precedence over the SYDBOX_CONFIG environment variable.

  • Sydbox may be configured using magic stat(2) calls during runtime. This is achieved by calling stat() system call on the special path /dev/sydbox followed by the magic command. Note that runtime configuration is only possible if the magic lock is unset. The system call stat() was chosen as the magic call because it is practical to invoke using builtin shell commands like:

                test -e /dev/sydbox/core/sandbox/read:deny
              

    which enables read sandboxing for a shell running under Sydbox. It is also possible to query certain values using the return value of the magic stat(2):

                test -e '/dev/sydbox/core/sandbox/read?' && echo "read sandboxing on" || echo "read sandboxing off"
              

    Note

    Some of these shell builtins may actually call lstat(2) system call instead of stat(2) thus Sydbox makes sure to check lstat() system calls for magic commands as well.

Specifying Magic Commands

As mentioned in the section called “Configuration” Sydbox may be configured using the so-called magic commands. Format of the magic commands is simple:

          ${PREFIX}/section/of/option${OPERATION_CHARACTER}value
        

where ${PREFIX} is /dev/sydbox by default (may be altered at compile-time using SYDBOX_MAGIC_PREFIX definition). This prefix is only required for magic stat(), not for -m command line switch.

${OPERATION_CHARACTER} determines the operation of the magic command. Possible values are listed below:

:
This term is used to set a value. Value must be either a boolean, an integer or a string.
?
This term is used to query a value. Boolean values and certain other values may be queried.
+
This term is used to append to a string array.
-
This is used to remove an element from a string array.
!
This is used to execute a special sydbox command.

Commands

Sydbox recognizes the following magic commands:

core/sandbox/exec

type: string

default: false

query: yes

A string specifying how execve(2) system call should be sandboxed. See the section called “execve(2) Sandboxing” for more information.

core/sandbox/read

type: string

default: false

query: yes

A string specifying how read sandboxing should be done. See the section called “Read Sandboxing” for more information.

core/sandbox/write

type: string

default: false

query: yes

A string specifying how write sandboxing should be done. See the section called “Write Sandboxing” for more information.

core/sandbox/network

type: string

default: false

query: yes

A string specifying how network sandboxing should be done. See the section called “Network Sandboxing” for more information.

core/restrict/file_control

type: boolean

default: false

A boolean specifying whether potentially dangerous options to open(2) and fcntl(2) should be forbidden. These options include O_ASYNC, O_DIRECT and O_SYNC. In addition all fcntl(2) commands except F_GETFL, F_SETFL, F_SETOWN, F_SETLK, F_SETLKW, F_SETLK64, F_SETLKW64, F_SETFD, F_GETFD and F_DUPFD are forbidden as well.

core/restrict/shared_memory_writable

type: boolean

default: false

A boolean specifying whether writable shared memory mapping ( mmap2(2) with PROT_WRITE & MAP_SHARED combination ) should be forbidden.

core/whitelist/per_process_directories

type: boolean

default: true

A boolean specifying whether per-process directories like /proc/$pid should automatically be whitelisted.

core/whitelist/successful_bind

type: boolean

default: true

A boolean specifying whether the socket address arguments of successful bind(2) calls should be whitelisted for connect(2) and sendto(2) system calls.

core/whitelist/unsupported_socket_families

type: boolean

default: true

A boolean specifying whether unknown socket families should be allowed access when network sandboxing is on.

core/violation/decision

type: string

default: deny

A string specifying the decision to take when an access violation occurs. Possible values are kill, killall and deny. Default is deny which means to deny the system call and resume execution.

core/violation/exit_code

type: integer

default: -1

An integer specifying the exit code in case core/violation/decision is killall. As a special case, if this integer is equal to zero, sydbox exits with 128 added to the eldest process' exit value in case an access violation has occured. This special case is meant for program tests to check whether an access violation has occured using the exit code.

core/violation/raise_fail

type: boolean

default: false

A boolean specifying whether certain failures like errors during path resolution should be treated as access violations. Note this is just a switch for reporting, the access to the system call is denied nevertheless.

core/violation/raise_safe

type: boolean

default: false

A boolean specifying whether certain violations which are considered safe should be reported. For example, mkdir(2) is a system call which fails when it can not create an existant directory. In this special case, sydbox denies the system call with EEXIST for consistency and does not raise an access violation in case core/violation/raise_safe is set to false. Other examples are, the access(2) system call which is silently denied with EACCES and listxattr(2), and llistxattr(2) system calls which are silently denied with ENOTSUP if this option is set to false.

core/trace/follow_fork

type: boolean

default: true

A boolean specifying whether Sydbox should follow forks, vforks and clones.

core/trace/exit_kill

type: boolean

default: false

A boolean specifying whether traced processes should be killed when Sydbox exits.

core/trace/magic_lock

type: string

default: off

A string specifying the state of the magic lock. Possible values are on, off and exec. If magic lock is on no magic commands are allowed. Note, the magic lock is tracked per-process. If exec is specified, the magic lock is set to on when the process returns from the system call execve(2).

core/trace/use_seccomp

type: boolean

default: false

A boolean specifying whether seccomp user-mode filters should be used. This works only on Linux-3.5 or newer and sydbox must be compiled with the --enable-seccomp configure option.

core/trace/use_seize

type: boolean

default: false

A boolean specifying whether sydbox should use the new ptrace requests PTRACE_SEIZE and PTRACE_INTERRUPT to trace processes.

core/trace/use_toolong_hack

type: boolean

default: false

A boolean specifying whether sydbox should use a hack to determine working directories under a path longer than PATH_MAX.

core/match/case_sensitive

type: boolean

default: true

A boolean specifying the case sensitivity of pattern matching.

See the section called “Pattern Matching” for more information.

core/match/no_wildcard

type: string

default: literal

A string specifying how to match patterns with no '*' or '?' characters in them. Possible values are literal and prefix. With literal such patterns are matched literally, whereas with prefix Sydbox appends /*** to the end of such patterns to make them a prefix match. Implemented mostly to provide compatibility with sydbox-0 patterns.

See the section called “Pattern Matching” for more information.

exec/resume_if_match

type: string-array

default: [empty array]

This setting specifies a list of path patterns. If one of these patterns matches the resolved path of an execve(2) system call, the process in question is resumed. See the section called “Pattern Matching” for more information on wildmatch patterns.

Note

The initial execve(2) is not checked. Thus, if sydbox is called like:

                  $> sydbox -m exec/resume_if_match+/bin/sh -- /bin/sh
                

she will not execute the /bin/sh command.

Note

This functionality does not work with seccomp because once enabled, seccomp mode can not be disabled. If sydbox detaches from the process all observed system calls of the process will fail with ENOSYS. Due to this fact upon receiving this command when seccomp is enabled sydbox goes on to trace the process but stops sandboxing and frees all sandboxing related data structures of the process. The process is ignored. However, this workaround may not be enough for some cases, for example, when the process in question is a daemon and must resume its execution after sydbox exits. For such cases use cmd/exec.

exec/kill_if_match

type: string-array

default: [empty array]

This setting specifies a list of path patterns. If one of these patterns matches the resolved path of an execve(2) system call, the process in question is killed. See the section called “Pattern Matching” for more information on wildmatch patterns.

Note

The initial execve(2) is not checked. Thus, if sydbox is called like:

                  $> sydbox -m exec/kill_if_match+/bin/sh -- /bin/sh
                

she will execute the /bin/sh command.

filter/exec

type: string-array

default: [empty array]

Specifies a list of path patterns to filter for execve(2) sandboxing. See the section called “execve(2) Sandboxing” and the section called “Pattern Matching”.

filter/read

type: string-array

default: [empty array]

Specifies a list of path patterns to filter for read sandboxing. See the section called “Read Sandboxing” and the section called “Pattern Matching”.

filter/write

type: string-array

default: [empty array]

Specifies a list of path patterns to filter for write sandboxing. See the section called “Write Sandboxing” and the section called “Pattern Matching”.

filter/network

type: string-array

default: [empty array]

Specifies a list of network addresses to filter for network sandboxing. See the section called “Network Sandboxing” and the section called “Address Matching”.

whitelist/exec

type: string-array

default: [empty array]

Specifies a list of path patterns to whitelist for execve(2) sandboxing. See the section called “execve(2) Sandboxing” and the section called “Pattern Matching”.

whitelist/read

type: string-array

default: [empty array]

Specifies a list of path patterns to whitelist for read sandboxing. See the section called “Read Sandboxing” and the section called “Pattern Matching”.

whitelist/write

type: string-array

default: [empty array]

Specifies a list of path patterns to whitelist for write sandboxing. See the section called “Write Sandboxing” and the section called “Pattern Matching”.

whitelist/network/bind

type: string-array

default: [empty array]

Specifies a list of network addresses to whitelist for bind(2) network sandboxing. See the section called “Network Sandboxing” and the section called “Address Matching”.

whitelist/network/connect

type: string-array

default: [empty array]

Specifies a list of network addresses to whitelist for connect(2) and sendto(2) network sandboxing. See the section called “Network Sandboxing” and the section called “Address Matching”.

blacklist/exec

type: string-array

default: [empty array]

Specifies a list of path patterns to blacklist for execve(2) sandboxing. See the section called “execve(2) Sandboxing” and the section called “Pattern Matching”.

blacklist/read

type: string-array

default: [empty array]

Specifies a list of path patterns to blacklist for read sandboxing. See the section called “Read Sandboxing” and the section called “Pattern Matching”.

blacklist/write

type: string-array

default: [empty array]

Specifies a list of path patterns to blacklist for write sandboxing. See the section called “Write Sandboxing” and the section called “Pattern Matching”.

blacklist/network/bind

type: string-array

default: [empty array]

Specifies a list of network addresses to blacklist for bind(2) network sandboxing. See the section called “Network Sandboxing” and the section called “Address Matching”.

blacklist/network/connect

type: string-array

default: [empty array]

Specifies a list of network addresses to blacklist for connect(2) and connect(2) network sandboxing. See the section called “Network Sandboxing” and the section called “Address Matching”.

cmd/exec

type: command

default: none

Makes sydbox execute an external command without sandboxing. The program name and arguments must be separated with the US (unit separator, octal: 037) character. sydfmt(1) may be used to do this. Consult its manual page for more information.

Sandboxing

There are four sandboxing types:

  1. Read sandboxing

  2. Write sandboxing

  3. execve(2) sandboxing

  4. Network sandboxing

Sandboxing may have three states:

off

Sandboxing is off, none of the relevant system calls are checked and all access is allowed.

deny

Sandboxing defaults to deny, whitelists can be used to allow access.

allow

Sandboxing defaults to allow, blacklists can be used to deny access.

In addition, there are filters for every sandboxing to prevent Sydbox from reporting an access violation. Note, access is still denied in such cases.

Read Sandboxing

This sandboxing checks certain system calls for filesystem read access. If a system call tries to read a path, this attempt is reported and the system call is denied. See the section called “Write Sandboxing” for more information on how to customize this behaviour.

List of observed system calls are: access(2), faccessat(2), open(2), openat(2), listxattr(2), and llistxattr(2).

Address Matching

Sydbox has a simple address scheme to match network addresses. The addresses can be in the following forms:

unix:${PATTERN}

Specifies a UNIX socket path, ${PATTERN} specifies a path pattern. See the section called “Pattern Matching” for more information on path patterns.

unix-abstract:${PATTERN}

Specifies an abstract UNIX socket path, ${PATTERN} specifies a path pattern. See the section called “Pattern Matching” for more information on path patterns.

inet:${IPV4_ADDR}/${NETMASK}@${PORT_RANGE}

Specifies an IPV4 address. For more information, read the paragraph below.

inet6:${IPV6_ADDR}/${NETMASK}@${PORT_RANGE}

Specifies an IPV6 address. For more information, read the paragraph below.

/${NETMASK} may be omitted from inet: and inet6: addresses and ${PORT_RANGE} can in two forms: either an integer or a service name from the services(5) database. Either as as a single entity or as a range in the form BEGIN-END.

In addition there are some aliases, you may use instead of specifying an address:

LOOPBACK

Expanded to inet:127.0.0.0/8

LOOPBACK6

Expanded to inet6:::1/8

LOCAL

Expanded to four addresses as defined in RFC1918:

  • inet:127.0.0.0/8

  • inet:10.0.0.0/8

  • inet:172.16.0.0/12

  • inet:192.168.0.0/16

LOCAL6

Expanded to four addresses:

  • inet6:::1

  • inet6:fe80::/7

  • inet6:fc00::/7

  • inet6:fec0::/7

Examples

Below are examples of invocation and configuration of Sydbox.

Invocation Examples

Below are some invocation examples:

Allow all reads, deny read access to /etc/shadow:

          $> sydbox -E LC_ALL=POSIX \
                       -m core/sandbox/read:allow \
                       -m blacklist/read+/etc/shadow \
                       -- /bin/sh -c 'cat /etc/shadow'
          sydbox@3141592653: -- Access Violation! --
          sydbox@3141592653: process id=20926 (abi=0 name:`cat')
          sydbox@3141592653: cwd: `/home/alip'
          sydbox@3141592653: cmdline: `cat /etc/shadow'
          sydbox@3141592653: open(`/etc/shadow')
          cat: /etc/shadow: Operation not permitted
          $>
        

Deny all reads and writes, allow read access to /dev/zero and write access to /dev/full. The executable dd is not static in this case thus allow access to /lib64 where it will load its shared libraries from as well:

Note

On the system of the author the dd binary links only to libraries under /lib64, use ldd to check the linked libraries on your system.

Note

Note the quoting to escape shell expansion.

        $> sydbox -E LC_ALL=POSIX \
                     -m core/sandbox/read:deny \
                     -m core/sandbox/write:deny \
                     -m 'whitelist/read+/lib64/***' \
                     -m whitelist/read+/dev/zero \
                     -m whitelist/read+/dev/full \
                     -- dd if=/dev/zero of=/dev/full count=1
        dd: writing to '/dev/full': No space left on device
        1+0 records in
        0+0 records out
        0 bytes (0 B) copied, 0.000447024 s, 0.0 kB/s
        $>
      

Kill common bittorrent applications:

Note

The initial execve is not checked.

        $> sydbox -E LC_ALL=POSIX \
                     -m exec/kill_if_match+/usr/bin/ktorrent \
                     -m exec/kill_if_match+/usr/bin/rtorrent \
                     -- /bin/sh -c ktorrent
        sydbox@3141592653: callback_exec: kill_if_match pattern=`/usr/bin/ktorrent' matches execve path=`/usr/bin/ktorrent'
        sydbox@3141592653: callback_exec: killing process:3097 [abi:0 cwd:`/home/alip']
      

Execute a process without sandboxing so it will continue execution after sandboxing:

          $> ./sydbox -- sh -c 'stat "$(./sydfmt exec echo hello world)"'
          hello world
            File: ‘/dev/sydbox/cmd/exec!echo\037hello\037world’
            Size: 0               Blocks: 0          IO Block: 512    character special file
          Device: 0h/0d   Inode: 0           Links: 0     Device type: 1,3
          Access: (0666/crw-rw-rw-)  Uid: (    0/    root)   Gid: (    0/    root)
          $>