aboutsummaryrefslogtreecommitdiff
path: root/notes/capabilities_and_io.txt
blob: 53f2970f122c21e0af501651fd5cbe94c58f0250 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

Capabilities and I/O
=====================

How to maintain security of capabilities when I/O and system calls are
allowed?

There are many attack vectors:

* Executing untrusted code
* Execution of commands with untrusted arguments
* Tampering with memory etc. via /proc
* Modifying e.g. .bashrc, .config/..., <repo>/.git/config
* Modifying or replacing executables.
* LD_PRELOAD etc.
* Connecting to services at localhost
* Connecting to unix sockets, pipes, etc.
* Somehow executing scripts that do the above.

seccomp is able to protect against this BUT it isn't always available and
sometimes one may want to execute non-SLUL commands.


Execution of untrusted code
---------------------------

Could block execution of non-root-owned executables. And non-SLUL code,
unless the capabilities of the executable has been defined (in a trusted
location).

A lesser strict way is to only allow things in $PATH / %PATH%.

For convenience, maybe there could be a `UncheckedExecutable` `giveme`
that would specify a name of an executable that can be executed without
any checks. BUT... this is incompatible with seccomp and would require
some separate forked process (forked prior to enabling sandboxing) that
would receive commands to execute via IPC (and check that they are
declared as `UncheckedExecutable`).


Execution of commands with untrusted arguments
----------------------------------------------

Could read the `giveme`s of executables (works only with those written in
SLUL), and ensure that they come from file arguments of the same "direction"
(input, output, read-write, ...). This requires that the there are no "Time
of Check - Time of Use" bugs, so most likely the executable and the directory
where it's located needs to be read-only. And this applies to targets of
symbolic links too.

To execute non-SLUL executables, it would be necessary to define which
capabilities they use (and keep this information in a trusted location).


Tampering with memory etc. via /proc
------------------------------------

Is there some fcntl, ioctl or similar to check if a file is a special
kernel file? Reading the mount points could work, but there may be race
conditions, and the information might be unavailable (e.g. if sandboxed).

On Linux, /proc/self/mem is "0 bytes" and is a "regular file". But normal
files could be empty too. But `fstat()` tells the *device* of the file
also. But that seems to be a dynamically allocated number, 0,x with
different x for /proc (and different x for different users if bind-mounted)
but also 0,x for /sys, /dev, /dev/shm and /tmp.


Modifying e.g. .bashrc, .config/..., <repo>/.git/config
-------------------------------------------------------

Could deny access to all dotfiles? But allow access to any dotfiles that
are explicitly allowed in the `giveme` section. Those could either reference
files in the current directory, or in a parent directory (e.g. like git
searches for `.git`, or ~/.config/appname/... or ~/.appname.

Perhaps only allow modification if the file has some application-specific
marker in it? E.g. a hash, UUID, pubkey-fingerprint, or similar?


Modifying or replacing executables
----------------------------------

Deny access to any directories in $PATH / %PATH%.

Deny access to adding directories to PATH.


LD_PRELOAD etc.
---------------

Simply block access to this environment variable. Or perhaps even all
environment variables, exception those listed in `giveme`s.


Connecting to services at localhost
-----------------------------------

Could disallow this, as well as LAN addresses, unless the application
specifially requests access to those subnets.


Connecting to unix sockets, pipes, etc.
---------------------------------------

Could check file type of fd immediately after opening a file.


Somehow executing scripts that do the above
-------------------------------------------

Maybe executed/interpreted CLI arguments should be a special `giveme`
in order for it to be possible to block passing a read-write file to an
interpreter.

This of course requires that the interpreter is either written in SLUL,
or that its capabilities have been defined. Other executables would have to
blocked by default.