1. Introdução ao Seandroid
SEAndroid é um conjunto de mecanismo de segurança do sistema com SELinux como o núcleo oficialmente lançado pelo Google no Android4.4. No código-fonte do Android, a configuração do Seandroid padrão do sistema é armazenada no seguinte caminho:
/home/qiang/lineageOs/system/sepolicy
O diretório armazena os arquivos de configuração, como adbd, system_server, app do sistema e app de terceiros.
Como o sistema Android introduziu a estratégia seandroid. Fortaleça as restrições de acesso do aplicativo aos recursos. A segurança foi muito melhorada. Por exemplo, pegue um exemplo de obtenção de wi-fi mac como exemplo:
Muitos aplicativos no aplicativo Android obtêm o endereço mac wi-fi do telefone móvel lendo / sys / class / net / wlan0 / address. As permissões para visualizar o arquivo por meio do comando adb são as seguintes:
C:\Users\Qiang>adb shell ls -la /sys/class/net/wlan0/address
-r--r--r-- 1 root root 4096 2021-01-12 14:57 /sys/class/net/wlan0/address
A descrição acima mostra que o aplicativo móvel pode ler e acessar o arquivo. Mas no Android 10, o sistema é configurado com permissão de política seandroid que o aplicativo comum não pode ler / sys / class / net / wlan0 / address. Causou falha de leitura no Android 10, solicitando permissão negada. Visto que o seandroid fortalece a segurança do sistema, se você deseja que um aplicativo acesse um determinado diretório ou caminho do sistema, é necessário configurar especificamente a estratégia de arquivo. É um pouco difícil de configurar para desenvolvedores que não estão familiarizados com a configuração do Seandroid. Existe uma maneira de acessar o arquivo ou diretório sem configurar o arquivo de política seandroid e definir a permissão de leitura do arquivo ou diretório. A resposta é fechar o Seandroid globalmente .
2. Discussão sobre como fechar o Seandroid no Android
1. Use o comando setenforce para fechar temporariamente
O comando é o seguinte
adb shell setenforce 0
O comando setenforce pode desligar temporariamente o Seandroid e, se o telefone for reiniciado, ele será restaurado ao seu estado normal.
O caminho de setenforce no código-fonte do Android é o seguinte:
external/toybox/toys/android/setenforce.c
O código de implementação setenforce é o seguinte:
#define FOR_setenforce
#include "toys.h"
void setenforce_main(void)
{
char *new = *toys.optargs;
int state, ret;
if (!is_selinux_enabled()) error_exit("SELinux is disabled");
else if (!strcmp(new, "1") || !strcasecmp(new, "enforcing")) state = 1;
else if (!strcmp(new, "0") || !strcasecmp(new, "permissive")) state = 0;
else error_exit("Invalid state: %s", new);
ret = security_setenforce(state);
if (ret == -1) perror_msg("Couldn't set enforcing status to '%s'", new);
}
Pelo código acima, podemos ver que setenforce finalmente chama a função security_setenforce para completar o controle selinux.
2. Feche o selinux no kernel
Configure SECURITY_SELINUX para false no kernel, recompile o kernel e atualize a máquina. Seandroid pode ser fechado permanentemente.
A seguir estão as informações de configuração após o selinux ser desativado no arquivo .config da compilação do kernel testada:
CONFIG_SECURITY_SELINUX=n
3. Feche o selinux quando o processo de inicialização começar
Durante a inicialização do sistema Android, o processo init inicializará o selinux. Ao ler o arquivo / proc / cmdline, determine se o valor de androidboot.selinux precisa habilitar o selinux. Portanto, podemos forçar a operação de desligamento quando o processo init inicializa o selinux.
A seguir, discutiremos a terceira opção para obter o desligamento global do selinux.
3. Globalmente feche o selinux no processo de inicialização
1. Análise do processo de inicialização do Selinux no processo init
Os caminhos de arquivo relacionados à inicialização do selinux no processo init são os seguintes:
system/core/init/selinux.cpp
system/core/init/main.cpp
O processo de inicialização aproximado é o seguinte:
a. A função principal em main.cpp chama SetupSelinux em selinux.cpp:
int main (int argc, char ** argv) {
...省略
if (!strcmp(argv[1], "selinux_setup")) {
return SetupSelinux(argv);
}
...省略
}
b. A função SetupSelinux em selinux.cpp é implementada da seguinte forma:
int SetupSelinux (char ** argv) {
...省略
SelinuxInitialize();
...省略
return 1;
}
c. SetupSelinux chama o método SelinuxInitialize. O código do método SelinuxInitialize é o seguinte:
// SelinuxInitialize pode ver que o método IsEnforcing é chamado para determinar
void SelinuxInitialize() {
...省略
bool kernel_enforcing = (security_getenforce() == 1);
//判断是否强制模式
bool is_enforcing = IsEnforcing();
if (kernel_enforcing != is_enforcing) {
//调用security_setenforce函数,和setenforce原理一样
if (security_setenforce(is_enforcing)) {
PLOG(FATAL) << "security_setenforce(%s) failed" << (is_enforcing ? "true" : "false");
}
}
...省略
}
d. O método IsEnforcing é implementado da seguinte forma:
// Determine se o modo obrigatório é necessário
bool IsEnforcing() {
if (ALLOW_PERMISSIVE_SELINUX) {
return StatusFromCmdline() == SELINUX_ENFORCING;
}
return true;
}
Pode-se saber por IsEnforcing que se continuar retornando falso, o selinux será fechado.
2. Modificação selinux de fechamento global à força
O processo de inicialização do selinux a partir do processo init acima pode fornecer dois esquemas de modificação para encerrar globalmente.
-
A primeira é modificar a função IsEnforcing para sempre retornar false. Modifique da seguinte forma:
bool IsEnforcing() {
///ADD START
if(1>0)
{
//一直返回false
return false;
}
///ADD END
if (ALLOW_PERMISSIVE_SELINUX) {
return StatusFromCmdline() == SELINUX_ENFORCING;
}
return true;
}
-
A segunda é modificar o método SelinuxInitialize para chamar ativamente security_setenforce (false) na função. Após a modificação da seguinte forma:
void SelinuxInitialize() {
Timer t;
LOG(INFO) << "Loading SELinux policy";
if (!LoadPolicy()) {
LOG(FATAL) << "Unable to load SELinux policy";
}
bool kernel_enforcing = (security_getenforce() == 1);
bool is_enforcing = IsEnforcing();
if (kernel_enforcing != is_enforcing) {
if (security_setenforce(is_enforcing)) {
PLOG(FATAL) << "security_setenforce(%s) failed" << (is_enforcing ? "true" : "false");
}
}
//直接调用security_setenforce方法来关闭
///ADD START
security_setenforce(false);
///ADD END
if (auto result = WriteFile("/sys/fs/selinux/checkreqprot", "0"); !result) {
LOG(FATAL) << "Unable to write to /sys/fs/selinux/checkreqprot: " << result.error();
}
// init's first stage can't set properties, so pass the time to the second stage.
setenv("INIT_SELINUX_TOOK", std::to_string(t.duration().count()).c_str(), 1);
}
Após a modificação, compile o código-fonte e atualize a máquina, e isso terá efeito após a inicialização.
Personalização e desenvolvimento de código-fonte do sistema Android10 divertido Mais artigos:
Desenvolvimento de código fonte Android10 divertido e operação de flashing de personalização (2)
Desenvolvimento de código-fonte divertido Android10 e personalização (oito) Apk integrado ao sistema
Siga a conta pública para mais artigos recentes