14

Linux では、mmap(2) のマニュアル ページで、匿名マッピングが

. . . どのファイルにも支えられていません。その内容はゼロに初期化されます。

FreeBSD mmap(2) のマニュアル ページは、ゼロ フィルについて同様の保証を行っていませんが、非匿名マッピングのファイルの末尾の後のバイトはゼロ フィルであると約束しています。

匿名のmmapからゼロで初期化されたメモリを返すことを約束するUnixのフレーバーはどれですか? 実際にゼロ初期化されたメモリを返すが、man ページでそのような約束をしていないものはどれですか?

ゼロ埋めは部分的にセキュリティ上の理由によるものだというのが私の印象です。mmap 実装が、単一のプロセスによって mmap され、munmap され、次に再度 mmap されたページのゼロ埋めをスキップするかどうか、または実装が新しくマップされたページを疑似乱数ビットまたはゼロ以外の定数で埋めるかどうか疑問に思います。

PSどうやら、brk と sbrk でさえ、ゼロで​​埋められたページを保証するために使用されていました。Linux での私の実験では、sbrk 呼び出しによってページが割り当てられた後にページ フォールトで完全なページがゼロで埋められたとしても、部分的なページはそうではないことが示されているようです。

#include <unistd.h>
#include <stdio.h>

int main() {
  const intptr_t many = 100;
  char * start = sbrk(0);
  sbrk(many);
  for (intptr_t i = 0; i < many; ++i) {
    start[i] = 0xff;
  }
  printf("%d\n",(int)start[many/2]);
  sbrk(many/-2);
  sbrk(many/2);
  printf("%d\n",(int)start[many/2]);
  sbrk(-1 * many);
  sbrk(many/2);
  printf("%d\n",(int)start[0]);
}
4

2 に答える 2

5

匿名のmmapからゼロで初期化されたメモリを返すことを約束するUnixのフレーバーはどれですか?

GNU/リナックス

質問で述べたように、Linux バージョンの mmap は、匿名マッピングをゼロで埋めることを約束します。

MAP_ANONYMOUS

マッピングは、どのファイルにも支えられていません。その内容はゼロに初期化されます。

NetBSD

mmapのNetBSD バージョンは、匿名マッピングをゼロで埋めることを約束します。

MAP_ANON

特定のファイルに関連付けられていない匿名メモリをマップします。ファイル記述子は、MAP_ANONリージョンの作成には使用されないため、 として指定する必要があります-1。マップされたメモリはゼロで埋められます。

OpenBSD

mmapのOpenBSD マンページは、匿名マッピングをゼロで埋めることを約束していません。ただし、Theo de Raadt (著名な OpenBSD 開発者) は、2019 年 11 月に OpenBSD メーリング リストで次のように宣言しました。

もちろんゼロ埋めです。他に何がありますか?もっともらしい代替案はありません。

あまりにも明白なことを言うと、メッセージの残りの部分が損なわれると思います。

そして、他の OpenBSD 開発者は彼に反対しませんでした。

IBM AIX

mmapのAIX バージョンは、匿名マッピングをゼロで埋めることを約束します。

MAP_ANONYMOUS

すべてゼロに初期化される新しい匿名メモリ領域の作成を指定します。

HP-UX

nixdoc.net によると、HP-UX バージョンの mmap は匿名マッピングをゼロで埋めることを約束しています。

MAP_ANONYMOUSが に設定されている場合flags、新しいメモリ領域が作成され、すべてゼロに初期化されます。

ソラリス

Solaris バージョンの mmap は、無名マッピングをゼロで埋めることを約束します。

MAP_ANONが で設定されflagsfildesが -1 に設定されている場合mmap()、匿名ページを呼び出し元に返す直接パスを提供します。この操作は、引数から省略してmmap()開いているファイル記述子を渡すことと同じです。/dev/zeroMAP_ANONflags

この Solaris man ページは、フラグで使用される mmap の動作に依存せずに、ゼロで埋められたメモリ ページを取得する方法を提供します。フラグをMAP_ANONYMOUS使用せずMAP_ANONYMOUS、ファイルに基づくマッピングを作成し/dev/zeroます。ファイルを提供している Unix ライクなオペレーティング システムのリストを知っておくと、このアプローチがフラグ/dev/zeroを使用するよりも移植性が高いかどうかを確認するのに役立ちます ( /dev/zeroMAP_ANONYMOUSも POSIX ではありません)。MAP_ANONYMOUS

興味深いことに、/dev/zero に関するウィキペディアの記事では、匿名マッピングを作成するときMAP_ANONYMOUSに開く必要がなくなるように導入されたと主張しています。/dev/zero

于 2020-12-01T04:30:22.627 に答える