1353: "Heartbleed"

This forum is for the individual discussion thread that goes with each new comic.

Moderators: Moderators General, Prelates, Magistrates

speising
Posts: 2353
Joined: Mon Sep 03, 2012 4:54 pm UTC
Location: wien

Re: 1353: "Heartbleed"

Postby speising » Thu Apr 10, 2014 10:36 pm UTC

how, exactly, does the use of stl affect a user of the binary?

KarenRei
Posts: 285
Joined: Sat Jun 16, 2012 10:48 pm UTC

Re: 1353: "Heartbleed"

Postby KarenRei » Fri Apr 11, 2014 2:27 am UTC

PhoenixRising wrote:The problem with STL, and C++ in general, is the lack of a well-defined ABI (application binary interface; basically an agreement on the size, layout, etc. of data in memory).


So? The API is well defined, that's all that should matter. It's to be *expected*, if only for performance reasons, that implementations won't be identical between platforms. C structures aren't guaranteed to be aligned identically either. At least there's a standard way in C++11 to force identical alignment; in C, it's only compiler-dependent extensions.

If you're sharing data between platforms, you need to align it and manage endianness yourself. And if you're using a language where that's done for you automatically, your performance probably sucks.

Even more importantly, using C++ STL containers means only C++ apps can use OpenSSL.


What's wrong with having a C wrapper, like pretty much everyone else does in this situation? And let's take your argument further - should everyone who programs C libraries have to stick to C89 so that people writing programs in C89 don't have to switch? Backwards compatibility shouldn't a suicide pact. The world moves on. Libraries get written in C++. And people deal.

User avatar
PhoenixRising
Posts: 129
Joined: Wed Mar 27, 2013 3:53 am UTC

Re: 1353: "Heartbleed"

Postby PhoenixRising » Fri Apr 11, 2014 4:31 am UTC

speising wrote:how, exactly, does the use of stl affect a user of the binary?

Anyone who picks up a an app using an OpenSSL implementation built with, say, MSVC will have tremendous compatibility issues if the server's OpenSSL is built with, say, GCC or clang.

KarenRei wrote:
PhoenixRising wrote:The problem with STL, and C++ in general, is the lack of a well-defined ABI (application binary interface; basically an agreement on the size, layout, etc. of data in memory).


So? The API is well defined, that's all that should matter. It's to be *expected*, if only for performance reasons, that implementations won't be identical between platforms. C structures aren't guaranteed to be aligned identically either. At least there's a standard way in C++11 to force identical alignment; in C, it's only compiler-dependent extensions.

If you're sharing data between platforms, you need to align it and manage endianness yourself. And if you're using a language where that's done for you automatically, your performance probably sucks.

Out of curiosity, did you actually read the threads I linked? It's not just alignment issues and it's not just different implementations between platforms. It's different implementations between different builds on the same platform, too. An OpenSSL implementation built with MSVC 2008 is not guaranteed to be compatible with an implementation built with MSVC 2013. An implementation built with any version of MSVC is not guaranteed compatibility with an implementation built with GCC. An implementation built with GCC is not guaranteed compatibility with an implementation built with clang. And so forth, and so on. Even if the human-readable code is precisely the same, the compiled version will not be, and I feel this is a much bigger issue than you seem to think it is.

KarenRei wrote:
Even more importantly, using C++ STL containers means only C++ apps can use OpenSSL.


What's wrong with having a C wrapper, like pretty much everyone else does in this situation? And let's take your argument further - should everyone who programs C libraries have to stick to C89 so that people writing programs in C89 don't have to switch? Backwards compatibility shouldn't a suicide pact. The world moves on. Libraries get written in C++. And people deal.


If we have a C wrapper, there will have to be some form of translation from the C++ STL back into raw C, and that defeats the entire point of using C++. This is all the more true because, to avoid cross-compiler compatibility issues, the actual sending and receiving of data would be done into the raw C wrapper, with the C++ code acting purely as a backend. There will be plenty of room for bugs in such a setup.
riverssong wrote:I step away for ten minutes and y'all are creating a new civilization?!

This is getting out of hand. Stop that right this minute.

justvisiting
Posts: 9
Joined: Fri May 17, 2013 10:21 am UTC

Re: 1353: "Heartbleed"

Postby justvisiting » Fri Apr 11, 2014 5:09 am UTC

PhoenixRising wrote:Anyone who picks up a an app using an OpenSSL implementation built with, say, MSVC will have tremendous compatibility issues if the server's OpenSSL is built with, say, GCC or clang.


Sorry, but that's not how it works. The SSL/TLS protocol specifies the format of data to be exchanged, which the client and server must follow regardless of what they are written in. Think about it: there are already several different SSL/TLS implementations (of which OpenSSL is just one), written in different languages and they all interoperate just fine.

jareds
Posts: 436
Joined: Wed Jan 03, 2007 3:56 pm UTC

Re: 1353: "Heartbleed"

Postby jareds » Fri Apr 11, 2014 6:17 am UTC

KarenRei wrote:
PhoenixRising wrote:The problem with STL, and C++ in general, is the lack of a well-defined ABI (application binary interface; basically an agreement on the size, layout, etc. of data in memory).


So? The API is well defined, that's all that should matter. It's to be *expected*, if only for performance reasons, that implementations won't be identical between platforms. C structures aren't guaranteed to be aligned identically either. At least there's a standard way in C++11 to force identical alignment; in C, it's only compiler-dependent extensions.

If you're sharing data between platforms, you need to align it and manage endianness yourself. And if you're using a language where that's done for you automatically, your performance probably sucks.


[EDIT: The following assumes that KarenRei was advocating a C++ interface for the OpenSSL library. In context, that was not a reasonable assumption, but my post accurately outlines the problems with that approach. There is of course no ABI compatibility impediment to a library that uses C++, or any other language, internally, but provides a C interface.]

This is confused. ABIs have nothing to do with cross-platform compatibility, but rather with link-time compatibility (and therefore library compatibility) between compilers on a single platform. That is, the ability to take a .so or .a or .lib or .dll built with compiler A and use it with code built with compiler B.

It is true that neither the C nor the C++ standard define an ABI. But it is not really plausible not to acknowledge that C ABIs are much better standardized than C++ ABIs. Basically every modern OS has a well-defined C ABI for every architecture that it supports. Most modern architectures even have a well-defined C ABI (e.g., by the processor vendor) for embedded use without an OS, but a few do not. Even the basic core language C++ ABI situation is well below this bar, although the Itanium C++ ABI is pretty popular. However, when you factor in the languages' standard libraries, the ABI compatibility difference is off the charts. Typically FILE is the only C standard library type that is left opaque by a C ABI, but code outside the library itself only deals with FILE * values, not FILE values, so you're fine unless you manage to use two different C libraries in one program, which would be unusual. With C++, there are a plethora of opaque standard library types that are intended to be used by value outside the standard library itself, and there simply is not any real cross-compiler ABI that defines the implementation of them all. For example, std::string values cannot cross compiler boundaries unless the compilers have the same implementation of std::string, even if the compilers use the same core language C++ ABI, whereas FILE * values can cross compiler boundaries (unless, as I said, you use two different copies of the C library in one program). [Edit: This is a bit oversimplified, but I don't think that it's misleadingly so.]

Nor is it plausible to claim that API compatibility is all that matters. Shared libraries are not an obscure thing that no one uses.

The situation is intended to improve starting with C++17, but the current reality is that C is dramatically better for shared libraries if you care about compatibility between compilers. There is a reason why a C foreign function interface is the FFI of choice for most non-C languages. (And, arguably, 'extern "C"' is C++'s FFI.)
Last edited by jareds on Fri Apr 11, 2014 9:57 am UTC, edited 1 time in total.

User avatar
PhoenixRising
Posts: 129
Joined: Wed Mar 27, 2013 3:53 am UTC

Re: 1353: "Heartbleed"

Postby PhoenixRising » Fri Apr 11, 2014 7:23 am UTC

justvisiting wrote:
PhoenixRising wrote:Anyone who picks up a an app using an OpenSSL implementation built with, say, MSVC will have tremendous compatibility issues if the server's OpenSSL is built with, say, GCC or clang.


Sorry, but that's not how it works. The SSL/TLS protocol specifies the format of data to be exchanged, which the client and server must follow regardless of what they are written in. Think about it: there are already several different SSL/TLS implementations (of which OpenSSL is just one), written in different languages and they all interoperate just fine.


If C++ STL containers are being passed back and forth, yes, this becomes very relevant. And my post was only about writing an OpenSSL version in C++.

Furthermore, if data is internally handled via C++ and passed from client to server and back via a C wrapper - not unlike the current situation - there's no reason to be using those C++ STL containers in the first place, because the extra layer is just slowing things down. There will still be plenty of room for bugs to show up in the wrapper.

jareds wrote:It is true that neither the C nor the C++ standard define an ABI. But it is not really plausible not to acknowledge that C ABIs are much better standardized than C++ ABIs. Basically every modern OS has a well-defined C ABI for every architecture that it supports. Most modern architectures even have a well-defined C ABI (e.g., by the processor vendor) for embedded use without an OS, but a few do not. Even the basic core language C++ ABI situation is well below this bar, although the Itanium C++ ABI is pretty popular.


Exactly. Your entire post is exactly what I've been trying to say.

In a nutshell, the API becomes irrelevant if the ABI isn't well-defined. It doesn't matter whether the client and server agree that X data will be sent as std::string if they can't agree on what exactly a std::string looks like. And there are so many facets of this that vary from one STL implementation to another.
riverssong wrote:I step away for ten minutes and y'all are creating a new civilization?!

This is getting out of hand. Stop that right this minute.

justvisiting
Posts: 9
Joined: Fri May 17, 2013 10:21 am UTC

Re: 1353: "Heartbleed"

Postby justvisiting » Fri Apr 11, 2014 7:49 am UTC

PhoenixRising wrote:
If C++ STL containers are being passed back and forth, yes, this becomes very relevant. And my post was only about writing an OpenSSL version in C++.


But the point is that passing STL containers between client and server is never ever an option in this case because the protocol specification already tells you exactly how to format the data being passed around. When you implement a TLS library you don't get any choice on that matter, you need to follow the protocol or it will simply not work. This applies to every standard protocol, not just TLS and the whole point of having these standard protocols is precisely so that one implementation does not have to worry about platform-specific issues of the other implementations.

Furthermore, if data is internally handled via C++ and passed from client to server and back via a C wrapper - not unlike the current situation -


I'm not sure what you mean by this. Are you saying that every non-C implementation of a binary protocol (like TLS) uses C wrapper to send/receive data? Because that is very far from reality.

User avatar
PhoenixRising
Posts: 129
Joined: Wed Mar 27, 2013 3:53 am UTC

Re: 1353: "Heartbleed"

Postby PhoenixRising » Fri Apr 11, 2014 9:24 am UTC

justvisiting wrote:
PhoenixRising wrote:
If C++ STL containers are being passed back and forth, yes, this becomes very relevant. And my post was only about writing an OpenSSL version in C++.


But the point is that passing STL containers between client and server is never ever an option in this case because the protocol specification already tells you exactly how to format the data being passed around. When you implement a TLS library you don't get any choice on that matter, you need to follow the protocol or it will simply not work. This applies to every standard protocol, not just TLS and the whole point of having these standard protocols is precisely so that one implementation does not have to worry about platform-specific issues of the other implementations.


My understanding of KarenRei's arguments is that STL containers should be exposed and worked with. Such behavior would be extremely non-portable from one system to another or even within the same system.

justvisiting wrote:
Furthermore, if data is internally handled via C++ and passed from client to server and back via a C wrapper - not unlike the current situation -


I'm not sure what you mean by this. Are you saying that every non-C implementation of a binary protocol (like TLS) uses C wrapper to send/receive data? Because that is very far from reality.


No, what I'm saying is that if we're pulling data out of the C++ STL containers and converting it into raw C data, that's not that unlike doing the entire implementation in C. Take the heartbeat code, for example. I'm tired so it's possible I'm misremembering something, but from my look at the patch it looks like the received buffer was being unpacked, then a new buffer immediately allocated and repacked. This would still happen with a raw C wrapper around a C++ lib. The results might be somewhat less disastrous ("just" a crash) depending on how the code is written, but there would still be an invalid buffer floating around C code, which means there's still plenty of opportunity for it to wreak havoc before it gets to the C++ code. There would be some additional breathing room once all the data actually makes it safely into the C++ library, no doubt, but claiming that C++ is the panacea for invalid buffers when a C wrapper has to go around that library anyway seems rather illogical. There are still all the same problems with having to check inputs for validity and having to ensure outputs are properly set up. All that's protected is the backend processing the C++ code is doing.

I'm writing a C wrapper around a C++ library of my own right now, and it's something of a pain. Every input parameter has to be checked for validity within the C code before I feed it to the actual C++ library, and when you look at a wrapper like that in a program like OpenSSL, missing a validity check can have some major consequences.
riverssong wrote:I step away for ten minutes and y'all are creating a new civilization?!

This is getting out of hand. Stop that right this minute.

KarenRei
Posts: 285
Joined: Sat Jun 16, 2012 10:48 pm UTC

Re: 1353: "Heartbleed"

Postby KarenRei » Fri Apr 11, 2014 9:41 am UTC

It's not just alignment issues and it's not just different implementations between platforms. It's different implementations between different builds on the same platform, too.


And? If you can't guarantee it between different platforms, then what good does it do to mandate that different compilers on a given platform have to use the same internal structures? Either you have an ABI guarantee or you don't. As stated, at least C++ gives you standardized ways to align your data structures. C does not. This is a problem, I work in my job with C data structures that have to be aligned on different platforms, and it's a pain.

If we have a C wrapper, there will have to be some form of translation from the C++ STL back into raw C


Yes, a single-stage one-step translation between char* and std::string. Not exactly a deal-breaker. If you can't avoid catastrophic failure while writing a simple wrapper between char* and std::string, you don't deserve to call yourself a programmer.

jareds
Posts: 436
Joined: Wed Jan 03, 2007 3:56 pm UTC

Re: 1353: "Heartbleed"

Postby jareds » Fri Apr 11, 2014 9:46 am UTC

PhoenixRising wrote:
jareds wrote:It is true that neither the C nor the C++ standard define an ABI. But it is not really plausible not to acknowledge that C ABIs are much better standardized than C++ ABIs. Basically every modern OS has a well-defined C ABI for every architecture that it supports. Most modern architectures even have a well-defined C ABI (e.g., by the processor vendor) for embedded use without an OS, but a few do not. Even the basic core language C++ ABI situation is well below this bar, although the Itanium C++ ABI is pretty popular.


Exactly. Your entire post is exactly what I've been trying to say.

In a nutshell, the API becomes irrelevant if the ABI isn't well-defined. It doesn't matter whether the client and server agree that X data will be sent as std::string if they can't agree on what exactly a std::string looks like. And there are so many facets of this that vary from one STL implementation to another.

Oops. I missed your original post because it was at the end of the page, and didn't realize that KarenRei only quoted your sentences that, standing alone, are correct. You are confused yourself.

It was not reasonable to think that KarenRei was talking about rewriting the SSL/TLS protocol to be based on C++; my response was only assuming that she was talking about rewriting the OpenSSL library to be based on C++ in its API. Standardized network protocols are basically never based on sending binary copies of some particular language's data structures over the network. If nothing else, this would have byte order (endianness) issues. Consequently, neither language APIs nor language ABIs are relevant to network protocols.

Here is what the ABI issue means for a library like OpenSSL:
I have an OpenSSL shared library, libssl.so.1.0.0, on my machine.
Say I build a program, apache2, that uses that library.
Right now, it doesn't matter if libssl.so.1.0.0 is built with GCC and I build apache2 with Clang. The C ABI for my machine is very well-standardized.
However, if OpenSSL were a C++ library that involved the passing of complex C++ data types across the library boundary, I would potentially have trouble (and I would very likely have trouble if, say, I had LIBSSL.DLL built with MinGW and built an application to use it with MS Visual Studio, whereas trouble would be unlikely with a pure C interface). It wouldn't really relate to the network communication--a straight-up crash is more likely.

KarenRei
Posts: 285
Joined: Sat Jun 16, 2012 10:48 pm UTC

Re: 1353: "Heartbleed"

Postby KarenRei » Fri Apr 11, 2014 10:00 am UTC

My understanding of KarenRei's arguments is that STL containers should be exposed and worked with.


They should be exposed and worked with... *internally*. Data passed *between* processes, however, needs to follow a protocol. You have to have serialized data out and in. It's the only reliable way without operating in an environment which ensures alignment and endianness is always identical on all platforms, and any such environment would have such a huge performance penalty that you wouldn't want to use it. Align and endian-correct it however you want, but you *have* to do it.

Once OpenSSL gets plain data, it should be switched to STL. It should not be switched back to plain data until it gets sent out. Doesn't matter whether it gets plain data from a packet reader or an API wrapper call, the first step is to put it into a reliable, bug-reducing format like STL objects.

Take the heartbeat code, for example. I'm tired so it's possible I'm misremembering something, but from my look at the patch it looks like the received buffer was being unpacked, then a new buffer immediately allocated and repacked.


The bug was of course at the steps *in-between* that do the actual packet building when you're doing the actual risky ops (data manipulation, memory handling, etc).

Any wrapper is literally just:

Code: Select all

std::string SomeSTDString(SomeCString);


What is so bloody hard or risk prone about that? The only potential screwup is if SomeCString is malformed, but if they're passing a malformed C string, then it would be broken in any possible implementation of the code.

And once again, I ask you to take your logic and apply it elsewhere. Should everyone have to program their libraries in C89 so that people who don't want to use C99 don't have to upgrade? Who ever uses long long ints, inline functions, inline variable declaration and one-line comments, right? Don't like wrappers? Fine, demand people use a compiler for their programs (C++) that doesn't mandate that they program in risky manners. They can still program just the same, C code with a C++ compiler. We don't mandate libraries have to use C89 because we expect at some point people will learn to move on from inferior, outdated ways of doing things or at least get themselves a compiler that's capable of it.
Last edited by KarenRei on Fri Apr 11, 2014 10:07 am UTC, edited 2 times in total.

KarenRei
Posts: 285
Joined: Sat Jun 16, 2012 10:48 pm UTC

Re: 1353: "Heartbleed"

Postby KarenRei » Fri Apr 11, 2014 10:02 am UTC

jareds wrote:It was not reasonable to think that KarenRei was talking about rewriting the SSL/TLS protocol to be based on C++; my response was only assuming that she was talking about rewriting the OpenSSL library to be based on C++ in its API. Standardized network protocols are basically never based on sending binary copies of some particular language's data structures over the network.


You are absolutely correct, and I have no idea why they were talking as if one would send raw C++ objects over the net, at least without guaranteeing alignment and endianness first. You don't do that in C and you don't do that in C++ either.

jareds
Posts: 436
Joined: Wed Jan 03, 2007 3:56 pm UTC

Re: 1353: "Heartbleed"

Postby jareds » Fri Apr 11, 2014 10:10 am UTC

For the record, you managed to overstate the effect of C++ ABI issues.
PhoenixRising wrote:For a security library which is as widely used as OpenSSL, this could be disastrous - how do you guarantee your server's STL-based version of OpenSSL is compatible with a given client's STL-based OpenSSL?

Everyone has explained that this is wrong. There's not even any requirement that both the client and server are both using OpenSSL in the first place. In fact, NSS is more common than OpenSSL as a client TLS library.
PhoenixRising wrote:Additionally, anyone who wanted to work with the OpenSSL source would need to use exactly the same version of the same compiler as the official OpenSSL lib.

This is also wrong; if you're working with the source of a library you're presumably building it completely from source and can use absolutely any compiler you like.

KarenRei wrote:You are absolutely correct, and I have no idea why they were talking as if one would send raw C++ objects over the net, at least without guaranteeing alignment and endianness first. You don't do that in C and you don't do that in C++ either.

Right, I assumed that I was jumping into a discussion about the merits of changing OpenSSL's API to C++ because the concept of changing the SSL/TLS protocol to "C++" would never have occurred to me. My bad.

User avatar
Philbert
Posts: 32
Joined: Mon Jan 05, 2009 12:32 pm UTC

Re: 1353: "Heartbleed"

Postby Philbert » Fri Apr 11, 2014 12:10 pm UTC

stankyjim wrote:
Philbert wrote:wouldn't an attacker still need command line access on the web server? Getting such access should be hard, right? Doesn't that make this problem less severe than it is drummed up to be?


Security expert here!

Nope command line access is not needed, after a connection is established and TLS encryption negotiated the client requests a heart beat keep alive to take place. If the client requests an oversized keep alive reply, the server will respond with data which due to a bug contains a portion of the server's operational memory.

This process is repeated over and over again until the attacker has however much memory as they desire.

This vulnerablity is likely the most devastating that we have seen in the past decade.



Cool Thanks! Great to see that Randall made your explanation into the next strip!

Random832
Posts: 2525
Joined: Wed Oct 10, 2007 4:38 pm UTC

Re: 1353: "Heartbleed"

Postby Random832 » Fri Apr 11, 2014 12:51 pm UTC

Ken_g6 wrote:If they'd used a secure malloc that wipes the memory it allocates


Would that help? I thought it was going into the next block, not reading uninitialized data that's still technically part of the same proper block. Wiping when freed could help, but not if the memory next to it is still live.

Mazzula
Posts: 54
Joined: Mon Sep 08, 2008 5:22 pm UTC

Re: 1353: "Heartbleed"

Postby Mazzula » Fri Apr 11, 2014 2:25 pm UTC

KarenRei wrote:I was copying straight from the patch that introduced the bug, although your version makes more sense - perhaps the original patch contained a different bug that was quickly patched?

The bug first went into the wild with version 1.0.1, on March 14, 2012. The source tarball is here...
http://www.openssl.org/source/openssl-1.0.1.tar.gz
That has the code that I saw.

KarenRei wrote:That's part of the problem of having only a partial implementation here, I wasn't about to go back and rework the entire openssl stack for a discussion on xkcd. My assumption was that the std::string length is taken as the buffer length everywhere in the program, which is the only thing that makes sense here.

The protocol requires the payload length to be inserted, and it has to be done as two bytes, high byte first. That is different from the buffer length, which is 3 + payload + padding.

KarenRei wrote:
Mazzula wrote:Perhaps crashing OpenSSL is better than a buffer overflow

"Perhaps"? Is there any remote question that it's the better option? The order of preferability of bugs is of the order:

1) Compiletime error
2) Runtime error
3) Silent error

As stated in my earlier post on the subject, C++/STL takes much of what would be in the third category and moves them to the first two categories. This is a Very Good Thing(TM).

Of course, in this case, the undetected error is extremely serious and I agree that crashing would have been better, but it isn't as hard and fast a rule as you make it out to be. Do you really want your car to stop running because your clock is set to the wrong time?

The fact of the matter is that the code, as written, is basically valid even within C++/STL. That is, there is nothing about C++/STL that requires the abandonment of C/non-STL code, because the additional features are not enforced.

In this case, the buffers are all counted, so there really shouldn't have been a problem creating a counted buffer object in C, with access methods that would have assured there were no buffer overruns—which you get "for free" with std::string.

But I continue to agree that C++ is a good choice for such projects, although there were valid reasons for choosing C in 1998, when OpenSSL was written. My concern here is whether the benefit of re-implementing in C++ is worth the cost, and the risks associated with any major change.

Of course there is no mandate to use OpenSSL. Webmasters are free to use an alternative that is written in C++. Likely the best answer is to let the market decide.

KarenRei wrote:
Mazzula wrote:The increase in overhead doesn't come from the buffer checking, but from maintaining the std:string structure and accessing the bytes of that string using array operations rather than operations like *bp++ in the original code.

As stated, in any *reasonable* implementation they would have just had a structure and assigned structurename.bp = ....; instead of assigning it by pointer dererence (or copying into a string), and it would have been even faster.

I believe that is the way it used to be done in the old days, for performance, but in this case I must disagree with you, the structure approach would be improper as a coding practice. The semantics of a structure don't match the concept of "sequence of bytes", which is what the buffer is supposed to represent.

But they could have assigned to buffer[0], and initially assigned bp to be buffer + 1. That would have avoided the postincrement (although I am not sure that the postincrement actually takes any time, given the tricks processors can do nowadays with parallelism).

Where would you put the "padding" component in your structure? It doesn't appear in a consistent offset within the buffer as sent on the wire.

KarenRei wrote:Perhaps they did that because they experienced trouble because C has such crappy support for data alignment (*cough* std::aligned_storage *cough*)? Also, as stated, C++ lets you do the exact same potentially dangerous operations as the un-bounds-checked, potentially-null-destroying *bp++ example above. But you have to do your dangerous behavior *explicitly*, preferably by extending std::string, less preferably by const casting c_str().

"aligned_storage" is a nice feature of the language, but you would be misusing it here. The code wouldn't be portable across all possible correct compilers. This is apart from the fact that we are not trying to create a structure, we are trying to create a string of bytes

The problem with using "aligned_storage" that way arises because the compiler is free to align more strictly than the alignment you give, providing extra padding that you don't expect. So the aligned_storage approach wouldn't be portable. For example, on a Motorola 68000 processor, it is quite possible that aligned_storage<2,1> will actually be aligned on the next even byte boundary, so that assignments of aligned_storage<2,1> values can be optimized to a single instruction. The purpose of "aligned_storage" is to specify a minimum alignment constraint.

C bit fields don't really work either, because different compilers are not required to number bits within storage units consistently. I seem to recall that on the Motorola 68000 series processors they went in kind of a wacky sequence, because it was big-endian with respect to words but little-endian with respect bits within a byte. (Big endian machines are strange, in general.)

So I think your original code was correct in that respect. The data structure here is supposed to represent a sequence of bytes to be sent on the wire. We are trying to figure out the sequence. An array of char (or of unsigned char) represents that very nicely (provided that the range of char is at least an 8-bit range, and both C and C++ require that as a minimum).

Of course, there is nothing stopping you from writing classes in C++ that would do the alignment you are going for. But the underlying storage would still likely be an array of unsigned char. That would be acceptable.

KarenRei wrote:
Mazzula wrote:The loops are also likely to take much longer, because the size of the payload is likely to be small

Not if you take a look at the actual data structure, and factor in all of the time to make the padding and send the message (or to receive it in the first place).

I suspect the encryption cost is likely the largest cost. One of the advantages of C++, however, is that you don't have to abandon the speed of C for those few inner loops that tend to make all the difference. I would agree that it is far better to have 95% of the code in a safer paradigm, allowing very strict and close attention to any of that 5% that was written using a less inherently safe paradigm for the sake of efficiency.

The Apache web server itself is also written (mostly) in C. Would you consider this a good argument for switching to IIS, which was (reportedly, I don't have access to the source) written in C++?

User avatar
ahammel
My Little Cabbage
Posts: 2135
Joined: Mon Jan 30, 2012 12:46 am UTC
Location: Vancouver BC
Contact:

Re: 1353: "Heartbleed"

Postby ahammel » Fri Apr 11, 2014 2:29 pm UTC

Mazzula wrote:Of course, in this case, the undetected error is extremely serious and I agree that crashing would have been better, but it isn't as hard and fast a rule as you make it out to be. Do you really want your car to stop running because your clock is set to the wrong time?
No, but I have a hard time imagining a situation where a crash isn't better than a buffer overwrite. Refusing to compile code that might result in buffer overwrites is even better.
He/Him/His/Alex
God damn these electric sex pants!

User avatar
addams
Posts: 10268
Joined: Sun Sep 12, 2010 4:44 am UTC
Location: Oregon Coast: 97444

Re: 1353: "Heartbleed"

Postby addams » Fri Apr 11, 2014 2:37 pm UTC

Is this like listening to MD's discuss Surgery vs Medical Management?

Manage if you can.

If that does not do it;
Tear it apart and fix it.

Try not to kill it in the process?
If you kill it, You have Back-Up.

Your profession is difficult and important.
I hope you have the internet backed up.
Life is, just, an exchange of electrons; It is up to us to give it meaning.

We are all in The Gutter.
Some of us see The Gutter.
Some of us see The Stars.
by mr. Oscar Wilde.

Those that want to Know; Know.
Those that do not Know; Don't tell them.
They do terrible things to people that Tell Them.

ericgrau
Posts: 92
Joined: Sat Dec 13, 2008 7:14 pm UTC

Re: 1353: "Heartbleed"

Postby ericgrau » Fri Apr 11, 2014 2:41 pm UTC

This is why you don't use C or similar languages for most applications. And with text data there is no performance excuse.

I'm quite surprised that such irresponsible coding is still going on at all. After 30 years we should know better. Or at least have languages or libraries so lazy programmmers can default to those.

A game I've been playing recently has been having memory leaks. They need performance so I fully expect them to use C, but I still find them irresponsible for being so careless in this day and age. Especially since they never fixed the memory leaks and don't seem to care.

I don't really take "bad programmers can screwup anything" as an excuse either. The time saved on debugging is worth using the appropriate language. And likewise for keeping code organized with well structured functions to handle data. I blame both the language and the coders, not one or the other.

User avatar
ahammel
My Little Cabbage
Posts: 2135
Joined: Mon Jan 30, 2012 12:46 am UTC
Location: Vancouver BC
Contact:

Re: 1353: "Heartbleed"

Postby ahammel » Fri Apr 11, 2014 7:30 pm UTC

ahammel wrote:<tinfoil hat on>

So, what's known about Heartbleed's provenance? By which I mean, how do we know the NSA didn't plant it intentionally?

<tinfoil hat off>
There's news on that front.

Heartbleed was checked in by one Robin Segglemann, a German security researcher who is presumably not an NSA stooge. Interestingly, he claims that the patch was in fact reviewed before it made it into production, and that the reviewer missed the bug as well.

So there you have it: the compiler, not the reviewer, should be taking care of memory safety.
He/Him/His/Alex
God damn these electric sex pants!


Return to “Individual XKCD Comic Threads”

Who is online

Users browsing this forum: Majestic-12 [Bot] and 49 guests