%3F.png)
Tenho tido um comportamento bizarro ao usarchown(2)dentro de um ambiente fakeroot. O seguinte programa mínimo ilustra o problema:
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
int main() {
//choose a reasonably unique filename
char path[30];
sprintf(path, "./file-%d", getpid());
//create file
close(creat(path, 0644));
//chown to some random UID/GID
chown(path, 4444, 4444);
//stat again (result can be seen in strace below)
struct stat s;
stat(path, &s);
return 0;
}
Suponha que seja main.c
. Agora eu executo o seguinte dentro de um fakeroot bash
:
$ gcc -o main main.c
$ strace -v ./main
...
creat("./file-10872", 0644) = 3
close(3) = 0
...
lchown("./file-10872", 84, 84) = -1 EPERM (Operation not permitted)
stat("./file-10872", {st_dev=makedev(8, 3), st_ino=3932971, st_mode=S_IFREG|0644, st_nlink=1, st_uid=1001, st_gid=100, st_blksize=4096, st_blocks=0, st_size=0, st_atime=2015/10/31-20:12:07, st_mtime=2015/10/31-20:12:07, st_ctime=2015/10/31-20:12:07}) = 0
...
$ ls -l file-10872
-rw-r--r-- 1 4444 4444 0 31. Okt 20:12 file-10872
O que podemos ver aqui?
- A
chown
chamada falhou com EPERM (Operação Não Permitida). - O subseqüente
stat
mostrast_uid=1001, st_gid=100
qual é meu UID e GID reais (não falsos) (o que é estranho porque, se entendi o fakeroot corretamente, ele deveria pelo menos mostrarst_uid=0, st_gid=0
). - O subseqüente
ls -l
no mesmo arquivo mostra que ochown
SUCESSO, emborachown
tenha relatado falha e o subseqüentestat
confirmou isso.
O que diabos está acontecendo aqui? Encontrei um bug no fakeroot ou isso é apenas um mal-entendido de como o fakeroot funciona?
(Minha fakeroot
versão é 1.20.2 e meu sistema é Arch Linux com todas as atualizações.)
Atualizar:Foi corretamente apontado por Jonas Wielicki que o strace funciona no nível do syscall e, portanto, é enganoso, uma vez que os resultados dos syscalls serão mutilados pelo libfakeroot antes de serem retornados ao próprio programa. Acontece que depois de stat(path, &s)
, struct stat s
contém o novo UID e GID. Mas ainda é confuso o que chown
falha com o EPERM.
Responder1
chown
na verdade, retorna zero quando executado em fakeroot
. Assim, de acordo com errno(3)
:
Seu valor é significativo somente quando o valor de retorno da chamada indica um erro (ou seja, -1 na maioria das chamadas do sistema; -1 ou NULL na maioria das funções da biblioteca); uma função bem-sucedida pode alterar errno.
O valor in errno
não é significativo e chown
de fato não falhou.
Conforme já discutido nos comentários, a strace
saída contém EPERM e uids/gids não falsificados conforme esperado, como strace
rastreamentos abaixo da LD_PRELOAD
biblioteca fakeroot. Imprimir o uid/gid do programa mostra a saída correta (falsificada).