保存されたuidが変数の場合。

保存されたuidが変数の場合。

私が知る限り、さまざまなユーザーIDは次のとおりです(プロセスの観点から)。

  • 実際のユーザーID:プロセスを所有するユーザーID
  • 有効ユーザーID:現在許可されているものと許可されていないものを決定するユーザーID。
  • 保存されたユーザーID:デフォルトでは元の有効ユーザーIDで、必要に応じて元の有効ユーザーIDに戻すことができます。

今、2つの質問があります。

  1. プログラムの起動時に有効なユーザーIDを変数に保存すると、保存する必要のないユーザーIDになりますか?

  2. Cプログラムで保存されたユーザーIDを取得するには?これを行う機能が見つかりません。

答え1

プログラムの起動時に有効なユーザーIDを変数に保存すると、保存されたユーザーIDは不要になりますか?

ユーザー空間プログラムが何を覚えているのではなく、カーネルがどの権限を使用できるかが問題です。ユーザーを分離するには、システムがプロセスで使用できるユーザーIDを制御する必要があります。それ以外の場合は、すべてのプロセスでroot権限を要求できます。

Cプログラムで保存されたユーザーIDを取得するには?これを行う機能が見つかりません。

getuid()これは標準関数(sumのみ)を使用することはできませんgeteuid()。少なくともLinuxはgetresuid()ただし、3 つのユーザー ID がすべて返されます。

とにかく一般的に読む必要はありません。 setuid プログラムの場合、実際のユーザー ID と実効ユーザー ID の間の切り替えが許可されるため、実効ユーザー ID のコピーから始まります。

setuidプログラムでは、実際のユーザーIDはプログラムを実行しているユーザーのIDであり、有効で保存されたユーザーIDはそのプログラムを所有するユーザーのIDです。有効なユーザー ID は権限の確認に非常に重要であるため、プロセスが一時的に権限を放棄したい場合は、実際のユーザー ID と保存されたユーザー ID の間で有効なユーザー ID を変更します。

プロセスがユーザーIDを変更できることを確認するために、カーネルは保存されたユーザーIDをどのように使用しますか?これは、プロセスが有効なユーザーIDを変更しようとしたときにカーネルが保存されているユーザーIDを調べて、プロセスがそのようにできることを確認することを意味しますか?

はい。 Linuxのマニュアルページにsetuid()これについての言及がありますが、やや隠されています。

ERRORS     
EPERM  The user is not privileged and uid does not match the real
       UID or saved set-user-ID of the calling process.

つまり、(有効な)ユーザIDは、実際のIDまたは保存されたIDのいずれかを設定することができる。

setreuid()これについてのマニュアルページがより明確です。

Unprivileged processes may only set the effective user ID to the real
user ID, the effective user ID, or the saved set-user-ID.

答え2

保存されたuidが変数の場合。

有効または実際のuidにコピーする権限がないため、一般変数は使用できません。コアできない一般変数からコピーできます。これはあなたが望むようにすることができます(大丈夫ですが、値がすでにsの1つにある場合にのみuid)。

そうですね。有効なuidは、システムコールの権限を確認するために使用されます。例外はsetuid/ですsetgid(関数を参照)。

権限はsetuid次のとおりです。 IDを移動できますが(あるuidから別のuidへ)、新しいIDを導入することはできません(CAP_SETUIDこれを含む:rootがない限り)。

だから一般ユーザーとして。 1 つまたは 2 つの uid (実際と有効ですが、両方とも同じことができる) で始まります。異なる場合は、実際のアイテムを有効なアイテムにコピーできます。そうすれば、元に戻せずに一つだけ残ります。カーネルは通常の変数からロードすることを許可しません。したがって、有効なコンテンツを保存ファイルにコピーします。残りの実行では、元の有効なコンテンツを保存しますが、これは本当です。これで、Effective-uidにコピーして有効にすることができます。しばらくすると、1つを捨てることができます。たとえば、real を他の 2 つにコピーします。もう元に戻せません。今、権限を取得する唯一の方法はexecsetuidバイナリを使用することです。 (または新機能を備えたバイナリですが、今は心配しないでください)。

suidを取得するには、次のものを使用できますgetresuidhttp://man7.org/linux/man-pages/man2/getresuid.2.html

実際には通常のC変数を使用してください。ただし、uid値がuidの1つにすでに含まれていない場合は、その値を追加できません。

/*setup UIDs*/
uid_t real_uid = getuid(void);
uid_t original_effective_uid = geteuid(void);
int err = setresuid(real_uid, original_effective_uid, original_effective_uid); /*this line not needed as done by kernel for setuid binary*/
#ifdef see_effect_of_no_suid
   int err = setresuid(real_uid, original_effective_uid, real_uid);     
#endif
while (true) {
   err=seteuid(original_effective_uid);
   /*do stuff as original_effective uid*/

   err=seteuid(real_uid);
   /*do stuff as real uid*/
}

関連情報