Limitazioni dell'ispezione dello stack


8

Questo è il seguito di Come funziona Stack Inspection? che esplora la nozione in modo più dettagliato

L'ispezione dello stack è un meccanismo per garantire la sicurezza nel contesto delle macchine virtuali JVM e CLR quando moduli di codice scaricati esternamente con diversi livelli di affidabilità possono essere eseguiti insieme. Le librerie di sistema hanno bisogno di un modo per distinguere tra chiamate originate da codice non attendibile e chiamate originate dall'applicazione attendibile stessa. Questo viene fatto associando al codice il principale corrispondente alla sua origine. Quindi le autorizzazioni di accesso vengono registrate nello stack e ogni volta che viene effettuata una chiamata a un metodo di sistema sensibile, lo stack viene attraversato per vedere se le autorizzazioni appropriate per l'entità che effettua la chiamata sono presenti nello stack.

Quali sono i limiti dell'ispezione dello stack? Quali meccanismi sono stati proposti per sostituirlo? Sono stati apportati cambiamenti significativi al modello da quando è stato introdotto alla fine degli anni '90?


Ho difficoltà a comprendere come funziona l'ispezione dello stack. Puoi per favore includere un link a una buona spiegazione?
Raffaello

@Raphael: bella domanda. Ho fatto una domanda: cs.stackexchange.com/questions/796/…
Dave Clarke,

1
Questo documento presenta alcuni limiti del Stack Inspection Model utilizzato in JVMs e Microsoft CLR (ma l'ho trovato ora e ho letto solo le conclusioni): research.microsoft.com/en-us/um/people/adg/Publications/…
Vor

Risposte:


6

L'ispezione dello stack è necessaria perché i programmi su JVM e CLR hanno accesso predefinito alle operazioni pericolose, quindi è necessario fare qualcosa per prevenire le catastrofi. Ad esempio, un programma non attendibile può fare riferimento a una libreria I / O e chiamarla:

using IO;
...
IO.DeleteFile("/home/foo/bla");

Quindi su ogni operazione pericolosa effettuata, dobbiamo verificare se è consentito. Con l'ispezione dello stack è generalmente complicato capire chi ha accesso a cosa. Inoltre rende difficili le ottimizzazioni come inline e tail call.

Un meccanismo superiore consiste nel non dare a ciascun programma l'accesso automatico alle operazioni pericolose in primo luogo. In questo modello non è possibile importare una libreria IO. L'unico modo per ottenere l'accesso a una libreria IO è se qualcun altro te lo ha dato. Questo si chiama sicurezza delle capacità. Un'introduzione può essere trovata qui .

Invece, scriveremmo il programma precedente in questo modo:

Main(IOLibrary IO){
  IO.DeleteFile("/home/foo/bla");
}

La libreria IO è un parametro per il punto di ingresso del programma, e questa è chiamata capacità (poiché consente di utilizzare alcune funzionalità, in questo caso per eseguire IO). Per essere in grado di eseguire questo programma, dobbiamo avere accesso a una funzionalità IO e avviare il programma chiamando Main(ourIOlibrary). Se stiamo eseguendo un programma non attendibile, semplicemente non gli passiamo la nostra libreria IO, poiché potrebbe utilizzare quella libreria per eliminare i nostri file. In alcuni casi vogliamo dare a un programma non attendibile un accesso limitato al filesystem. In tal caso creiamo un wrapper attorno alla nostra libreria IO che consente l'accesso solo a una determinata directory e passiamo quello al programma non attendibile invece che alla libreria IO completa

Quindi, se abbiamo bisogno di una capacità di I / O per invocare un programma che ha bisogno di una capacità di I / O, ciò significa anche che tutto ciò che ha invocato il nostro programma doveva avere accesso a una capacità di I / O per poterlo fornire a noi. Da dove proviene la sua capacità IO? Bene, alla fine c'è un punto in cui l'essere umano che gestisce il computer ha invocato un programma. Questo essere umano ha accesso a tutte le funzionalità del sistema, quindi è stato in grado di trasmettere la funzionalità IO. Se questo umano non si fida del programma che sta eseguendo, semplicemente non gli passerà la sua capacità di IO.

Probabilmente puoi facilmente immaginare altri tipi di funzionalità: accesso a Internet, accesso per disegnare elementi sullo schermo, ecc. Ad esempio un sistema di plug-in del browser sicuro potrebbe fornire una funzionalità grafica a un plug-in non attendibile che gli consente solo di dipingere la grafica in un rettangolo predefinito sulla pagina.


5

Una limitazione dell'ispezione dello stack come tradizionalmente implementata è che interrompe le chiamate di coda appropriate. In particolare, le implementazioni tipiche devono mantenere l'intero "stack" in ogni momento. Clements e Felleisen mostrano come risolvere questo problema usando una tecnica chiamata "segni di continuazione" nel loro articolo A Semantics ricorsivo di coda per ispezioni di stack in ESOP 2003.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.