exec를 통해 기능 전달

exec를 통해 기능 전달

exec()다른 프로세스에서 이미 처리하고 있는 프로세스 에 Linux 기능이 어떻게 전달되는지 이해하려고 합니다 . 내가 읽은 바에 따르면, exec 이후 특정 기능을 유지하려면 상속 가능한 세트에 있어야 합니다. 하지만 컬렉션이 어떻게 채워지는지 잘 모르겠습니다.

내 목표는 일반적으로 루트 권한이 필요한 일반 사용자로 프로그램을 실행할 수 있는 것입니다. 필요한 기능은 cap_dac_override개인 파일을 읽을 수 있어야 한다는 것입니다. 다른 기능을 제공하고 싶지 않습니다.

이것은 내 래퍼입니다.

#include <unistd.h>

int main(int argc, char *argv[]) {
    return execl("/usr/bin/net", "net", "ads", "dns", "register", "-P", NULL);
}

이는 생성된 실행 파일에 대해 setuid 권한을 설정할 때 작동합니다.

~ $ sudo chown root: ./registerdns
~ $ sudo chmod u+s ./registerdns
~ $ ./registerdns 
Successfully registered hostname with DNS

하지만 setuid 대신 함수를 사용하고 싶습니다. cap_dac_override래퍼에 함수를 설정하려고 합니다 .

~ $ sudo setcap cap_dac_override=eip ./registerdns
~ $ ./registerdns 
Failed to open /var/lib/samba/private/secrets.tdb
ERROR: Unable to open secrets database

cap_dac_override또한 실행 파일 자체의 함수에 상속 가능 플래그를 설정해 보았습니다 net.

~ $ sudo setcap cap_dac_override=eip ./registerdns
~ $ sudo setcap cap_dac_override=i /usr/bin/net
~ $ ./registerdns 
Failed to open /var/lib/samba/private/secrets.tdb
ERROR: Unable to open secrets database

정확한 매개변수 집합을 통해서만 기능을 사용할 수 있도록 래퍼를 사용해야 합니다. 프로그램은 net사용자에게 너무 광범위한 권한이 부여된 경우 위험할 수 있는 여러 가지 작업도 수행합니다.

나는 상속이 어떻게 작동하는지 분명히 오해했습니다. 래퍼가 해당 기능을 사용할 수 있도록 교체 프로세스에 전달하도록 래퍼를 설정하는 방법을 알 수 없는 것 같습니다. 나는 그것을 사용하는 방법에 대한 매뉴얼 페이지와 수많은 다른 문서를 읽었습니다.~해야 한다일하면서 나는 그것이 설명하는 일을 하고 있다고 생각했습니다.

답변1

래퍼에 +i를 설정하면아니요래퍼 프로세스의 컬렉션 에 기능을 추가하여 CAP_INHERITABLE전달되지 않도록 합니다 exec. 따라서 호출하기 전에 수동으로 추가해야 합니다 CAP_DAC_OVERRIDE.CAP_INHERITABLEexecl

#include <sys/capability.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv[]) {
    cap_t caps = cap_get_proc();
    printf("Capabilities: %s\n", cap_to_text(caps, NULL));
    cap_value_t newcaps[1] = { CAP_DAC_OVERRIDE, };
    cap_set_flag(caps, CAP_INHERITABLE, 1, newcaps, CAP_SET);
    cap_set_proc(caps);
    printf("Capabilities: %s\n", cap_to_text(caps, NULL));
    cap_free(caps);
    return execl("/usr/bin/net", "net", "ads", "dns", "register", "-P", NULL);
}

cap_dac_override또한 허용되는 파일 기능 설정을 추가 /usr/bin/net하고 유효한 비트를 설정 해야 했습니다 .

~ $ sudo setcap cap_dac_override=p ./registerdns
~ $ sudo setcap cap_dac_override=ei /usr/bin/net
~ $ ./registerdns
Capabilities = cap_dac_override+p
Capabilities = cap_dac_override+ip
Successfully registered hostname with DNS

나는 이제 무슨 일이 일어나고 있는지 정확히 이해했다고 생각합니다.

  1. CAP_DAC_OVERRIDE래퍼는 상속 가능한 세트에 추가될 수 있도록 허용된 세트에 있어야 합니다 .
  2. 래퍼의 프로세스 상속 가능 세트는 파일 상속 가능 세트와 다르기 때문에 파일에 +i를 설정하는 것은 쓸모가 없습니다. / 를 사용하여 래퍼를 명시적 CAP_DAC_OVERRIDE으로 추가해야 합니다 .CAP_INHERITABLEcap_set_flagcap_set_proc
  3. 파일 이 실제로 래퍼의 기능을 해당 세트로 상속할 수 있도록 상속 가능한 세트에 net포함되어야 합니다 . 또한 자동으로 승격되려면 유효한 비트 세트가 필요합니다 .CAP_DAC_OVERRIDECAP_PERMITTEDCAP_EFFECTIVE

답변2

내 생각에는 두 가지가 모두 필요하다고 생각합니다.

setcap cap_dac_override+pe ./registerdns
setcap cap_dac_override+i /usr/bin/net

pe위의 기호는 registerdns프로그램을 실행하면 해당 기능을 얻을 수 있음을 나타냅니다. ion 플래그는 net호출 프로그램에서 기능을 상속할 수 있음을 나타냅니다.

관련 정보