Hopp til innhold
NorscodeNorscode

Lese og skrive filer

EksempelAv Norscode-prosjektet

Filhåndtering med kapabiliteter — og hvorfor programmet ditt ikke får lese det du ikke har gitt det.

Filoperasjoner krever kapabiliteter. Det er ikke i veien — det er poenget.

bruk std.fil som fil

funksjon start() -> heltall {
    fil.skriv("notat.txt", "Første linje\nAndre linje\n")
    la innhald = fil.les("notat.txt")
    la linjer = builtin.split(innhald, "\n")
    skriv("Antall linjer: " + tekst(lengde(linjer) - 1))
    returner 0
}

Hva som skjer her

Skrivefunksjonen oppretter fila hvis den ikke finnes, og skriver over hvis den gjør det. Lesefunksjonen gir deg hele innholdet som én tekst.

Legg merke til at det trekkes fra én i tellingen. Fila slutter med et linjeskift, så oppdelingen gir et tomt element til slutt. Det er en klassisk av-med-én-feil som fint passerer en test med to linjer og ødelegger for deg med tusen. Når du deler opp tekst på linjeskift, spør alltid deg selv om det siste elementet er ekte eller bare halen etter det siste skiftet.

Kjør med begrenset tilgang

NORSCODE_VM_CAPABILITIES="disk.read,disk.write" \
NORSCODE_VM_DISK_ROOT="$PWD" \
  nc run filer.no

Prøv å bryte ut

Bytt stien til noe utenfor NORSCODE_VM_DISK_ROOT — for eksempel systemets passordfil — og kjør på nytt. Programmet stopper med manglar capability.

Det er verdt å dvele ved hvorfor. Det finnes ikke noe API for å be om mer tilgang mens programmet kjører. Grensen settes av den som starter programmet, ikke av programmet selv. Et bibliotek du ikke har lest kan altså ikke nå lenger enn du har sluppet det — ikke fordi det oppfører seg pent, men fordi veien ikke finnes.

Sammenlign med hvordan dette vanligvis er: et program arver rettighetene til brukeren som startet det. En avhengighet fem lag ned i treet kan lese nøkkelfilene dine og sende dem ut på nettet, og du oppdager det ikke uten å granske hver linje.

I praksis

Sett NORSCODE_VM_DISK_ROOT så smalt som jobben tillater. Skal tjenesten bare lese konfigurasjon fra én katalog, gi den bare den katalogen — og bare disk.read, ikke disk.write. Det koster deg én linje i oppstartskommandoen, og gir deg en grense som holder selv om noe lenger nede i avhengighetstreet skulle ville noe annet.

Les også

Tilbake til oversikten