exec()
他のプロセスがすでに処理しているプロセスにLinux機能がどのように渡されるかを理解したいと思います。私が読んだことによれば、exec以降の特定の機能を維持するために継承可能なセットにする必要があります。しかし、コレクションがどのように満たされるのかはよくわかりません。
私の目標は、通常、root権限を必要とする一般ユーザーとしてプログラムを実行できることです。必要な機能は、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_INHERITABLE
execl
#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
私は今何が起こっているのかを正確に理解したと思います。
CAP_DAC_OVERRIDE
ラッパーは、継承可能なセットに追加できるように、許可されたセットになければなりません。- ラッパーのプロセス継承可能セットはファイル継承可能セットとは異なるため、ファイルに+iを設定することは役に立ちません。 /を使用してラッパーを明示的
CAP_DAC_OVERRIDE
に追加する必要があります。CAP_INHERITABLE
cap_set_flag
cap_set_proc
- ファイルが実際にラッパーの機能をそのセットに継承できるように、継承可能なセットに
net
含める必要があります。また、自動的に昇格するには有効なビットセットが必要です。CAP_DAC_OVERRIDE
CAP_PERMITTED
CAP_EFFECTIVE
答え2
私の考えには両方が必要だと思います。
setcap cap_dac_override+pe ./registerdns
setcap cap_dac_override+i /usr/bin/net
pe
上記の記号は、registerdns
プログラムを実行するとその機能が得られることを示しています。i
onフラグは、net
呼び出し元プログラムから機能を継承できることを示します。