Existe alguma maneira de definir uma variável de ambiente readonly?

3

Estou usando o seguinte no código openssh / telnet, que define o ambiente do usuário.

setenv("TEST_ENV", "testing", 1);

Mas isso pode ser modificado pelo usuário, existe alguma maneira de torná-lo apenas uma variável env?

    
por Ram 02.03.2013 / 07:00

2 respostas

6

Não há nada no ambiente de processo convencional para tornar uma variável somente leitura, apenas os shells têm esse conceito para seu próprio ambiente / variáveis (os dois se sobrepõem de formas, mas devem ser entendidos como distintos) . O mesmo se aplica para as propriedades type como integer, array, function etc.

Você já pensou em usar um shell restrito, como rbash ? Você pode definir rbash para executar readonly TEST_ENV ) em seu script de inicialização. rbash pode ser muito restritivo, mas aborda em grande parte as questões levantadas nos comentários.

O ambiente é uma parte de leitura / gravação de cada processo (veja aqui e aqui para detalhes), não apenas um processo pode gravar diretamente na parte de dados (via environ[] ), pode mudar os ponteiros para ele. Você pode fazer algo com isso (ou seja, mudar para uma página somente leitura) se for proficiente em montagem e puder encontrar o caminho em torno do código de inicialização crt , mas não o recomendo; -)

Se houver comandos específicos que os usuários executam que devem ter um determinado ambiente, você poderá definir somente a execução de grupo e usar sudo para definir as variáveis corretas (por exemplo, via /etc/environment ou env_file diretiva) e execute o comando como o grupo específico (preservando o uid). As versões recentes suportam noexec na maioria das plataformas, o que pode ser usado para evitar a execução de um novo shell (embora possa quebrar programas que legitimamente fork() e exec() ).

Como última opção, você pode usar LD_PRELOAD e sua própria biblioteca para definir um ambiente controlado para alguns / todos os processos do usuário, agrupando as funções libc relevantes ( getenv() putenv() etc.). O libfaketime faz exatamente isso para funções libc relacionadas ao tempo. Existe uma ferramenta menos conhecida chamada timetravel que faz semelhante, mas também ganchos setenv() e getenv() para manter o controle de LD_PRELOAD em face da adversidade.

A abordagem mais robusta é filtrar as chamadas setenv() unsetenv() putenv() (e possivelmente clearnv() ) para impedir a modificação e filtrar getenv() para que sempre retorne o valor necessário (possivelmente de um arquivo). Essa abordagem não impedirá a manipulação direta da memória do ambiente via environ[] , mas contanto que você esteja no controle de getenv() , qualquer processo que dependa da API libc deve ver seu valor. bash usa environ[] diretamente quando inicializa, mas também chama getenv() .

    
por 02.03.2013 / 15:53
3

Readonly variáveis podem ser definidas em shells compatíveis com POSIX usando o comando readonly .

readonly VAR=foo   # POSIX
declare -r VAR=foo # bash
export VAR

Este não é um recurso de segurança que impeça o usuário de alterá-lo. O usuário sempre pode gerar um novo shell e alterar a variável.

    
por 02.03.2013 / 07:26