Guia de variáveis

Introdução

Conforme explicado na página Visão geral, o código de host faz chamadas RPC para a biblioteca no modo sandbox. O sandbox resulta em uma separação de memória entre os processos e, assim, o código de host não pode acessar diretamente a memória na biblioteca em sandbox.

Para garantir que o código de host possa acessar variáveis e blocos de memória em um processo remoto e para simplificar a implementação do código de lógica principal, o SAPI fornece um conjunto abrangente de classes C++. No entanto, em muitos casos você também poderá usar tipos C nativos.

A necessidade dos tipos especiais (tipos SAPI) surge ao transmitir ponteiros para tipos simples e blocos de memória (estruturas, matrizes).

Por exemplo, ao chamar uma função usando um ponteiro, ele precisa ser convertido em um ponteiro correspondente dentro da memória da biblioteca em sandbox. O snippet de código abaixo ilustra esse cenário. Em vez de uma matriz de três números inteiros, é criado um objeto ::sapi::v::Array<int> que pode ser transmitido na chamada de API da Biblioteca em sandbox:

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

Para uma visão geral abrangente de todos os tipos SAPI disponíveis, revise os arquivos principais var_*.h no código-fonte do projeto SAPI. Esses arquivos de cabeçalho fornecem classes e modelos que representam vários tipos de dados, por exemplo:

  • ::sapi::v::UChar representa caracteres não assinados conhecidos
  • ::sapi::v::Array<int> representa uma matriz de números inteiros.

Tipos SAPI

Esta seção apresenta três tipos de SAPI que são comumente vistos no código de host.

Ponteiros SAPI

Se uma função a ser colocada no sandbox exigir a transmissão de um ponteiro, esse ponteiro precisará ser obtido de um dos métodos PtrXXX() abaixo. Esses métodos são implementados pelas classes de variáveis SAPI.

Tipos de ponteiro
::PtrNone() Não sincroniza a memória subjacente entre o processo do código de host e o processo da biblioteca em sandbox quando passado para uma função da API no modo sandbox.
::PtrBefore() Sincroniza a memória do objeto para o qual ele aponta antes da chamada de função da API no sandbox. Isso significa que a memória local da variável apontada será transferida para o processo da Biblioteca em sandbox antes de a chamada ser iniciada.
::PtrAfter() Sincroniza a memória do objeto para o qual aponta depois que a chamada de função da API no sandbox ocorre. Isso significa que a memória remota da variável apontada será transferida para a memória do processo do código de host após a conclusão da chamada.
::PtrBoth() Combina a funcionalidade de ::PtrBefore() e ::PtrAfter().

A documentação para ponteiros SAPI pode ser encontrada aqui.

Struct SAPI

O modelo ::sapi::v::Struct está documentado em var_struct.h. Ele fornece um construtor que pode ser usado para unir estruturas existentes. O SAPI Struct oferece todos os métodos descritos nos Ponteiros SAPI (link em inglês) para receber um objeto ::sapi::v::Ptr que pode ser usado para chamadas de bibliotecas em sandbox.

O snippet de código abaixo mostra uma estrutura que é iniciada e transmitida para uma chamada de função no modo sandbox no exemplo de zlib (link em inglês):

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 o struct tiver ponteiros, eles vão apontar para endereços no sandboxee. Em consequência, você terá que transferir os dados do Sandboxee antes que eles se tornem acessíveis para o código do host.

Matrizes SAPI

O modelo ::sapi::v::Array está documentado em var_array.h. Ele fornece dois construtores: um que pode ser usado para unir matrizes de elementos existentes e outro para criar dinamicamente uma matriz.

Este snippet de código (extraído do exemplo de soma) mostra o uso do construtor que envolve uma matriz que não pertence a esse objeto:

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

Este snippet de código mostra um exemplo do construtor usado para criar dinamicamente uma matriz:

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

A matriz SAPI fornece todos os métodos descritos em Ponteiros SAPI para obter um objeto ::sapi::v::Ptr que pode ser usado para chamadas de bibliotecas em sandbox.