Het artikel bespreekt de huidige beperkingen van de Rust Foreign Function Interface (FFI) bij het communiceren met C, waarbij men vaak moet vertrouwen op onveilige grenzen. De auteur stelt voor om een brug te bouwen naar Fil-C, een systeem dat C- en C++-code hercompileert met runtime-checks en capabilities, waardoor geheugenonveiligheid leidt tot een panic in plaats van een exploit.
Belangrijke punten uit het artikel:
- Economische prikkel: Door legacy C-code via Fil-C veilig maar trager te maken (vanwege runtime-controles), ontstaat er een prestatiereden om kritieke paden te herschrijven in Rust voor statische veiligheid en snelheid.
- Ecosysteem: Er wordt verwezen naar
filnix (een Nix cross-compilatieplatform) en soortgelijke initiatieven binnen de Zig-gemeenschap die streven naar een Fil ABI.
- Doel: De creatie van
extern "fil-c" om een volledig geheugenveilige grens tussen Rust en C te waarborgen, zonder terugval op onveilige 'Yolo-C' ABI's.
De auteur sluit af met een uitnodiging voor cross-ecosysteem samenwerking tijdens OceanSprint op Lanzarote.
Ik wil extern "fil-c"
We gebruiken Rust om geheugenveiligheid tijdens het compileren te bewijzen. Vervolgens steken we een onveilige grens over en vertrouwen we erop dat de C-bibliotheek zich houdt aan een contract dat geen van beide talen kan afdwingen. De legacy-code blijft hiermee de goedkope route, terwijl het herschrijven ervan de dure weg is.
Fil-C biedt een interessantere afspraak. Het hercompileert C en C++ met capabilities, runtime-checks en een concurrente garbage collector. Schendingen van de geheugenveiligheid leiden tot een panic in plaats van dat ze exploits worden. Bestaande software vereist vaak weinig tot geen wijzigingen in de broncode, maar betaalt voor deze veiligheid tijdens de runtime.
Ik wil een Rust FFI die spreekt via de Fil-C ABI.
De eerste versie zou doelbewust beperkt kunnen zijn: scalaire waarden, gekopieerde strings en slices, en ondoorzichtige (opaque) handles. Het zou veilige Rust-wrappers genereren, de volledige C-afhankelijkheidsgrafiek compileren met Fil-C, en geen ontsnappingsroute terugbieden naar gewoon onveilig C. Gedeeld geheugen zou later kunnen volgen, zodra de brug in staat is om Fil-C een capability te geven die Rust betrouwbaar kan intrekken.
Dit is geen nieuwe optie voor bindgen. Fil-C is bron-compatibel met C, maar bewust niet ABI-compatibel; de gewone Rust extern "C" spreekt namelijk de ABI die Fil-C "Yolo-C" noemt. Het bouwen van de brug betekent dat we Rust, Fil-C, of een paar gegenereerde stubs moeten leren hoe ze waarden kunnen uitwisselen zonder de garanties van Fil-C te verliezen. Als dit gemakkelijk was, zou het al bestaan.
Een belangrijk onderdeel van deze stack is al in ontwikkeling. filnix verpakt Fil-C als een Nix cross-compilatieplatform en heeft poorten voor meer dan 100 nixpkgs-pakketten. Door Fil-C als platform te behandelen, bouwt Nix de transitieve afhankelijkheidsstructuur opnieuw op voor de Fil-C ABI, in plaats van per ongeluk gewone C daarin te linken. filnix is nog niet de Rust-brug, maar het biedt de reproduceerbare toolchain, het pakkettenuniversum en de testomgeving waarbinnen zo'n brug gebouwd kan worden.
Zig benadert hetzelfde probleem vanuit een andere hoek. Andrew Kelley heeft een optionele Fil ABI voorgesteld, geïnspireerd door Fil-C. Dit zou een onafhankelijke implementatie zijn in de Zig-compiler en standaardbibliotheek, bedoeld om een Zig-programma en de volledige C- en C++-afhankelijkheidsboom te compileren met runtime-geheugenveiligheid. Dat komt opvallend dicht in de buurt van de wereld waar een Rust-brug in zou moeten treden.
Het resultaat zou ons precies de juiste prikkels geven: we kunnen Rust gebruiken voor veiligheid tijdens het compileren, en vervolgens een prestatieboete betalen voor het gebruik van C.
Behoud je de legacy-bibliotheek? Dan blijft deze geheugenveilig, maar wordt elke pointer-operatie gecontroleerd en neemt het geheugen deel aan garbage collection. Schrijf je het kritieke pad (hot path) in Rust? Dan worden die controles statisch en verdwijnt de "belasting". C wordt daarmee het veilige compatibiliteitspad in plaats van het permanente snelle pad.
"100% veilig" betekent hier dat het geheugenveilig is over de gehele ondersteunde grens, niet dat het vrij is van logische bugs, deadlocks of slechte API's. Die grens is het lastige gedeelte. Fil-C vereist momenteel dat het volledige programma en al zijn afhankelijkheden gebruikmaken van deze ABI.
Het project beschouwt interoperabiliteit met gewoon C als een non-goal. Een Rust-brug zou die garantie voor de gehele omgeving moeten behouden, in plaats van er stilletjes een "Yolo-vormig" gat in te ponsen.
Ik wil extern "fil-c": Rust op het snelle pad, oud C op het veilige pad, en een prestatiereden om de migratie te voltooien.
Ik zou ook graag cross-ecosysteem samenwerking willen zien in plaats van verschillende, bijna-compatibele eilanden. Fil-C heeft het capability-model en een werkende runtime. Rust heeft veiligheid tijdens het compileren. Zig verkent een door Fil-C geïnspireerde ABI. Nix en filnix kunnen volledige afhankelijkheidsgrafieken herbouwen en testen. Dit probleem verdient de beste geesten uit alle vier de gemeenschappen in dezelfde ruimte.
Daarom is hier de uitnodiging: sluit je volgend jaar aan bij OceanSprint op Lanzarote en bouw het samen. Mikael Brockman, die filnix bouwt, heeft al toegezegd.
Wie doet er nog meer mee?
Ik wil extern "fil-c"
We gebruiken Rust om geheugenveiligheid tijdens het compileren te bewijzen. Vervolgens steken we een onveilige grens over en vertrouwen we erop dat de C-bibliotheek zich houdt aan een contract dat geen van beide talen kan afdwingen. De legacy-code blijft hiermee de goedkope route, terwijl het herschrijven ervan de dure weg is.
Fil-C biedt een interessantere afspraak. Het hercompileert C en C++ met capabilities, runtime-checks en een concurrente garbage collector. Schendingen van de geheugenveiligheid leiden tot een panic in plaats van dat ze exploits worden. Bestaande software vereist vaak weinig tot geen wijzigingen in de broncode, maar betaalt voor deze veiligheid tijdens de runtime.
Ik wil een Rust FFI die spreekt via de Fil-C ABI.
De eerste versie zou doelbewust beperkt kunnen zijn: scalaire waarden, gekopieerde strings en slices, en ondoorzichtige (opaque) handles. Het zou veilige Rust-wrappers genereren, de volledige C-afhankelijkheidsgrafiek compileren met Fil-C, en geen ontsnappingsroute terugbieden naar gewoon onveilig C. Gedeeld geheugen zou later kunnen volgen, zodra de brug in staat is om Fil-C een capability te geven die Rust betrouwbaar kan intrekken.
Dit is geen nieuwe optie voor bindgen. Fil-C is bron-compatibel met C, maar bewust niet ABI-compatibel; de gewone Rust extern "C" spreekt namelijk de ABI die Fil-C "Yolo-C" noemt. Het bouwen van de brug betekent dat we Rust, Fil-C, of een paar gegenereerde stubs moeten leren hoe ze waarden kunnen uitwisselen zonder de garanties van Fil-C te verliezen. Als dit gemakkelijk was, zou het al bestaan.
Een belangrijk onderdeel van deze stack is al in ontwikkeling. filnix verpakt Fil-C als een Nix cross-compilatieplatform en heeft poorten voor meer dan 100 nixpkgs-pakketten. Door Fil-C als platform te behandelen, bouwt Nix de transitieve afhankelijkheidsstructuur opnieuw op voor de Fil-C ABI, in plaats van per ongeluk gewone C daarin te linken. filnix is nog niet de Rust-brug, maar het biedt de reproduceerbare toolchain, het pakkettenuniversum en de testomgeving waarbinnen zo'n brug gebouwd kan worden.
Zig benadert hetzelfde probleem vanuit een andere hoek. Andrew Kelley heeft een optionele Fil ABI voorgesteld, geïnspireerd door Fil-C. Dit zou een onafhankelijke implementatie zijn in de Zig-compiler en standaardbibliotheek, bedoeld om een Zig-programma en de volledige C- en C++-afhankelijkheidsboom te compileren met runtime-geheugenveiligheid. Dat komt opvallend dicht in de buurt van de wereld waar een Rust-brug in zou moeten treden.
Het resultaat zou ons precies de juiste prikkels geven: we kunnen Rust gebruiken voor veiligheid tijdens het compileren, en vervolgens een prestatieboete betalen voor het gebruik van C.
Behoud je de legacy-bibliotheek? Dan blijft deze geheugenveilig, maar wordt elke pointer-operatie gecontroleerd en neemt het geheugen deel aan garbage collection. Schrijf je het kritieke pad (hot path) in Rust? Dan worden die controles statisch en verdwijnt de "belasting". C wordt daarmee het veilige compatibiliteitspad in plaats van het permanente snelle pad.
"100% veilig" betekent hier dat het geheugenveilig is over de gehele ondersteunde grens, niet dat het vrij is van logische bugs, deadlocks of slechte API's. Die grens is het lastige gedeelte. Fil-C vereist momenteel dat het volledige programma en al zijn afhankelijkheden gebruikmaken van deze ABI.
Het project beschouwt interoperabiliteit met gewoon C als een non-goal. Een Rust-brug zou die garantie voor de gehele omgeving moeten behouden, in plaats van er stilletjes een "Yolo-vormig" gat in te ponsen.
Ik wil extern "fil-c": Rust op het snelle pad, oud C op het veilige pad, en een prestatiereden om de migratie te voltooien.
Ik zou ook graag cross-ecosysteem samenwerking willen zien in plaats van verschillende, bijna-compatibele eilanden. Fil-C heeft het capability-model en een werkende runtime. Rust heeft veiligheid tijdens het compileren. Zig verkent een door Fil-C geïnspireerde ABI. Nix en filnix kunnen volledige afhankelijkheidsgrafieken herbouwen en testen. Dit probleem verdient de beste geesten uit alle vier de gemeenschappen in dezelfde ruimte.
Daarom is hier de uitnodiging: sluit je volgend jaar aan bij OceanSprint op Lanzarote en bouw het samen. Mikael Brockman, die filnix bouwt, heeft al toegezegd.
Wie doet er nog meer mee?