Skip to content

Commit a54dae5

Browse files
committed
More tainting APIs use
1 parent 882443a commit a54dae5

File tree

2 files changed

+123
-39
lines changed

2 files changed

+123
-39
lines changed

src/chapters/advanced/raw-sandbox-pointers.md

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,7 @@ pointers of the form `char*`. Rather the pointers will be wrapped as
66
raw pointer into sandbox memory.
77

88
You can do this with the `unverified_safe_pointer_because` API. This converts a
9-
`tainted` pointer to a raw pointer with only minimal verification.
9+
`tainted` pointer to a raw pointer with only minimal verification of checking
10+
that the pointer is within the sandbox boundary.
1011

11-
`unverified_safe_pointer_because` takes two parameters. The first is the number
12-
of bytes in this pointer that you will be accessing. RLBox needs this to ensure
13-
that these many bytes of the pointer stay within the sandbox boundary. The
14-
second is a string, that allows the developer to document why they are doing
15-
this and why its safe. This string does not have any special meaning in the
16-
code. Rather the RLBox API asks you to provide a free-form string that acts as
17-
documentation. Essentially you are providing a string that says _it is safe to
18-
remove the tainting from this type because..._ . Such documentation may be
19-
useful to other developers who read your code.
20-
21-
```cpp
22-
tainted<char*> a = sandbox.malloc_in_sandbox(12);
23-
char* raw = a.unverified_safe_pointer_because(10, "Demo of a raw pointer");
24-
```
12+
The details of how to use this API are provided [here](/chapters/advanced/untainting-apis.md).

src/chapters/advanced/untainting-apis.md

Lines changed: 120 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ gives some flexibility to how you want to manage your data. So for example, you
1717
may be untainting an `int`, but can return an `unsigned int` or an `int*`, or
1818
`void` etc.
1919

20-
21-
## Tainted primitive/fundamental types
22-
23-
C/C++ defines the fundamental types as the types [built-in to the
20+
3. We will refer to the term fundamental types frequently. C/C++ defines the
21+
fundamental types as the types [built-in to the
2422
language](https://en.cppreference.com/w/cpp/language/types.html), such as `int`,
2523
`float` etc.
2624

25+
## Untainting fundamental types
26+
2727
These types can be untainted with a verifier of the following form
2828

2929
```cpp
@@ -34,13 +34,46 @@ These types can be untainted with a verifier of the following form
3434
});
3535
```
3636
37-
## Tainted byte buffers
37+
There maybe some scenarios where the application can handle any possible integer
38+
from the sandbox, i.e., the `<insert security checks here>` can be left empty.
39+
40+
- An example of this could be when you are calling an sandboxed library function
41+
that returns an integer 0 on success and a non-zero error code otherwise. From
42+
the host application perspective, you may do something if the returned value is
43+
0, and exit otherwise.
44+
45+
46+
In this scenario, RLBox provides a shorthand API called
47+
`unverified_safe_because` which can be used as follows.
48+
49+
```cpp
50+
tainted<int> a = ... ; //
51+
int a_verified = a.unverified_safe_because("Error code. App is robust to all values of error code");
52+
```
53+
54+
The `unverified_safe_because` API takes a string argument that allows the
55+
developer to document why they are doing this and why its safe. This string does
56+
not have any special meaning in the code. Rather the RLBox API asks you to
57+
provide a free-form string that acts as documentation. Essentially you are
58+
providing a string that says _it is safe to remove the tainting from this type
59+
because..._ . Such documentation may be useful to other developers who read your
60+
code. The above is equivalent to:
61+
62+
```cpp
63+
tainted<int> a = ... ; //
64+
int a_verified = a.copy_and_verify([](int val){
65+
// Error code. App is robust to all values of error code
66+
return val;
67+
});
68+
```
69+
70+
## Untainting byte buffers
3871
3972
Sometimes the sandbox returns a buffer that you want to untaint. For example,
4073
you may use a sandboxed XML parse to parse jpeg images. In this example, after
4174
the sandboxed library parses th image, it will produce a byte buffer with image
4275
pixels, probably of the type `tainted<char*>` or some other tainted pointer to a
43-
[fundamental type](https://en.cppreference.com/w/cpp/language/types.html).
76+
fundamental type.
4477
4578
These types can be untainted with a verifier of the following form
4679
@@ -52,8 +85,8 @@ These types can be untainted with a verifier of the following form
5285
}, size);
5386
```
5487

55-
This API copies `size` bytes out of the sandbox and applies the necessary checks
56-
like ensuring the entire buffer is coming from the sandbox memory.
88+
This API **copies** `size` bytes out of the sandbox and applies the necessary
89+
checks like ensuring the entire buffer is coming from the sandbox memory.
5790

5891
In the example of a sandboxed image decoder, the buffer may hold completely
5992
random data instead of pixels of the image. It is up to you to figure out what
@@ -63,7 +96,40 @@ sensible way to check that decoding has occurred correctly, and rather the rest
6396
of your program should be robust to showing an incorrect image on the screen. In
6497
this case, there would be no security check in place.
6598

66-
## Tainted C-strings
99+
100+
## Untainting byte buffers without copying
101+
102+
103+
There maybe some scenarios where the application can handle any possible byte
104+
buffer from the sandbox, i.e., the `<insert security checks here>` can be left
105+
empty.
106+
107+
- An example of this, would be if the image being displayed to the app in our
108+
sandboxed libjpeg example is say an application background and may not really
109+
matter.
110+
111+
In this case, we may want to use the byte before **without making a copy**, to
112+
avoid overheads.
113+
114+
RLBox provides aan API for this called `unverified_safe_pointer_because` which
115+
can be used as follows.
116+
117+
```cpp
118+
tainted<char*> a = ...;
119+
char* raw = a.unverified_safe_pointer_because(10, "Demo of a raw pointer");
120+
```
121+
122+
`unverified_safe_pointer_because` takes two parameters. The first is the number
123+
of bytes in this pointer that you will be accessing. RLBox needs this to ensure
124+
that these many bytes of the pointer stay within the sandbox boundary. The
125+
second is a string, that allows the developer to document why they are doing
126+
this and why its safe. This string does not have any special meaning in the
127+
code. Rather the RLBox API asks you to provide a free-form string that acts as
128+
documentation. Essentially you are providing a string that says _it is safe to
129+
remove the tainting from this type because..._ . Such documentation may be
130+
useful to other developers who read your code.
131+
132+
## Untainting C-strings
67133

68134
Untainting C-strings of type `tainted<char*>` is covered in the
69135
[tutorial](/chapters/tutorial/noop-sandbox/strings.md).
@@ -84,11 +150,7 @@ terminated, and makes a copy of the string that you can use.
84150
A useful check in `<insert security checks here>` is also to limit the size of
85151
the string you want to allow.
86152
87-
## Tainted one-level pointer to a primitive/fundamental type
88-
89-
C/C++ defines the fundamental types as the types [built-in to the
90-
language](https://en.cppreference.com/w/cpp/language/types.html), such as `int`,
91-
`float` etc.
153+
## Untainting one-level pointers to fundamental types
92154
93155
If you have a tainted pointer to a fundamental type such as `tainted<int*>`,
94156
`tainted<float*>` etc., these types can be untainted with a verifier of the
@@ -110,21 +172,55 @@ limited to tainted pointers to fundamental types.
110172

111173
This API is also limited to one-level pointers, i.e., things like
112174
`tainted<int*>` and is not allowed for `tainted<int**>`.
113-
<!--
114-
## Tainted array types
115175

116-
## Tainted struct types
176+
## Untainting just the "address bits" of a pointer
117177

118-
## Tainted one-level pointer to a struct types
178+
Your application may sometimes need just the raw bits of a tainted pointer
179+
without needing to look at the data being pointed to. An example of this would
180+
be if you want to maintain a hashmap of pointers in the class, but the pointers
181+
are produced by the sandbox.
119182

120-
## Tainted primitive/fundamental types that don't need verification
183+
```cpp
184+
tainted<int*> foo = sandbox.invoke_sandbox_function(...);
185+
186+
std::map<int*, int> my_map;
187+
my_map[foo] = 3; // RLBox gives a compiler error
188+
```
121189

122-
`unverified_safe_because`
190+
For this scenario, RLBox provides an API called `copy_and_verify_address` which
191+
takes a verifier that accepts a `uintptr_t`. This API can be used as follows.
123192

124-
## Tainted pointers that don't need verification
193+
```cpp
194+
tainted<int*> foo = sandbox.invoke_sandbox_function(...);
195+
196+
std::map<int*, int> my_map;
197+
uintptr_t foo_verified = foo.copy_and_verify_address([&](uintptr_t addr) {
198+
// <insert security checks here>
199+
return addr;
200+
});
201+
my_map[foo_verified] = 3;
202+
```
125203

126-
`unverified_safe_pointer_because`
204+
## Untainting C-arrays of fundamental types
127205

128-
## Untainting just the ``address'' bits of a pointer
206+
Untainting C-arrays of fundamental types like `tainted<int[3]>` is possible
207+
using `copy_and_verify`. Note, however, that the API expects the verifier to
208+
accept an argument of `std::array`, so that the data is correctly copied.
209+
210+
These types can be untainted with a verifier of the following form
211+
212+
```cpp
213+
tainted<int[3]> a = ... ; //
214+
std::array<int, 3> a_verified = a.copy_and_verify([](std::array<int, 3> val){
215+
// <insert security checks here>
216+
return val;
217+
});
218+
```
219+
220+
<!--
221+
222+
## Tainted struct types
223+
224+
## Tainted one-level pointer to a struct types
129225
130-
`copy_and_verify_address` -->
226+
-->

0 commit comments

Comments
 (0)