fakeroot에서 chown이 성공하더라도(성공하지 못하더라도) EPERM을 반환하는 이유는 무엇입니까?

fakeroot에서 chown이 성공하더라도(성공하지 못하더라도) EPERM을 반환하는 이유는 무엇입니까?

사용할 때 이상한 동작이 발생했습니다.마을 (2)fakeroot 환경에서. 다음 최소 프로그램은 문제를 보여줍니다.

#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;
}

yes 라고 가정 main.c하면 다음 명령을 실행합니다 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

여기서 무엇을 볼 수 있나요?

  1. chownEPERM(작업이 허용되지 않음)으로 인해 호출이 실패합니다.
  2. 그런 다음 내 실제(가짜 아님) UID와 GID가 무엇인지 stat보여줍니다 st_uid=1001, st_gid=100(이상한 이유는 내가 fakeroot를 올바르게 이해했다면 최소한 표시되어야 하기 때문입니다 st_uid=0, st_gid=0).
  3. ls -l동일한 파일의 후속 콘텐츠에서는 보고서가 실패했지만 후속 콘텐츠에서는 보고서 chown가 성공했음을 확인했습니다.chownstat

정확히 무슨 일이 일어나고 있는 걸까요? fakeroot에서 버그를 찾았나요, 아니면 이것이 fakeroot 작동 방식에 대한 오해인가요?

(내 fakeroot버전은 1.20.2이고 내 시스템은 모든 업데이트가 포함된 Arch Linux입니다.)

고쳐 쓰다:Jonas Wielicki는 strace가 시스템 호출 수준에서 작동한다는 점을 올바르게 지적했습니다. 이는 시스템 호출의 결과가 프로그램 자체로 반환되기 전에 libfakeroot에 의해 파괴되기 때문에 오해의 소지가 있습니다. 게시물에 새 UID와 GID가 stat(path, &s)포함되어 있는 것으로 나타났습니다. struct stat s그러나 chownEPERM 실패는 여전히 수수께끼로 남아 있습니다.

답변1

chown실제로 아래에서 실행하면 0이 반환됩니다 fakeroot. 따라서 다음과 같습니다 errno(3).

해당 값은 호출의 반환 값이 오류(즉, 대부분의 시스템 호출의 경우 -1, 대부분의 라이브러리 함수의 경우 -1 또는 NULL)를 나타내는 경우에만 의미가 있습니다. 성공적인 함수는 errno를 변경할 수 있습니다.

의 가치는 errno중요하지 않으며 chown실제로 실패하지도 않습니다.

주석에서 이미 논의한 것처럼 strace출력에는 stracefakeroot 저장소 LD_PRELOAD아래 추적에 표시된 대로 EPERM 및 예상되는 가짜가 아닌 uids/gid가 포함됩니다. 프로그램에서 uid/gid를 인쇄하면 올바른(가짜) 출력이 표시됩니다.

관련 정보