Guida alle variabili

Introduzione

Come spiegato nella pagina Panoramica, il codice host effettua chiamate RPC alla libreria in sandbox. Il sandboxing comporta una separazione della memoria tra i processi, pertanto il codice host non può accedere direttamente alla memoria nella libreria in sandbox.

Per assicurarsi che il codice host possa accedere a variabili e blocchi di memoria in un processo remoto e per semplificare l'implementazione del codice della logica principale, SAPI fornisce un insieme completo di classi C++. Tuttavia, in molti casi potrai utilizzare anche i tipi C nativi.

La necessità dei tipi speciali (tipi SAPI) si presenta quando si passano puntatori a tipi semplici e blocchi di memoria (strutture, array).

Ad esempio, quando si chiama una funzione che accetta un puntatore, questo deve essere convertito in un puntatore corrispondente all'interno della memoria della libreria in modalità protetta. Lo snippet di codice riportato di seguito visualizza questo scenario. Anziché un array di tre numeri interi, viene creato un oggetto ::sapi::v::Array<int> che può essere passato nella chiamata API della libreria in modalità protetta:

int arr[3] = {1, 2, 3};
sapi::v::Array<int> sarr(arr, ABSL_ARRAYSIZE(arr));

Per una panoramica completa di tutti i tipi di SAPI disponibili, consulta i file di intestazione var_*.h nel codice sorgente del progetto SAPI. Questi file di intestazione forniscono classi e modelli che rappresentano vari tipi di dati, ad esempio:

  • ::sapi::v::UChar rappresenta caratteri non firmati noti
  • ::sapi::v::Array<int> rappresenta un array di numeri interi

Tipi di SAPI

Questa sezione introduce tre tipi di SAPI che si trovano comunemente nel codice host.

SAPI Pointers

Se una funzione da isolare nella sandbox richiede il passaggio di un puntatore, questo puntatore deve essere ottenuto da uno dei metodi PtrXXX() riportati di seguito. Questi metodi vengono implementati dalle classi di variabili SAPI.

Tipi di puntatore
::PtrNone() Non sincronizza la memoria sottostante tra il processo del codice host e il processo della libreria in modalità sandbox quando viene passato a una funzione API in modalità sandbox.
::PtrBefore() Sincronizza la memoria dell'oggetto a cui punta prima che venga eseguita la chiamata alla funzione API in sandbox. Ciò significa che la memoria locale della variabile puntata verrà trasferita al processo della libreria in sandbox prima dell'avvio della chiamata.
::PtrAfter() Sincronizza la memoria dell'oggetto a cui punta dopo la chiamata di funzione dell'API in sandbox. Ciò significa che la memoria remota della variabile puntata verrà trasferita alla memoria del processo del codice host dopo il completamento della chiamata.
::PtrBoth() Combina le funzionalità di ::PtrBefore() e ::PtrAfter().

La documentazione relativa ai puntatori SAPI è disponibile qui.

SAPI Struct

Il modello ::sapi::v::Struct è documentato in var_struct.h. Fornisce un costruttore che può essere utilizzato per racchiudere le strutture esistenti. SAPI Struct fornisce tutti i metodi descritti in SAPI Pointers per ottenere un oggetto ::sapi::v::Ptr che può essere utilizzato per le chiamate alle librerie in sandbox.

Lo snippet di codice riportato di seguito mostra una struttura che viene inizializzata e poi passata a una chiamata di funzione in modalità sandbox nell'esempio zlib:

sapi::v::Struct<sapi::zlib::z_stream> strm;

if (ret = api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION,
                             version.PtrBefore(), sizeof(sapi::zlib::z_stream));

Se la tua struttura esistente contiene puntatori, questi punteranno a indirizzi in Sandboxee. Di conseguenza, dovrai trasferire i dati di Sandboxee prima che diventino accessibili al codice host.

SAPI Arrays

Il modello ::sapi::v::Array è documentato in var_array.h. Fornisce due costruttori, uno che può essere utilizzato per racchiudere array esistenti di elementi e un altro per creare dinamicamente un array.

Questo snippet di codice (estratto dall'esempio sum) mostra l'utilizzo del costruttore che racchiude un array non di proprietà di questo oggetto:

int arr[10];
sapi::v::Array<int> iarr(arr, ABSL_ARRAYSIZE(arr));

Questo snippet di codice mostra un esempio del costruttore utilizzato per creare dinamicamente un array:

sapi::v::Array<uint8_t> buffer(PNG_IMAGE_SIZE(*image.mutable_data()));

SAPI Array fornisce tutti i metodi descritti in SAPI Pointers per ottenere un oggetto ::sapi::v::Ptr che può essere utilizzato per le chiamate alle librerie in sandbox.