Skip to content

Commit 1077be0

Browse files
authored
Update GuardedMemcpy.md
1 parent d8f174c commit 1077be0

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

docs/security/GuardedMemcpy.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ So let's see how we detect this with snmalloc.
1414

1515
So `memcpy(dst, src, len)` copies `len` bytes from `src` to `dst`.
1616
For this to be valid, we can check:
17-
```
17+
```C++
1818
if (src is managed by snmalloc)
19-
check(remaining_bytes(src) >= len)
19+
check(remaining_bytes(src) >= len);
2020
if (dst is managed by snmalloc)
21-
check(remaining_bytes(dst) >= len)
21+
check(remaining_bytes(dst) >= len);
2222
```
2323
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.
2424
By default, for release checks we only check the `dst` is big enough.
@@ -34,7 +34,7 @@ All slab sizes are powers of two, and a given slab's lowest address will be natu
3434
That is if `x` is the start of a slab of size `2^n`, then `x % (2^n) == 0`.
3535
This means that a single mask can be used to find the offset into a slab.
3636
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:
37-
```
37+
```C++
3838
object_size - ((p % slab_size) % object_size)
3939
```
4040

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

4747
When you have a finite domain, you can lower divisions into a multiply and shift.
4848
By pre-calculating `c = (((2^n) - 1)/size) + 1`, the division `x / size` can instead be computed by
49-
```
49+
```C++
5050
(x * c) >> n
5151
```
5252
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.
5353

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

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

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

0 commit comments

Comments
 (0)