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

이라고 가정해보자 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. 후속 statst_uid=1001, st_gid=100는 내 실제(가짜가 아닌) UID 및 GID입니다(이상한 이유는 내가 fakeroot를 올바르게 이해했다면 최소한 을 표시해야 하기 때문입니다 st_uid=0, st_gid=0).
  3. ls -l동일한 파일의 후속 에서는 보고된 실패 chown에도 불구하고 SUCCEEDED 가 표시되고 chown후속에서는 stat이를 확인했습니다.

여기서 도대체 무슨 일이 일어나고 있는 걸까요? fakeroot에서 버그를 발견한 걸까요, 아니면 이것은 단지 fakeroot의 작동 방식에 대한 오해인가요?

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

업데이트:strace가 syscall 수준에서 작동하고 따라서 syscall의 결과가 프로그램 자체로 반환되기 전에 libfakeroot에 의해 엉망이 되기 때문에 Jonas Wielicki가 올바르게 지적했습니다. 이후 stat(path, &s)에는 struct stat s새 UID와 GID가 포함되어 있는 것으로 나타났습니다 . 그러나 chownEPERM에서는 실패하는 것이 여전히 혼란스럽습니다 .

답변1

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

그 값은 호출의 반환 값이 오류를 나타낼 때만 중요합니다(예: 대부분의 시스템 호출에서는 -1, 대부분의 라이브러리 함수에서는 -1 또는 NULL). 성공한 함수는 errno를 변경할 수 있습니다.

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

주석에서 이미 논의한 것처럼 출력에는 fakeroot 라이브러리 아래의 추적 strace으로 EPERM 및 가짜가 아닌 uids/gid가 예상대로 포함됩니다 . 프로그램에서 uid/gid를 인쇄하면 올바른(가짜) 출력이 표시됩니다.straceLD_PRELOAD

관련 정보