BRAIDGROUP
RESEARCH & DEV
31. Documentation

Security Model

Memory Safety via ARC

Braid uses Automatic Reference Counting (ARC) with cycle detection as its primary memory management strategy. Every heap-allocated object carries a reference count in its header:

struct Object {
    ObjType type;
    int ref_count;
    struct Object* next;
    bool marked;
};

ARC ensures objects are freed immediately when their reference count reaches zero, preventing dangling pointers. The gc_retain() and gc_release() calls are inserted throughout the VM to manage ownership precisely.

No Undefined Behavior

Braid's Hindley-Milner type system prevents type confusion at compile time. The VM enforces type safety at runtime with #if VM_SAFE guards that validate every stack operation, array index, and field access:

#if VM_SAFE
    if (current_vm->stack_top >= current_vm->stack + STACK_MAX) {
        runtime_error("VM: Stack overflow on push.");
        return;
    }
#endif

Division by zero, stack underflow, and out-of-bounds constant access are all caught at runtime with descriptive error messages.

Safe FFI via Extern Declarations

Braid provides two FFI mechanisms with different safety profiles:

  • extern fn — binds to C functions (e.g., extern fn sqrt(x: float) -> float); the programmer must ensure type signatures match
  • native fn — registered functions linked into the BraidVM runtime, wrapped with proper type marshalling

The module name validation in the VM (is_module_name_safe) prevents path traversal attacks by rejecting module names with special characters:

static bool is_module_name_safe(const char* module_name) {
    if (!module_name || module_name[0] == '\0') return false;
    for (const char* p = module_name; *p; p++) {
        if (!(isalnum(*p) || *p == '_' || *p == '.'))
            return false;
    }
    return true;
}

Sandboxed compiler.eval()

Runtime code compilation via std.compiler runs in a controlled environment. The module resolution path is scoped to the current project directory, and only safe character sequences are allowed in module names.

No Arbitrary Code Execution

Braid does not allow arbitrary code execution from untrusted sources. All code must go through the standard parse-validate-compile pipeline. The bytecode loader validates the magic header (BRAID), version, and chunk boundaries before execution.

ARC Cycle Detection

The next and marked fields in the Object header support a cycle collector. When ARC alone cannot free circular references (e.g., parent-child relationships), the cycle detector traverses the object graph, identifies cycles, and breaks them to allow deallocation.