From 1f20ab0d5fe29276a6e55e8bd9aa3e1d967aafdf Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Sun, 25 Oct 2020 11:40:21 -0600 Subject: fucking windows line endings smdh --- safety.md | 184 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 92 insertions(+), 92 deletions(-) (limited to 'safety.md') diff --git a/safety.md b/safety.md index b8a2303..845c45b 100644 --- a/safety.md +++ b/safety.md @@ -1,92 +1,92 @@ -Each item in Wikipedia's [list of types of memory errors](https://en.wikipedia.org/wiki/Memory_safety#Types_of_memory_errors) and what Crowbar does to prevent them. - -In general, Crowbar does its best to ensure that code will not exhibit any of the following memory errors. -However, sometimes the compiler knows less than the programmer, and so code that looks dangerous is actually fine. -Crowbar allows programmers to suspend the memory safety checks with the `fragile` keyword. - -# Access errors - -## Buffer overflow - -Crowbar addresses buffer overflow with bounds checking. -In C, the type `char *` can point to a single character, a null-terminated string of unknown length, a buffer of fixed size, or nothing at all. -In Crowbar, the type `char *` can only point to either a single character or nothing at all. -If a buffer is declared as `char[50] name;` then it has type `char[50]`, and can be implicitly converted to `(char[50])*`, a pointer-to-50-chars. -If memory is dynamically allocated, it works as follows: - -```crowbar -void process(size_t bufferSize, char[bufferSize] buffer) { - // do some work with buffer, given that we know its size -} - -int main(int argc, (char[1024?])[argc] argv) { - size_t bufferSize = getBufferSize(); - (char[bufferSize])* buffer = malloc(bufferSize); - process(bufferSize, buffer); - free(buffer); -} -``` - -Note that `malloc` as part of the Crowbar standard library has signature `(void[size])* malloc(size_t size);` and so no cast is needed above. -In C, `buffer` in `main` would have type pointer-to-VLA-of-char, but `buffer` in `process` would have type VLA-of-char, and this conversion would emit a compiler warning. -However, in Crowbar, a `(T[N])*` is always implicitly convertible to `T[N]`, so no warning exists. -(This is translated into C by dereferencing `buffer` in `main`.) - -Note as well that the type of `argv` is complicated. -This is because the elements of `argv` have unconstrained size. -TODO figure out if that's the right way to handle that - -## Buffer over-read - -bounds checking again - -## Race condition - -uhhhhh 🤷‍♀️ - -## Page fault - -bounds checking, dubious-pointer checking - -## Use after free - -`free(x);` not followed by `x = NULL;` is a compiler error. -`owned` and `borrowed` keywords - -# Uninitialized variables - -forbid them in syntax - -## Null pointer dereference - -dubious-pointer checking - -## Wild pointers - -dubious-pointer checking - -# Memory leak - -## Stack exhaustion - -uhhhhhh 🤷‍♀️ - -## Heap exhaustion - -that counts as error handling, just the `malloc`-shaped kind - -## Double free - -this is just use-after-free but the use is calling free on it - -## Invalid free - -don't do that - -## Mismatched free - -how does that even happen - -## Unwanted aliasing - -uhhh don't do that? +Each item in Wikipedia's [list of types of memory errors](https://en.wikipedia.org/wiki/Memory_safety#Types_of_memory_errors) and what Crowbar does to prevent them. + +In general, Crowbar does its best to ensure that code will not exhibit any of the following memory errors. +However, sometimes the compiler knows less than the programmer, and so code that looks dangerous is actually fine. +Crowbar allows programmers to suspend the memory safety checks with the `fragile` keyword. + +# Access errors + +## Buffer overflow + +Crowbar addresses buffer overflow with bounds checking. +In C, the type `char *` can point to a single character, a null-terminated string of unknown length, a buffer of fixed size, or nothing at all. +In Crowbar, the type `char *` can only point to either a single character or nothing at all. +If a buffer is declared as `char[50] name;` then it has type `char[50]`, and can be implicitly converted to `(char[50])*`, a pointer-to-50-chars. +If memory is dynamically allocated, it works as follows: + +```crowbar +void process(size_t bufferSize, char[bufferSize] buffer) { + // do some work with buffer, given that we know its size +} + +int main(int argc, (char[1024?])[argc] argv) { + size_t bufferSize = getBufferSize(); + (char[bufferSize])* buffer = malloc(bufferSize); + process(bufferSize, buffer); + free(buffer); +} +``` + +Note that `malloc` as part of the Crowbar standard library has signature `(void[size])* malloc(size_t size);` and so no cast is needed above. +In C, `buffer` in `main` would have type pointer-to-VLA-of-char, but `buffer` in `process` would have type VLA-of-char, and this conversion would emit a compiler warning. +However, in Crowbar, a `(T[N])*` is always implicitly convertible to `T[N]`, so no warning exists. +(This is translated into C by dereferencing `buffer` in `main`.) + +Note as well that the type of `argv` is complicated. +This is because the elements of `argv` have unconstrained size. +TODO figure out if that's the right way to handle that + +## Buffer over-read + +bounds checking again + +## Race condition + +uhhhhh 🤷‍♀️ + +## Page fault + +bounds checking, dubious-pointer checking + +## Use after free + +`free(x);` not followed by `x = NULL;` is a compiler error. +`owned` and `borrowed` keywords + +# Uninitialized variables + +forbid them in syntax + +## Null pointer dereference + +dubious-pointer checking + +## Wild pointers + +dubious-pointer checking + +# Memory leak + +## Stack exhaustion + +uhhhhhh 🤷‍♀️ + +## Heap exhaustion + +that counts as error handling, just the `malloc`-shaped kind + +## Double free + +this is just use-after-free but the use is calling free on it + +## Invalid free + +don't do that + +## Mismatched free + +how does that even happen + +## Unwanted aliasing + +uhhh don't do that? -- cgit v1.2.3