6

パーミッション 4750 のプロセスがあります。私の Linux システムには 2 人のユーザーがいます。root ユーザーと appz ユーザー。このプロセスは、「appz」ユーザーとして実行されるプロセス マネージャーのアクセス許可を継承します。

2 つの基本的なルーチンがあります。

void do_root (void)
{
        int status;
        status = seteuid (euid);
        if (status < 0) { 
        exit (status);
        }    
}

/* undo root permissions */
void undo_root (void)
{
int status;
        status = seteuid (ruid);
        if (status < 0) { 
                exit (status);
        }
        status = setuid(ruid);
        if (status < 0) { 
                exit (status);
        }
}

私のフローは次のとおりです。

int main() {
 undo_root();
 do some stuff;
 do_root();
 bind( port 80); //needs root perm
 undo_root();
 while(1) {

    accept commads()
    if ( commands needs root user access)
    {
       do_root();
       execute();
       undo_root();

    }

 }

ご覧のとおり、いくつかのコマンドを root として実行したいと考えています。アクセス許可を一時的に削除しようとしていますが、タスクにルート アクセスが必要な場合は、コマンドを do_root 呼び出しと undo_root 呼び出しの間にラップします。

しかし、私のプログラムは動作していないようです。

それを行う標準的な方法は何ですか?

4

3 に答える 3

6

昔ながらの方法は、do_root と undo_root の両方で setreuid() を使用して ruid と euid を交換することです。

setreuid(geteuid(), getuid());

プログラムが完全なセキュリティ監査を行うのに十分小さい場合、これは完全に許容されます。

新しい学校の方法ははるかに複雑で、root として何をすべきかのディレクティブを受け入れる子を fork() し、次に setuid(getuid()) を実行して root を親に永久にドロップする必要があります。受信したすべてのディレクティブを検証します。十分に大きなプログラムの場合、これにより、セキュリティ監査が必要なコードの量が減り、ユーザーはジョブ制御でプロセスを管理したり、プロセスを強制終了したりできます。

于 2012-02-15T16:59:20.120 に答える
5

Hao Chen、David Wagner、Drew Deanによる論文「Setuid Demystified 」があります。これは USENIX 2002 で発表されました。どのようsetuid()に遷移が機能するかが非常に詳細に説明されています (2002 年時点で正しい)。読む価値は十分にあります (数回 - 再読するには 1 年か 2 年かかるはずです)。

基本的に、Peteshがコメントで指摘したように、EUID 0 のプロセスが で行う場合、(EUID 0) 特権に戻る方法はありませんsetuid(nuid)。そして実際、そうであることが極めて重要です。そうしないと、ログインするときに、ログインするプロセスが自分の特権に制限されず、. 保存された UID は物事を複雑にしますが、それが EUID 0 を実行するという一方通行の罠には影響しないと思います。nuid != 0rootrootrootsetuid()

于 2012-02-15T16:53:34.567 に答える
2

setuidマニュアルページには次のように書かれています。

...一時的にroot権限を削除し、非rootユーザーのIDを引き受け、その後root権限を取り戻すことを希望するset-user-ID-rootプログラムは、setuid()を使用できません。

使用できないという意味setuid()。を使用する必要がseteuid()あり、場合によってはsetreuid()。詳細については、 Setuidプログラムの例を参照してください。

于 2012-02-15T16:50:16.830 に答える