No ping, por que precisamos fazer a cópia da matriz em vez de transmitir a matriz de origem que o cliente nos enviou?

5

Então eu estive pesquisando sobre essa coisa de sangramento no coração do OpenSSL e de alguma forma vê que é causada pela extensão heartbeat que requer que o cliente faça ping no servidor para mostrar sua vitalidade e tudo vem para essa função memcpy em C que significa para copiar da matriz de origem para a matriz de destino com o tamanho especificado pelo usuário.

Se o tamanho for uma mentira (o que significa que a fonte contém menos bytes do que o tamanho requer), então o memcpy vai pegar a memória arbitrária e alocar para o destino e, nesse caso, mandar de volta para o cliente…

Referência: Anatomia do Heartbleed do OpenSSL: apenas quatro bytes disparam o bug de horror

payload is controlled by the attacker, and it's quite large at 64KB. If the actual HeartbeatMessage sent by the attacker only has a payload of, say, one byte, and its payload_length is a lie, then the above memcpy() will read beyond the end of the received HeartbeatMessage and start reading from the victim process's memory...

Se o meu entendimento acima estiver correto, então eu tenho uma pergunta aqui, talvez ingênua, por que temos que fazer array (matriz de caracteres aqui) copiando aqui? Não podemos simplesmente transmitir a matriz de caracteres de origem que o cliente nos enviou?

i.e. Se você me enviar

function(char[] array)

Então eu só precisaria enviar de volta esse array

send(array)
    
por vcharlie 21.04.2014 / 10:32
fonte

1 resposta

5

É por causa da maneira como a pilha de rede funciona em seu sistema operacional e bibliotecas padrão. Um pacote ethernet é um fluxo contínuo de bits que sai do seu computador. Você pode ter lacunas entre pacotes, mas não dentro deles. Para uma conexão de 1 Gbps, isso significa que, a cada bilionésimo de segundo, você precisa estar pronto para transmitir o próximo bit.

Para permitir que o software não esteja em tempo real para atender a esses requisitos de tempo estritos, a pilha de rede configura um buffer. Seu software de servidor não em tempo real preenche o buffer, e o driver e o hardware o enviam em tempo real.

Como você precisa de cabeçalhos diferentes e outros campos ao redor da resposta (por exemplo, os endereços de origem e destino são invertidos), e essa informação deve ser contígua com a carga ecoada no buffer de transmissão, isso exige uma cópia da carga útil no buffer.

Sim, você poderia evitar a cópia redesenhando a pilha de rede para usar um tipo diferente de estrutura de dados para o buffer de transmissão, como uma lista de ponteiros para matrizes. No entanto, isso teria seu próprio conjunto de complexidades, problemas de segurança e ineficiências.

Pessoalmente, estou surpreso que aplicativos sensíveis à segurança ainda permitam o uso de memcpy bruto. Eles têm que fazer a verificação dos limites de qualquer maneira, então por que não criar um tipo de buffer seguro e resolver o problema uma vez, em vez de ter que ficar atento a esses overflows via revisão de código?

    
por 21.04.2014 / 17:33
fonte

Tags