aboutsummaryrefslogtreecommitdiff
path: root/safety.rst
diff options
context:
space:
mode:
Diffstat (limited to 'safety.rst')
-rw-r--r--safety.rst109
1 files changed, 109 insertions, 0 deletions
diff --git a/safety.rst b/safety.rst
new file mode 100644
index 0000000..61cca97
--- /dev/null
+++ b/safety.rst
@@ -0,0 +1,109 @@
+*************
+Memory Safety
+*************
+
+In general, Crowbar does its best to ensure that code will not exhibit any of the following memory errors (pulled from `Wikipedia's list of 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.
+
+.. _Wikipedia's list of memory errors: https://en.wikipedia.org/wiki/Memory_safety#Types_of_memory_errors
+
+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::
+
+ 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.
+
+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 idk
+
+Page fault
+----------
+
+bounds checking, dubious-pointer checking
+
+Use after free
+--------------
+
+``free(&x);`` will set ``x = NULL;``
+``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 idk
+
+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?