/dev/urandomのddが早く停止するのはなぜですか? [コピー]

/dev/urandomのddが早く停止するのはなぜですか? [コピー]

dd現在、Linuxシステム(Debian Jessie amd64)では、動作が異なります/dev/urandom/dev/random動作は正しく文書化されています)。無邪気に1Gのランダムデータが必要な場合:

$ dd if=/dev/urandom of=random.raw bs=1G count=1
0+1 records in
0+1 records out
33554431 bytes (34 MB) copied, 2.2481 s, 14.9 MB/s
$ echo $?
0

この場合、34MBのランダムデータのみが保存されますが、複数の読み取りを使用する場合は次のようになります。

$ dd if=/dev/urandom of=random.raw bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB) copied, 70.4749 s, 14.9 MB/s

その後、1Gのランダムデータを正しく取得した。

その文書はやや/dev/urandom把握するのが難しいです。

/dev/urandomデバイスからの読み込みは、追加のエントロピーを待つことをブロックしません。したがって、エントロピープールに十分なエントロピーがない場合、返された値は理論的にドライバが使用するアルゴリズムによる暗号化攻撃に対して脆弱です。現在分類されていない文献にはこれを行う方法についての知識はありませんが、理論的にはそのような攻撃が存在する可能性があります。これがアプリケーションに問題がある場合は、代わりに/dev/randomを使用してください。

私は文書にある種の最大読み取りサイズがあることを示唆していると思いますurandom

私も私のシステムのエントロピープールサイズが34MBであると推測しています。これは、最初のread1Gが約34MBで失敗した理由を示しています。

しかし、私の質問は、エントロピープールのサイズをどのように知ることができるかということです。それともdd他の要因(ある種の関連タイミング問題urandom?)によってブロックされたのでしょうか。

答え1

確認してみると/dev/urandomで33554431バイトを読んだ後にEOFを提供する議論に続き、次のように言います。別のバグレポートTed Tsoは次のように指摘しています。

...commit 79a8468747c5 により 32MB より大きい読み取りが発生し、read(2) システムコールが 32MB だけ返されるようになりました。つまり、短い読み取りが発生します。 POSIXは常に短い読み取り(2)を許可し、すべてのプログラムは短い読み取りを確認する必要があります。

ddの問題は、POSIXにバイトではなく読み取りに基づくcount = Xパラメータが必要であることです。 iflag=fullblock に変更できます。

~によるとgnu dd 手動:

Note if the input may return short reads as could be the case when reading from
a pipe for example, ‘iflag=fullblock’ will ensure that ‘count=’ corresponds to
complete input blocks rather than the traditional POSIX specified behavior of
counting input read operations.

したがって、以下を追加するとiflag=fullblock

dd if=/dev/urandom of=random.raw bs=1G count=1 iflag=fullblock
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB) copied, 65.3591 s, 16.4 MB/s

これは実際に確認されました。おおよそのバイト数(または乗算サフィックスのページあたりの部分)である読み取り数をdd省略して増やすと、単純な警告が出力されます。iflag3232 x 33554431= 10737417921G1.1GBdd man

dd if=/dev/urandom of=random.raw bs=1G count=32
dd: warning: partial read (33554431 bytes); suggest iflag=fullblock
0+32 records in
0+32 records out
1073741792 bytes (1.1 GB) copied, 59.6676 s, 18.0 MB/s

答え2

私は以前はurandomのこの奇妙さを知りませんでしたが、ddの「短い読書」に触れます。望むより:

ddはいつデータのコピーに適していますか? (またはread()とwrite()が部分的な場合)

最初の例では、1つのread()呼び出しで1 GBのメモリをランダムなデータで埋めるようにカーネルに要求することです。メモリはゆっくり割り当てられているため、デフォルトでは、最初の呼び出しでプロセスに1 GBのメモリを割り当てるようにカーネルに要求します。彼らが早く止まった理由はいくつかあります。また、必要な操作を実行している場合は、試しているシステムによってはメモリが不足する可能性があります。

ああ、これがあなたのエントロピープールに関連しているかどうか疑問です。 urandom は、エントロピープールが使い果たされてもデータを返すため、便利です。

関連情報