5

私が書いたPython拡張機能は、単一のハードウェア初期化呼び出しを行うためにrootアクセスを必要とします。拡張機能でこの1回の呼び出しのためだけにスクリプト全体をルートとして実行したくないので、ユーザー特権にドロップして実際のスクリプトを実行する前に、この初期化を行うラッパーを作成したいと思います。

私はこのラッパーがsudo例えばを介して実行されることを意図しています

$ sudo devwrap python somescript.py

私は次のようなことを考えていました(いくつかのバグを修正するために更新されました):

int main(int argc, char * argv[])
{
  if(argc < 2) return 0;

  int res = do_hardware_init();
  if(res != OK_VALUE)
  {
    // Print error message
    return HW_ERR;
  }

  const char *sudo_uid = getenv("SUDO_UID");
  if(sudo_uid)
  {
      int real_uid = (int) strtol(sudo_uid, NULL, 0);
      setuid(real_uid);
  }

  return execvp(argv[1], &argv[1]); // No return if successful

}

だから私は3つの質問があります:

  1. これは正気に見えますか?私は通常、* uid()呼び出しをいじる必要がないので、通常の落とし穴に精通していません。呼び出しも少し奇妙に見えますexecvpが、私が見る限り、適切な場所に引数があります)。
  2. execvpマニュアルページには、「アプリケーションがenviron配列に直接アクセスしてはならない」と書かれていますが、これはgetenv呼び出しを悪い考えにしますか?
  3. よりも良い呼び出しがexecvpあるので、私はできますsudo devwrap somescript.py(「python」がないことに注意してください)
4

1 に答える 1

1
  1. 正気のような...もっと下に。
  2. を使用することは、アレイに直接getenv()アクセスすることではありません-それはクリーンです。environ配列に直接アクセスするenvironということは、'strcpy(buffer、environ [3])`などを意味します。
  3. スクリプトがシバンで始まる場合(#!/usr/bin/env pythonおそらく)、すでに必要なことを実行できますsomescript.py。もちろん、実行可能ファイルである必要があります。

最初の部分で見られる問題は、ハードウェアの初期化からのエラーをどのように処理するかによって異なります。strtol()省略されたエラー処理が終了しない場合は、nullポインターで実行しているため、「sudo」を介して実行しないとコアダンプ(またはsegfault)が発生する可能性があります。それdo_hardware_init()自体が失敗時に終了する場合、ユーザーが「sudo」から環境を破壊する方法を見つけない限り、問題はありません。SUDO_UIDが適切に設定されていない場合は、環境を検証してエラーで終了する必要があると思います。ルートはこの拡張機能を実行しますか?

の仕様を調べてsudo、SUDO_UID環境変数が設定されていることを確認していません。これは正しいと思います。

これを入力するユーザーの影響は何ですか?

sudo devwrap ls

ハードウェアの初期化を行い、UIDをリセットしてから実行lsします。おそらくそれほど害はありませんが、考えていたものではない可能性があります。それは重要ですか?あなたはそれを完全に制御できますか?

引数の数が2未満の場合は、正常に終了するのではなく、エラーを終了する必要があります。


'sudo'を介して拡張機能を実行するように人々に要求することは非常に型破りです。

それを達成する別の方法はありませんか?初期化の要件は何ですか?すべてのプロセスに対して1回実行されますか、それともプロセスごとに1回実行されますか(したがって、連鎖が重要です)?


devwrapプログラムをSUIDルートにするだけでいいですか?次に、UIDを別の方法でリセットする必要があります。

setgid(getgid());
setuid(getuid());

これにより、コマンドを実行する前に、SGID性とSUID性がすべて削除されます。大きなダメージを与えるのはかなり難しいです。setgid()プログラムがSGIDなしでインストールされている場合、呼び出しが必須であるかどうかは明らかではありませんが、害もありません。

于 2010-11-18T07:44:17.627 に答える