非特権モードにもかかわらず、mmap'ing /dev/memはどのように機能しますか?

非特権モードにもかかわらず、mmap'ing /dev/memはどのように機能しますか?

私が理解したのは、ユーザー空間プログラムは非権利モードで実行されるため、メモリやI / Oに直接アクセスできないことです。

それでは、ユーザー空間プログラムで/dev/memをmmapするときに、どのようにメモリまたはI/Oの場所に直接アクセスできますか?

たとえば、

int fd = 0;
u8 leds = 0;
fd = open("/dev/mem", O_RDWR|O_SYNC);
leds = (u8 *)mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x80840000);

これは組み込みデバイスで非常に一般的な技術です。

この変数をledsすぐに使用して、0x80840000に存在できるすべてのデバイスにアクセスできるようになりました。

我々はもはやこのアドレスにアクセスするためにシステムコールを使用しません。

でも好き

leds[0x20] = val;

動作します。

ただし、I / Oアドレスからの直接読み取り/書き込みなどの特権操作は、システムコールを介してプロセッサを特権モードにすることによってのみ達成できます。

源泉

答え1

権限のないプロセスへのアクセスを許可することは/dev/mem実際にはセキュリティ上の問題であるため、許可しないでください。

私のシステムでは、ls -l /dev/mem次のようになります。

crw-r----- 1 root kmem 1, 1 Sep  8 10:12 /dev/mem

したがってroot、読んで書くことができ、kmemグループメンバー(誰もいない)を読むことはできますが、書くことはできず、他の人はまったく開くことができません。だからこれは安全でなければなりません。

あなたの/dev/memものが私のようなものであれば、あなたの権限を持たないプロセスは、ファイルはどこでも開けられないはずですmmap

システムの権限が安全である/dev/memことを確認してください!

答え2

ルートとして実行するか、権限のないユーザーとして実行する場合でも、ユーザープロセスに表示されるアドレスは、ページテーブルを介してMMUによって物理アドレスにマッピングされる仮想アドレスです。ページテーブルの設定は特権操作であり、カーネルコードでのみ実行できます。ただし、ページテーブルが設定されると、ユーザーモードでメモリへのアクセスが許可されます。

具体的には、コードは、カーネルに特定のmmap範囲の物理メモリへのアクセスを許可するようにページテーブルを設定するように要求するために使用されます。カーネルはプロセスの権限(読み取り/書き込みアクセス権を持つ/dev/mem)を確認し、物理メモリにアクセスできるようにページテーブルを設定します。

答え3

値はleds仮想アドレスです。現在のプロセスのユーザースペースにある限り、プロセスは仮想アドレスがleds[0] = valRAM上のどの場所にマップされていても、特権モードにせずにコマンドを介して直接アクセスできます。

関連情報