Skip to content

Commit

Permalink
Update GuardedMemcpy.md
Browse files Browse the repository at this point in the history
  • Loading branch information
mjp41 authored Mar 27, 2023
1 parent d8f174c commit 1077be0
Showing 1 changed file with 7 additions and 7 deletions.
14 changes: 7 additions & 7 deletions docs/security/GuardedMemcpy.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ So let's see how we detect this with snmalloc.

So `memcpy(dst, src, len)` copies `len` bytes from `src` to `dst`.
For this to be valid, we can check:
```
```C++
if (src is managed by snmalloc)
check(remaining_bytes(src) >= len)
check(remaining_bytes(src) >= len);
if (dst is managed by snmalloc)
check(remaining_bytes(dst) >= len)
check(remaining_bytes(dst) >= len);
```
Now, the first `if` is checking for reading beyond the end of the object, and the second is checking for writing beyond the end of the destination object.
By default, for release checks we only check the `dst` is big enough.
Expand All @@ -34,7 +34,7 @@ All slab sizes are powers of two, and a given slab's lowest address will be natu
That is if `x` is the start of a slab of size `2^n`, then `x % (2^n) == 0`.
This means that a single mask can be used to find the offset into a slab.
As the objects are layed out continguously, we can also get the offset in the object with a modulus operations, that is, `remaining_bytes(p)` is effectively:
```
```C++
object_size - ((p % slab_size) % object_size)
```

Expand All @@ -46,14 +46,14 @@ However, as `object_size` can be non-power-of-two values, we need to work a litt

When you have a finite domain, you can lower divisions into a multiply and shift.
By pre-calculating `c = (((2^n) - 1)/size) + 1`, the division `x / size` can instead be computed by
```
```C++
(x * c) >> n
```
The choice of `n` has to be done carefully for the possible values of `x`, but with a large enough `n` we can make this work for all slab offsets and sizes.

Now from division, we can calculate the modulus, by multiplying the result of the division
by the size, and then subtracting the result from the original value:
```
```C++
x - (((x * c) >> n) * size)
```
and thus `remaining_bytes(x)` is:
Expand Down Expand Up @@ -85,7 +85,7 @@ So we need a check for this case.

The finished assembly for checking the destination length in `memcpy` is:

```x86asm
```asm
<memcpy_guarded>:
mov rax,QWORD PTR [rip+0xbfa] # Load Chunk map base
test rax,rax # Check if chunk map is initialised
Expand Down

0 comments on commit 1077be0

Please sign in to comment.