suid-rootは効果がありません

suid-rootは効果がありません

プログラムは以下で提供されます。アプエ

#include "apue.h"
#include <fcntl.h>

int main(int argc, char *argv[])
{
    if(argc!=2)
        err_quit("usage: a.out <pathname>");

    if(access(argv[1], R_OK)<0)
        err_ret("access error for %s",argv[1]);
    else
        printf("read access OK\n");
    if (open(argv[1], O_RDONLY)) {
        err_ret("open error for %s", argv[1]);
    } else {
        printf("open for reading OK\n");
    }

    return 0;
}

私はそれを呼び出された実行可能ファイルにコンパイル4-2し、所有者を変更してsuidを設定しました。これは次の出力ですls -l

-rwsr-xr-x 1 root sinners 8490 Jan  7 18:50 4-2*

そして/etc/shadow

-rw------- 1 root root 421 Jan  4 01:29 /etc/shadow

しかし、実行してみると:

user% ./4-2 /etc/shadow 
access error for /etc/shadow: Permission denied
open error for /etc/shadow: Permission denied

access誰かがこれらのエラーが発生する理由を説明できますかopen

ベストアンサー1

引用するaccess() マンページ:

このチェックは、実際にファイルを操作しようとすると(たとえば、open(2))、有効なIDを使用する代わりに、呼び出しプロセスの実際のUIDとGIDを使用して実行されます。これにより、SetUserID プログラムは呼び出し側ユーザーの権限を簡単に確認できます。

ユーザ ID ビットを設定すると、プロセスがアクティブになります。有効なUIDファイル所有者と同じですが、実際のユーザーIDは変更されません(つまり、以前の状態を維持しますexec())。

あなたはそれを使用することができますsetreuid()プロセスの有効なUIDと実際のUIDを変更するか、それを使用してopen()権限を決定できます。特にすでに電話をかけているので、2番目の解決策をお勧めしますopen()errno同じことを確認して、EPERM権限の不足によってopen()エラーが発生したかどうかを確認できます。

open()open()戻り値をif条件として使用しているため、コード内の呼び出しは失敗します。私は実際に呼び出しが成功し、ゼロ以外の有効なファイル記述子を返し、制御がエラー処理ブランチに入ると思います。 if のエラー処理ブランチは、呼び出しによって発生した最後のエラーであるEPERMため、エラーメッセージを表示します。access()エラー処理ブランチを入力する条件は、open()-1が返されることを確認する必要があります。

おすすめ記事