Security Model

Zith provides strong safety guarantees without runtime overhead through its compile-time ownership system.

Memory Safety Guarantees

What Zith Prevents at Compile-Time

Vulnerability How Zith Prevents It
Use-after-free Ownership tracking via NRA ensures memory is valid
Double-free Unique ownership prevents multiple frees
Data races Mutability rules prevent concurrent writes
Buffer overflows Bounds checking (optional in release)
Null pointer dereference No null by default, use ?T types
Uninitialized memory Compiler enforces initialization

Ownership System (NRA)

Six Ownership Modifiers

default  // Default ownership, full control
lend     // Exclusive mutable borrow, temporary
view     // Read-only borrow, multiple allowed
unique   // Single owner, heap-allocated, movable
share    // Multiple mutable names, synchronized
belong   // Back-pointer, part-of relationship

Example: Safe Memory Access

fn processData() {
    var buffer: [u8] = [0; 1024];

    // Create read-only views (safe, multiple allowed)
    let header: view [u8] = buffer[0..64];
    let payload: view [u8] = buffer[64..];

    @println("Header: {header}");
    @println("Payload: {payload}");
}

Comparison with Other Languages

vs C/C++

// C - Manual, error-prone
void process() {
    int* ptr = malloc(sizeof(int) * 100);
    free(ptr);
    free(ptr);  //  Double-free! Undefined behavior
}
// Zith - Compile-time safety
fn process() {
    var ptr: [i32] = [0; 100];
}  //  Automatically freed, double-free impossible

vs Rust

// Rust - Powerful but complex lifetimes
fn process<'a>(data: &'a mut Vec<i32>, index: usize) -> &'a i32 {
    &data[index]  // Lifetime annotations required
}
// Zith - Simpler, implicit lifetimes
fn process(data: lend [i32], index: usize): view i32 {
    data[index]  //  No lifetime annotations needed
}

Unsafe Code

When you need to bypass safety checks:

unsafe {
    // Raw pointer operations
    let raw_ptr = alloc.raw_alloc(1024);

    // FFI calls
    libc::printf("Unsafe operation\n");
}  // You're responsible for safety here

Best Practice: Minimize unsafe blocks, isolate them, and document why they're safe.

Security Best Practices

1. Use Safe Abstractions

//  Good: Use safe collections
let vec = Vec{ 1, 2, 3 };

2. Leverage the Type System

struct NonZeroU32 {
    value: u32,  // Invariant: never zero

    fn new(v: u32): ?Self {
        if (v == 0) ? none
        else Self { value: v }
    }
}

3. Minimize Unsafe

fn safeWrapper() {
    unsafe {
        // Only the necessary unsafe operations
    }
}

4. Use Views for Borrowing

fn processLargeData(data: view [u8]) {
    // Read-only access, no copy
}

fn processLargeData(data: [u8]) {  // Copies entire array!

Limitations

Zith's safety model doesn't prevent:

Conclusion

Zith provides strong memory safety guarantees through its NRA ownership system, preventing entire classes of vulnerabilities at compile-time while maintaining zero runtime overhead.


Next: Compare with Rust