You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/security/GuardedMemcpy.md
+7-7Lines changed: 7 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,11 +14,11 @@ So let's see how we detect this with snmalloc.
14
14
15
15
So `memcpy(dst, src, len)` copies `len` bytes from `src` to `dst`.
16
16
For this to be valid, we can check:
17
-
```
17
+
```C++
18
18
if (src is managed by snmalloc)
19
-
check(remaining_bytes(src) >= len)
19
+
check(remaining_bytes(src) >= len);
20
20
if (dst is managed by snmalloc)
21
-
check(remaining_bytes(dst) >= len)
21
+
check(remaining_bytes(dst) >= len);
22
22
```
23
23
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.
24
24
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
34
34
That is if `x` is the start of a slab of size `2^n`, then `x % (2^n) == 0`.
35
35
This means that a single mask can be used to find the offset into a slab.
36
36
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++
38
38
object_size - ((p % slab_size) % object_size)
39
39
```
40
40
@@ -46,14 +46,14 @@ However, as `object_size` can be non-power-of-two values, we need to work a litt
46
46
47
47
When you have a finite domain, you can lower divisions into a multiply and shift.
48
48
By pre-calculating `c = (((2^n) - 1)/size) + 1`, the division `x / size` can instead be computed by
49
-
```
49
+
```C++
50
50
(x * c) >> n
51
51
```
52
52
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.
53
53
54
54
Now from division, we can calculate the modulus, by multiplying the result of the division
55
55
by the size, and then subtracting the result from the original value:
56
-
```
56
+
```C++
57
57
x - (((x * c) >> n) * size)
58
58
```
59
59
and thus `remaining_bytes(x)` is:
@@ -85,7 +85,7 @@ So we need a check for this case.
85
85
86
86
The finished assembly for checking the destination length in `memcpy` is:
87
87
88
-
```x86asm
88
+
```asm
89
89
<memcpy_guarded>:
90
90
mov rax,QWORD PTR [rip+0xbfa] # Load Chunk map base
0 commit comments