Unsafe "SLUL" ============= SLUL will not have any way to escape safety rules/checks. But in order to allow the runtime library to be written in "SLUL", it is necssary to allow unsafe code somehow. Solution: The "CrashFast" language ---------------------------------- Changes compared to SLUL: - File extension is .crhf (or maybe .yolo) - Main file is sysmain.crhf (sysmain.yolo) - Header starts with \crashfast (\yolo) instead of \slul - Unsafe features! Name of "CrashFast" ------------------- - CrashFast? - YoloLang? (with .yolo extension? and \yolo header?) - UhohLang? (.uhoh and \uhoh) - UnsafeLang? Preventing usage of "CrashFast" ------------------------------- Require some additional compiler options? cslul --__crash__fast_ --build-syslib --i-know-what-i-am-doing=ddf5f7e88fb39330d0bd cslul --language=_crash_fast --build-syslib --i-know-what-i-am-doing=ddf5f7e88fb39330d0bd /usr/local/lib/cslul/crashfast --build-syslib --i-know-what-i-am-doing=ddf5f7e88fb39330d0bd /usr/local/libexec/cslul/crashfast --build-syslib --i-know-what-i-am-doing=ddf5f7e88fb39330d0bd Perhaps use a wrapper, "/usr/bin/crashfast", that modifies the args? cslul --crash-fast=$(printf '\b') --build-syslib --i-know-what-i-am-doing=ddf5f7e88fb39330d0bd cslul --crash-fast=$(printf '\n') --build-syslib --i-know-what-i-am-doing=ddf5f7e88fb39330d0bd Best solution? - require the option "--__crash__fast_" ("--__caution__yololang_") - require either of "--freestanding" or "--hosted" - require a README.txt or README.md file that BEGINS with the following contents (with \n, \r\n, or \r endings) Warning ======= This code is written in the CrashFast programming language, which is a modified variant of SLUL that allows unsafe operations. CrashFast is only intended to be used for implementing the SLUL runtime library. WARNING: CrashFast code can have security exploits that allow code execution and/or allow bypassing security restrictions that would have been applied to normal SLUL code. Removal of this notice will prevent compilation! Unsafe features --------------- * Type casts * Making array length assumptions * Making ownership assumptions * Making boolean/null assumptions * Unchecked arithmetic * (Raw assembly?) * Raw hexcode * With macro support? * "Static if" for architecture detection Hexcode ------- Alt. 1: Similar to macros in C: hexconst R1 0x41 hexfunc ADDI(ra,rb,rc) emit(0x42, rc, ra, rb) func f(int x) { int y UNSAFE hexcode in(R0=x) out(y=R2) clobber(none) { ADDI(R2,R1,R1) } } Alt. 2: Very basic variant: hexcode ADDI__R2_R1_R1 0x42 0x42 0x41 0x41 func f(int x) { int y UNSAFE hexcode { hexsave r1 r2 hexld r1 x ADDI__R2_R1_R1 hexst r2 y hexrestore x } } Alt. 3: Very basic variant with funny names: hexconst ADDI__R2_R1_R1 0x42 0x42 0x41 0x41 func f(int x) { int y UNSAFE hexconst { hexfly r1 r2 hexld r1 x ADDI__R2_R1_R1 hexst r2 y hexland x } } Special entry points -------------------- _ifsys windows { func UNSAFE bare pe_entrypoint() noreturn { ... } } _elsesys linux { func UNSAFE bare _start() noreturn { ... } } Here, UNSAFE means that: 1. the following identifier is a special identifier, which creates some kind of special function. 2. the function can have special keywords ("bare" in this case) Static if --------- With special cases for all architectures: UNSAFE hexcode { _ifsys rv64 { hexsave r1 r2 hexld r1 x ADDI__R2_R1_R1 hexst r2 y hexrestore x } _elsesys aarch64 { ... } _elsesys i386 { ... } } With special cases for only some architectures: _ifsys rv64 { UNSAFE hexcode { hexsave r1 r2 hexld r1 x ADDI__R2_R1_R1 hexst r2 y hexrestore x } } _elsesys aarch64 { ... } _elsesys { } _ifsys/_elsesys could be handled in the tokenizer. For _ifsys/_elsesys it should be required to have { } in order to simplify the tokenizer! _ifsys/_elsesys have underscores in order to allow for future usage of ifsys/elsesys keywords in SLUL (which could have different semantics). UNSAFE syntax ------------- # Obviously unsafe features UNSAFE hexcode x86_64 { ... } UNSAFE assume p != none UNSAFE cast p ref Thing UNSAFE assume_own p UNSAFE assume_unown p [UNSAFE]int array func UNSAFE bare f() noreturn { ... } Should there be an "unassert" statement? unassert p != none unassert len < 5 # After this line, we can no longer assume that p!=none and that len<5 Also: Forcing a (re-)read or write of variables: _writemem obj1 UNSAFE(read) silently_use_obj1() UNSAFE(write) silently_modify_obj2() _readmem obj2 _volatile obj3 { UNSAFE(readwrite) silently_use_modify_obj3() } Alternative solution: Capabilities + Minimal assembly files ----------------------------------------------------------- Idea: Perhaps there could be capabilities that the "root arena" of the main module does not have? Perhaps an object called SlulSystem, which is never passed to SlulApp.main? (and which there is not way to obtain a reference to) slulrt public header: type SlulSystem slulrt_asm public header: type SysCallArg # p = pointer, z = size_t, i = int, o = off_t func SlulSystem.syscall_pziiio() func SlulSystem.syscall6( ref SysCallArg arg1, ref SysCallArg arg2, ref SysCallArg arg3, ref SysCallArg arg4, ref SysCallArg arg5, ref SysCallArg arg6, ) inside slulrt: type AnyData # private function! func SlulSystem.mmap(ref AnyData addr, usize length, int prot, int flags, int fd, fileoffs off) -> ref AnyData { ref SysCallArg ret = this.syscall6( .arg1=.from_anydata(addr), .arg2=.from_usize(length), .arg3=.from_int(prot), .arg4=.from_int(flags), .arg5=.from_int(fd), .arg6=.from_fileoffs(off)) return .from_sysret(ret) } Building slulrt: * assembly code -> slulrt_asm.o * slul code -> slulrt_slul.o * then these can be linked into libslulrt.so * should there be OS-specific parts? probably? (and both slul and asm parts)