web-dev-qa-db-ja.com

vdsoおよびvsyscallとは何ですか?

やった Sudo cat /proc/1/maps -vv

出力の意味を理解しようとしています。予想どおり、メモリマッピングセグメントに多くの共有ライブラリがマップされています。

7f3c00137000-7f3c00179000 r-xp 00000000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c00179000-7f3c00379000 ---p 00042000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c00379000-7f3c0037a000 r--p 00042000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c0037a000-7f3c0037b000 rw-p 00043000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c0037b000-7f3c00383000 r-xp 00000000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00383000-7f3c00583000 ---p 00008000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00583000-7f3c00584000 r--p 00008000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00584000-7f3c00585000 rw-p 00009000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00585000-7f3c0059b000 r-xp 00000000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0
7f3c0059b000-7f3c0079b000 ---p 00016000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0
7f3c0079b000-7f3c0079c000 r--p 00016000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0

最後に向かってのようなものがあります

7f3c0165b000-7f3c0177e000 rw-p 00000000 00:00 0                          [heap]
7fff97863000-7fff97884000 rw-p 00000000 00:00 0                          [stack]
7fff97945000-7fff97946000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

vdsovsyscallはどういう意味ですか? vsyscallはメモリのカーネル部分ですか?誰もが問題に何らかの光を投げることができれば素晴らしいでしょう。

76
liv2hak

vsyscallおよびvDSOセグメントは、Linuxで特定のシステムコールを高速化するために使用される2つのメカニズムです。たとえば、gettimeofdayは通常このメカニズムを通じて呼び出されます。最初に導入されたメカニズムはvsyscallでした。これは、システムコールのオーバーヘッドを減らすために実行するために実際のレベルの特権を必要としない特定のシステムコールを実行する方法として追加されました。前の例に従って、gettimeofdayがする必要があるのは、カーネルの現在の時刻を読み取ることだけです。 gettimeofdayを頻繁に呼び出すアプリケーション(タイムスタンプを生成するためなど)があり、ほんの少しのオーバーヘッドでさえも気にします。この懸念に対処するために、カーネルは現在の時間と高速gettimeofday実装(つまり、vsyscall)。この仮想システムコールを使用して、Cライブラリは、従来のシステムコールモデルによって通常導入されるカーネル空間とユーザー空間の間のコンテキストスイッチによって導入されるオーバーヘッドのない高速gettimeofdayを提供できますINT 0x80またはSYSCALL

ただし、このvsyscallメカニズムにはいくつかの制限があります:割り当てられたメモリは小さく、4つのシステムコールのみを許可し、より重要かつ深刻なvsyscallページは、各プロセスで同じアドレスに静的に割り当てられます。これは、vsyscallページの場所がカーネルABIに固定されているためです。このvsyscallの静的な割り当ては、Linuxで一般的に使用されるメモリ空間のランダム化によってもたらされる利点を損ないます。攻撃者は、スタックオーバーフローを悪用してアプリケーションを危険にさらした後、vsyscallページから任意のパラメーターを使用してシステムコールを呼び出すことができます。彼が必要とするのは、システムコールのアドレスだけです。これは、静的に割り当てられるため、簡単に予測できます(異なるアプリケーションでもコマンドを再実行しようとすると、のアドレスvsyscallは変更されません)。このタイプの攻撃を阻止するために、vsyscallページの場所を削除するか、少なくともランダム化するのは良いことです。残念ながら、アプリケーションはそのページの存在と正確なアドレスに依存するため、何もできません。

このセキュリティ問題は、固定アドレスにあるすべてのシステムコール命令を特別なトラップ命令に置き換えることで解決されています。 vsyscallページを呼び出そうとするアプリケーションは、カーネルにトラップされ、カーネル空間で目的の仮想システムコールをエミュレートします。その結果、仮想システムコールをエミュレートするカーネルシステムコールが作成されます。仮想システムコールは、そもそもカーネルシステムコールを回避するために配置されました。結果はvsyscallであり、実行に時間がかかりますが、決定的に、既存のABIを壊しません。いずれの場合でも、アプリケーションがvDSOの代わりにvsyscallページを使用しようとしている場合にのみ、スローダウンが見られます。

vDSOは、vsyscallと同じ機能を提供しながら、その制限を克服します。 vDSO(仮想ダイナミックリンク共有オブジェクト)は、ユーザー空間に割り当てられたメモリ領域であり、ユーザー空間のカーネル機能を安全に公開します。これは、vsyscallによって引き起こされるセキュリティの脅威を解決するために導入されました。 vDSOは動的に割り当てられ、セキュリティの問題を解決し、4つ以上のシステムコールを持つことができます。 vDSOリンクは、glibcライブラリを介して提供されます。リンカはglibcvDSO機能にリンクします。ただし、そのようなルーチンにgettimeofday。プログラムの実行時に、カーネルにvDSOサポートがない場合、従来のsyscallが作成されます。

クレジットと便利なリンク:

133
Giuseppe Pes

これを新しいカーネルに追加したいのですが、vDSOは「安全な」syscallだけに使用されるのではなく、システムでsyscallを呼び出すための好ましいsyscallメカニズムを決定するために使用されます。

7
incompetent