/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

이것은 실제로 확인되었습니다 . 대략 바이트 수 (또는 곱셈 접미사의 페이지당 부분) 인 read 수를 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()가 부분적인 경우)

첫 번째 예에서 수행 중인 작업은 한 번의 read() 호출에서 1GB의 메모리를 임의의 데이터로 채우도록 커널에 요청하는 것입니다. 메모리는 느리게 할당되므로 기본적으로 첫 번째 호출에서 프로세스에 1GB의 메모리를 할당하도록 커널에 요청하는 것입니다. 그들이 일찍 멈춘 데에는 여러 가지 이유가 있을 수 있습니다. 또한 원하는 작업을 수행하는 경우 시도 중인 시스템에 따라 메모리가 부족할 수도 있습니다.

아, 이것이 당신의 엔트로피 풀과 관련이 있는지 의심스럽습니다. urandom은 엔트로피 풀이 소진되더라도 계속해서 데이터를 반환하므로 유용합니다.

관련 정보