GNU/Linux >> Linux の 問題 >  >> Linux

setuid ビットの動作に一貫性がないのはなぜですか?

変わったのは /bin/sh です どちらかが bash になりました または dash 滞在 追加のフラグ -p を取得しました bash の動作を模倣します。

Bash には -p が必要です man ページで説明されているように、setuid 特権をドロップしないフラグ:

<ブロック引用>

実際のユーザー (グループ) ID と等しくない実効ユーザー (グループ) ID でシェルが開始され、-p オプションが指定されていない場合、起動ファイルは読み取られず、シェル関数は環境 (SHELLOPTS) から継承されません。 BASHOPTS、CDPATH、および GLOBIGNORE 変数が環境に表示された場合、それらは無視され、有効なユーザー ID が実際のユーザー ID に設定されます .呼び出し時に -p オプションが指定されている場合、起動時の動作は同じですが、有効なユーザー ID はリセットされません。

以前、dash これを気にせず、setuid の実行を許可しました (それを防ぐために何もしませんでした)。しかし、Ubuntu 16.04 の dash のマンページには、 bash のような追加のオプションが記述されています :

<ブロック引用>

-p 特権
uid と一致しない場合は、有効な uid をリセットしようとしないでください。 誤った使用を避けるため、これはデフォルトでは設定されていません system(3) または popen(3) を介して root プログラムを bysetuid します。

このオプションは、アップストリーム (提案されたパッチに反応しなかった可能性があります) にも Debian 9 にも存在しませんでしたが、2018 年以降にパッチを取得した Debian バスターには存在します。

注:Stéphane Chazelas が説明したように、"/bin/sh -p" を呼び出すには遅すぎます system() で なぜなら system() /bin/sh で指定されたものをすべて実行します そのため、setuid は既に削除されています。 derobert's answer は、 system() の前のコードで、これを処理する方法を説明しています .

あちこちに歴史の詳細があります。


おそらく、シェルは何らかの理由で起動の一部として有効なユーザー ID を実際のユーザー ID に戻しています。以下を追加することでこれを確認できます:

/* needs _GNU_SOURCE; non-Linux users see setregid/setreuid instead */
uid_t euid = geteuid(), egid = getegid();
setresgid(egid, egid, egid);
setresuid(euid, euid, euid);

system() の前に . (実際には、Linux でも、おそらく実際のものだけを設定する必要があります。保存されているものはそのままにしておいて問題ありません。これは、デバッグするための強引な方法です。ID を設定する理由によっては、もちろん必要になる場合があります。実際の ID もどこかに保存します。)

[また、setid がどのように機能するかを学習するだけの演習ではない場合、特にシェルを呼び出すときに、心配すべきセキュリティ上の問題がたくさんあります。たとえば、シェルの動作に影響を与える多くの環境変数があります。 sudo のような既存のアプローチを好む 可能であれば。]


Linux
  1. 〜/ .bash_profileが機能しないのはなぜですか?

  2. .bashrcの目的とそれはどのように機能しますか?

  3. ルートユーザーがSudo権限を必要とするのはなぜですか?

  1. Bashrcが現在のシェルがインタラクティブであるかどうかをチェックするのはなぜですか?

  2. Setuidビットを適切に使用していますか?

  3. Linux Setuidが機能しませんか?

  1. $なしの変数展開が式で機能するのはなぜですか?

  2. 「ls」コマンドは Linux/Unix でどのように機能しますか?

  3. vsftpd の chroot_local_user が安全でないのはなぜですか?