Por que o dd de / dev / urandom para mais cedo? [duplicado]

13

No meu sistema Linux atual (Debian Jessie amd64), estou obtendo um comportamento diferente para dd usando /dev/urandom ( /dev/random behavior está apropriadamente documentado). Se eu ingenuamente quiser 1G de dados aleatórios:

$ 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

Neste caso, apenas 34MB de dados aleatórios são armazenados, enquanto que se eu usar várias leituras:

$ 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

então eu recebo corretamente meu 1G de dados aleatórios.

A documentação para /dev/urandom é um pouco evasiva:

A read from the /dev/urandom device will not block waiting for more entropy. As a result, if there is not sufficient entropy in the entropy pool, the returned values are theoretically vulnerable to a cryptographic attack on the algorithms used by the driver. Knowledge of how to do this is not available in the current unclassified literature, but it is theoretically possible that such an attack may exist. If this is a concern in your application, use /dev/random instead.

Eu acho que a documentação implica que há algum tipo de tamanho máximo de leitura para urandom .

Eu também estou supondo que o tamanho do pool de entropia é 34MB no meu sistema, o que explicaria porque o primeiro read de 1G falhou em cerca de 34MB.

Mas a minha pergunta é como eu sei o tamanho da minha piscina de entropia? Ou será dd interrompido por outro fator (algum tipo de problema de sincronização associado a urandom ?).

    
por malat 13.01.2015 / 17:19

2 respostas

17

Se você verificar Ler de / dev / urandom dará EOF após 33554431 bytes e seguir a discussão, ele aponta para outro relatório de bug onde Ted Tso declara ...

...that commit 79a8468747c5 causes reads larger than 32MB results in a only 32MB to be returned by the read(2) system call. That is, it results in a short read. POSIX always allows for a short read(2), and any program MUST check for short reads.

The problem with dd is that POSIX requires the count=X parameter, to be based on reads, not on bytes. This can be changed with iflag=fullblock.

Como por gnu dd manual :

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.

se você adicionar 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

Isso é confirmado por dd , se você omitir iflag e aumentar a contagem para obter 32 leituras, ou seja, 32 x 33554431 bytes = 1073741792 bytes, que é aproximadamente 1G (ou 1.1GB conforme dd man seção da página sobre sufixos multiplicativos), será emitida uma breve advertência:

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
    
por 13.01.2015 / 17:53
3

Eu não estava ciente dessa estranheza com o urandom, mas você está executando "short reads" com o dd. Veja:

Quando o dd é adequado para copiar dados? (ou, quando são lidos () e escritos () parciais)

O que você está fazendo no primeiro exemplo é pedir ao Kernel para preencher 1GB de memória com dados aleatórios em uma única chamada para read (). Como a memória é alocada preguiçosamente, você está essencialmente pedindo ao kernel para alocar 1GB de memória em seu processo naquela primeira chamada. Pode haver vários motivos pelos quais eles param mais cedo. Além disso, se ele fez o que você pediu, você pode ficar sem memória RAM dependendo do sistema em que você está tentando isso.

Ah, e duvido que tenha algo a ver com o seu pool de entropia. urandom é útil exatamente porque ele continuará retornando dados mesmo quando o pool de entropia estiver esgotado.

    
por 13.01.2015 / 17:32

Tags