set-user-ID 비트가 켜져 있으면 프로세스의 EUID와 저장된 set-user-ID가 모두 파일의 사용자 ID로 변경됩니까?

set-user-ID 비트가 켜져 있으면 프로세스의 EUID와 저장된 set-user-ID가 모두 파일의 사용자 ID로 변경됩니까?

APUE에서

저장된 설정된 사용자 ID는 exec해당 기능을 통해 유효 사용자 ID에서 복사됩니다. 파일의 설정된 사용자 ID 비트가 설정된 경우 이 복사본을 저장하십시오.뒤쪽에 exec파일 사용자 ID에 유효 사용자 ID를 저장합니다.

그게 무슨 뜻인가요?

  • 먼저 프로세스의 EUID가 파일의 사용자 ID로 변경되고,

  • 그러면 프로세스에 의해 저장된 set-user-ID가 프로세스의 EUID로 변경되나요?

그러면 프로세스의 EUID와 저장된 set-user-ID가 파일의 사용자 ID로 변경되나요?

답변1

이것문서:credentials(7)이는 Linux 시스템에 대해 명확해졌습니다.

사용자 및 그룹 식별자

각 프로세스에는 다양한 관련 사용자 및 그룹 ID가 있습니다. 이러한 ID는 각각 유형 uid_tgid_t표현( 에 정의됨 )을 사용하는 정수입니다 <sys/types.h>.

Linux에서 각 프로세스에는 다음과 같은 사용자 및 그룹 식별자가 있습니다.

  • 실제 사용자 ID와 실제 그룹 ID입니다. 이러한 ID는 프로세스를 소유한 사람을 결정합니다. 프로세스는 를 사용하여 실제 사용자(그룹) ID를 얻을 수 있습니다 getuid(2).

  • 유효 사용자 ID 및 유효 그룹 ID. 커널은 이러한 ID를 사용하여 메시지 큐, 공유 메모리, 세마포어와 같은 공유 리소스에 액세스할 때 프로세스가 갖는 권한을 결정합니다. 대부분의 UNIX 시스템에서 이러한 ID는 파일에 액세스할 때 권한도 결정합니다. 그러나 Linux는 아래 설명된 파일 시스템 ID를 사용하여 이 작업을 수행합니다. 프로세스는 를 사용하여 유효 사용자(그룹) ID를 얻을 수 있습니다 geteuid(2).

  • 저장된 설정 사용자 ID 및 저장된 설정 그룹 ID입니다. 이러한 ID는 set-user-ID 및 set-group-ID 프로그램에서 프로그램 실행 시 해당 유효한 ID 세트의 복사본을 저장하는 데 사용됩니다(참고자료 참조 execve(2)). 사용자 ID 설정 프로그램은 실제 사용자 ID와 저장된 사용자 ID 설정 값 사이에서 유효 사용자 ID를 전환하여 권한을 획득하거나 포기할 수 있습니다. 이 전환은 seteuid(2), 또는 을 호출하여 setreuid(2)수행됩니다 setresuid(2). set-group-ID 프로그램이 사용되거나 setegid(2)유사한 setregid(2)작업을 수행합니다 setresgid(2). 프로세스는 를 사용하여 저장된 set-user-ID(set-group-ID)를 얻을 수 있습니다 getresuid(2).

[...]

나는 무슨 일이 일어나는지 알아보기 위해 테스트 프로그램을 작성했습니다.

#define _GNU_SOURCE

#include <stdio.h>
#include <unistd.h>

int getuids(uid_t *uids) {
  if(getresuid(&uids[0], &uids[1], &uids[2]) == -1) {
    perror("Unable to get UIDs\n");
    return 0;
  }
  return 1;
}

int getgids(gid_t *gids) {
  if(getresgid(&gids[0], &gids[1], &gids[2]) == -1) {
    perror("Unable to get GIDs\n");
    return 0;
  }
  return 1;
}

int main(void) {
  uid_t uids[3];
  gid_t gids[3];

  if(getuids(uids) && getgids(gids)) {
    printf("Real ID: user %d, group %d\n", (int)uids[0], (int)gids[0]);
    printf("Effective ID: user %d, group %d\n", (int)uids[1], (int)gids[1]);
    printf("Set-ID: user %d, group %d\n", (int)uids[2], (int)gids[2]);

    seteuid(uids[0]);
    getuids(uids);
    getgids(gids);
    printf("Effective ID: user %d, group %d\n", (int)uids[1], (int)gids[1]);
  }

  return 0;
}

파일은 다음과 같습니다.

server /home/erik # ls -l perms
-r-sr-sr-x 1 nobody nobody 8280 Apr 26 00:36 perms

다음으로 실행 root:

server-calgary /home/erik # ./perms
Real ID: user 0, group 0
Effective ID: user 65534, group 65534
Set-ID: user 65534, group 65534
Effective ID: user 0, group 65534

다음으로 실행 erik:

erik@server ~ $ ./perms
Real ID: user 1000, group 1000
Effective ID: user 65534, group 65534
Set-ID: user 65534, group 65534
Effective ID: user 1000, group 65534

테스트 프로그램에서 볼 수 있듯이 파일이 set-ID인 경우 EUID/EGID는 파일에 있는 소유자/그룹으로 시작하지만(set-UID 및 set-UID+GID 권한만 작동합니다!) 작동합니다. 프로그램에서 요구하는 경우 이 ID와 호출자의 실제 ID 사이에 만들어집니다.

관련 정보