5

So I have been googling about this OpenSSL heart-bleed thing and somehow sees that it is caused by the heartbeat extension which requires client to ping the server to show its aliveness and it all comes to this memcpy function in C which is meant to copy from the source array to the destination array with the user specified size.

If the size was a lie (which means the source contains lesser byte than the size claims) then memcpy will grab the arbitrary memory around and allocated to the destination and in this case send back to the client…

Reference: Anatomy of OpenSSL's Heartbleed: Just four bytes trigger horror bug

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...

If my understanding above is correct, then I have a question here maybe naive one, why do we have to do array (char array here) copying here? Can't we just pass on the source char array that the client sent to us?

i.e. If you send me

function(char[] array)

Then I would just need to send back that very array

send(array)
  • 4
    How long is char[] array? How do you know? – user40980 Apr 21 '14 at 14:11
  • Don't we have sizeof() in C/C++ ? anyway the thing here is not about the size, what I want to ask is that why don't we just give back the whole thing the client send to the server instead of copying the content of what the client sent to a buffer an then send the buffer – vcharlie Apr 22 '14 at 2:15
5

It's because of the way the network stack works in your operating system and standard libraries. An ethernet packet is a continuous stream of bits coming out of your computer. You can have gaps between packets, but not within them. For a 1 Gbps connection, that means every billionth of a second you have to be ready to transmit the next bit.

In order to allow software which is not real time to meet those strict timing requirements, the network stack sets up a buffer. Your non-real time server software fills the buffer, and the driver and hardware sends it out in real time.

Since you need different headers and other fields around the response (for example the source and destination addresses are reversed), and that information must be contiguous with the echoed payload in the transmit buffer, that necessitates a copy of the payload into the buffer.

Yes, you could avoid the copy by redesigning the network stack to use a different kind of data structure for the transmit buffer, like a list of pointers to arrays. However, that would have its own set of complexities, security issues, and inefficiencies.

Personally, I'm surprised security sensitive apps still allow the use of a raw memcpy. They have to do the bounds checking anyway, so why not create a safe buffer type and solve the problem once instead of continually having to watch out for these overflows via code review?

  • Ah! so what you mean is that the response is not purely just the same content the client sent to the server, but some additional information is added as well? I understand that we need buffer so that things can be sent all at once and continuous, but I was thinking why we don't just point to the original buffer we got from client... – vcharlie Apr 22 '14 at 2:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.