[From the last episode: We saw how pointersA variable that, instead of holding data, holds an address where data is located. That is, it "points" to the data instead of being the data. are an important kind of variable, representing data whose location we can’t predict in advance.]
We saw last time that pointers are used to store the addresses of data stored in memory space that’s allocated while the program is running. Why might that create some vulnerability? We’ll look at a couple of possible programming errors that could cause problems.
Well, let’s start with what might be the biggest mistake new programmers make when writing in old, venerable languages like CA programming language that gives low-level control of all the details.. (Certainly it’s a mistake I made…) The way pointers normally work is that the language gives you a way to say, in effect, “Please get me the data located at this location.” Or, “Please write this data to that addressWhen referring to memory, a binary number that shows where, within some memory block, the data you want is located. If you want to read or change that data, you have to give the address so that the right data is read or changed..” Especially with the latter one, the big mistake is that you do that before you’ve initialized the pointer. In other words, the pointer doesn’t have a real address in it yet – it probably has the value of 0.
It’s hard to know what’s at any given place in memory, but it’s pretty much guaranteed that address 0 doesn’t belong in the region of memory allocated to your program. It’s probably system-related stuff; regardless, if you change the data at location 0, you could mess something else up in a serious way.
OK, so that’s a little thing that an experienced programmer probably wouldn’t do. Here’s a bigger thing that’s more common: you can do math with pointers.
Math with Pointers
Let’s say that you’re a programmer and you’ve got a place that stores a list of things. Let’s say those things all have a size of one byteA byte is 8 bits.. And let’s say you’ve saved space for eight of them. The pointer gives you the address of the first one; you can then find the others by adding to the value of the pointer. Because, of course, a pointer simply contains a number; the computer doesn’t care. It’s we that know that the number is supposed to represent an address.
So if we want the first byte of the list, we simply go to the address in the pointer. If we want the eighth item in the list, then we add 7 to the pointer to get that address. This works, and it’s a very useful tool.
Now let’s imagine that we make a mistake with our pointer. Or perhaps we neglect to check the value of the pointer to make sure that it makes sense for our program. Let’s say that, by accident, instead of adding 7 to the pointer, we add 700. That’s going to be an address for something we weren’t expecting. It might be some of our own data we’re going to mess up. But, even worse, we might mess up the data for some other completely unrelated program.
The following drawing shows a (made-up) memory situation. It maps where three programs reside in memory, as well as the other stuff at the top (starting with address 0). If we add 700 to one of our addresses, then, depending on where the original pointer points, we might actually be accessing the data for another program. We might mess up that data by overwriting something, or we might just be looking at some data we have no business seeing.
Bad Behavior, Leaked Secrets
Obviously, this will make our own program work poorly. But we’ve very likely also messed up some other program’s data – or even the program itself (what if you wrote over the top of the program instructions for that other program?). In a similar fashion, you could subtract a number from the pointer and end up in the space for the other program.
You might ask, “How could a program with that problem ever be released without catching the problem first? Didn’t anybody test it??” And the answer would likely be, for the most part, that yes, the program was tested (let’s hope so!), but there was this one bit of code that, in effect, says, “If this one really weird, oddball situation occurs, then go do this special stuff.” That weird, oddball situation may never show up during the testing, so that little bit of special-stuff code never got tested.
This is but one example. There are assuredly more. So let’s put this into the context of a multi-tenanted cloud serverA computer with a dedicated purpose. Older familiar examples are print servers (a computer that controls local printing) and file servers (a computer used for storing files centrally). More modern examples are web servers (the computers that handle your web requests when you use your browser) or application servers (computers dedicated to handling the computing needs of a specific application). Servers are often powerful, expensive machines since they have to handle a heavy load.. In that case, “your program” may be the code that’s serving your needs; the other programs may be serving other people’s needs – either with the same or different programs. In that case, you may be peeking into someone else’s data. In fact, this is something hackersA misused, but common term for an unauthorized person trying to break into a device or network. Originally, in this context, "hackers" referred to the good guys (or "white hats"), while "crackers" were the bad guys (black hats). might try – going out of bounds to see something they would otherwise not be permitted to see.
The bottom line here is that the single server can handle multiple programs or users, but, as shown here, it’s not really set up to provide iron-clad boundaries that could stop such accidental (or intentional) incursions. That can hurt both securityRefers to whether or not IoT devices or data are protected from unauthorized viewers. and privacyRefers to whether or not information gathered about your usage of IoT devices by authorized people can be made public, or shared with others, without your consent. Different from (although related to) security, which protects such data and devices from access by unauthorized people. Different from privacy, which is more concerned about use of data by authorized people. (not to mention basic functioning).
An Endless Process
Each specific programming error like this may have a number of ways to fix it. And, when it comes to security in particular, software developers may have to go through each specific scenario to make sure things are protected – that’s a lot of work, and, often, things get missed. They may get found later – which is when the program would be updated. It’s things like this (only much more complex) that explain why you’re always getting security updates on your laptop.
But there are some structural developments happening that help to prevent this sort of problem. We’ll look at that next.
Leave a Reply