Quando um processo obtém um fd com sucesso usando open(flags=O_RDWR)
, ele poderá ler/gravar nesse arquivo desde que o fd não esteja fechado (arquivo regular no sistema de arquivos local), mesmo que algum outro processo use chmod para cancelar a leitura/gravação permissão para o usuário correspondente. O kernel do Linux verifica as permissões de arquivo no inode ou na descrição do arquivo aberto? Mas e quando o processo tentar executar esse arquivo usando execveat
, o kernel lerá o disco para verificar a permissão x bit e suid bit? Que tipo de permissões são registradas na descrição do arquivo aberto, ele contém uma ACL completa ou um bit simplesmente legível/gravável para que todas as outras operações ( execveat
, fchdir
, fchmod
, etc) verifiquem as informações no disco?
E se eu transferir este fd para outro processo de outro cujo fsuid não tenha um bit de leitura/gravação/execução nesse arquivo (de acordo com as informações do sistema de arquivos no disco), esse processo receptor será capaz de ler/gravar/executar o arquivo através do fd?
execveat
é tratado pordo_open_execat
, que especifica que deseja abrir o arquivo de destino para execução. O procedimento de abertura do arquivo é feito viado_filp_open
epath_openat
, com um processo de acompanhamento documentado separadamente . O resultado de tudo isso, independente de como o processo se inicia, é umstruct file
e seu associadostruct inode
que armazena o modo do arquivo e, se for o caso, um ponto para as ACLs. A estrutura de dados do inode é compartilhada por todas as descrições de arquivo que fazem referência ao mesmo inode.O kernel garante que as informações do inode na memória estejam atualizadas quando recuperadas. Isso pode ser mantido nos caches dentry e inode em alguns casos (sistemas de arquivos locais, ext4, ext3, XFS e btrfs em particular), em outros envolverá alguma E/S (em particular pela rede).
A verificação de permissão em si é realizada um pouco mais tarde, por
bprm_fill_uid
; que leva em consideração as permissões atuais no inode e os privilégios atuais do usuário chamador.Conforme discutido anteriormente , as permissões são verificadas apenas quando um arquivo é aberto, mapeado ou seus metadados são alterados, não quando é lido ou gravado; para que os descritores de arquivo possam ser passados pelos processos sem novas verificações de permissão.
Não. Nenhuma "permissão" é mantida na "descrição do arquivo aberto" (
struct file
) além dos modos de acesso ao arquivo e dos sinalizadores de status do arquivo que podem ser recuperados comfcntl(F_GETFL)
ou via/proc/PID/fdinfo/FD
. Todas as permissões de arquivo são mantidas nostruct inode
referenciado de lá (e que é compartilhada entre todos os processos/usuários que têm esse arquivo específico aberto). Astruct file
também contém uma referência às credenciais do abridor.Se você está perguntando sobre
execveat(fd, "", av, env, AT_EMPTY_PATH)
isso está usando apenas o descritor de arquivo como ponteiro para o inode, e tudo será verificado como se o arquivo referenciado fosse executado através de seu caminho. As bandeiras defd
não importam nem um pouco; o descritor de arquivo pode ser um identificador opaco aberto comO_PATH
(algo que será bem-sucedido com qualquer arquivo acessível por algum caminho).