Eu escrevi este código de teste e descobri que esse programa sempre pode ler o arquivo com sucesso, mesmo depois que eu cancelei a permissão de leitura ao executar o getchar()
.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/types.h>
int main(){
int f = open("a.txt",O_RDONLY);
uint8_t data[200];
printf("Got %d from read", pread(f, (void *)data, 200, 0));
getchar();
printf("Got %d from read", pread(f, (void *)data, 200, 0));
}
Este programa imprimiu
Tenho 9 de leitura
duas vezes, mesmo que eu use chmod a-r a.txt
durante a pausa.
Tenho certeza de que sou apenas um usuário normal e meu processo não tem CAP_DAC_OVERRIDE; por que o segundo não pread()
retorna nenhum erro?
Meu palpite é que, ao fazer leitura/gravação, o kernel apenas verifica a permissão do arquivo na descrição do arquivo aberto, que é criada com open()
, e não altera mesmo que eu tenha alterado a permissão do arquivo no sistema de arquivos subjacente.
Meu palpite está correto?
Pergunta extra :
Se eu estiver certo sobre isso, que tal as regiões mapeadas?
O kernel apenas verifica as permissões registradas na tabela de páginas quando eu leio/escrevo/executo essa região mmaped?
Esses dados verdadeiros do inode armazenados no sistema de arquivos são usados apenas ao criar a descrição do arquivo aberto e a região mmap?
Sim, as permissões são verificadas apenas no horário de abertura e registradas. Portanto, você não pode gravar em um descritor de arquivo que abriu para acesso somente leitura, independentemente de poder gravar no arquivo.
O kernel consulta inodes na memória em vez dos armazenados no sistema de arquivos. Eles diferem na contagem de referência para arquivos abertos e os pontos de montagem obtêm o inode do arquivo montado.
Mesmo. (Sinalizadores PROT_* passados para sinalizadores
mmap()
equivalentes aos sinalizadores O_RDWR / O_RDONLY / O_WRONLY passados paraopen()
).Não tenho certeza de quando mais ele poderia verificar as permissões registradas na tabela de páginas :-). Pelo que entendi sua pergunta: sim.
As permissões de inode também são verificadas para operações de metadados, por exemplo
mkdir()
(e similarmenteopen()
com O_CREAT).E não se esqueça
chdir()
, que é diferente de qualqueropen()
chamada. (Ou, pelo menos, é diferente de qualqueropen()
chamada no Linux atual).Não tenho certeza sobre as permissões específicas do SELinux.