Eu consegui a transição trabalhando no final graças a várias referências - na verdade, ela se mostrou incrivelmente simples e eu acho que você poderia dizer que está relacionada a uma regra básica de boa programação?
Na política que publiquei na pergunta, defini dois novos tipos:
type testprog_t;
type testprog_exec_t;
Depois, permitimos que várias coisas acontecessem com esses tipos e também especificamos uma transição de tipo:
allow testprog_t fs_t:filesystem getattr;
allow testprog_t testprog_exec_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ;
type_transition unconfined_t testprog_exec_t : process testprog_t;
allow unconfined_t testprog_t : process transition ;
No entanto, em nenhum momento eu realmente disse ao SELinux o que esses tipos realmente eram. Por exemplo, eu defino o contexto do arquivo /usr/bin/testprog
como system_u:object_r:testprog_exec_t:s0
, mas na verdade nunca contei ao SELinux por meio de minha política que testprog_exec_t era um arquivo. Assim que mudei a política, adicionando especificações de tipo, as coisas começaram a parecer mais promissoras. Também precisei usar a instrução de função para permitir que testprog_t
fosse executado sob a função unconfined_r
que os comandos shell normalmente executam em um sistema RHEL no modo SELinux de destino. O atual fragmento da política relacionada a isso se parece com isso:
# Define our new types that testprog will use, and ensure that we tell the policy that testprog_exec_t is a file
type testprog_t;
domain_type(testprog_t);
type testprog_exec_t;
files_type(testprog_exec_t);
type testprog_etc_t;
files_type(testprog_etc_t);
type testprog_var_run_t;
files_type(testprog_var_run_t);
type testprog_data_t;
files_type(testprog_data_t);
# Allow the testprog_t type under the unconfined_r role
role unconfined_r types testprog_t;
# Tell SELinux that testprog_exec_t is an entrypoint to the tetprog_t domain
allow testprog_t testprog_exec_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ;
# Make the type transition from unconfined_t (i.e. user shell) to testprog_t
type_transition unconfined_t testprog_exec_t : process testprog_t;
# Explicitly allow the type transition we have just created
allow unconfined_t testprog_t : process transition ;
Feito isso, a transição de tipo acontece perfeitamente e a tarefa de concluir a política tornou-se uma das que usam sealert
para explorar o comportamento do programa e implementar as políticas certas para que funcione conforme desejado.
Espero montar um exemplo completo de um aplicativo que não seja o SELinux e que precise ser executado em seu próprio contexto confinado, em vez de não confinado para meus colegas (e para qualquer outra pessoa que precise dele) - é bastante esqueletal agora mas se alguém estiver interessado em rastreá-lo, você pode encontrar o código aqui: