Security-Oriented C Tutorial 0x05 - Control Structures Part II: Loops
Welcome back to control structures, part two featuring the three types of loops. Here we go!
Loops are convenient little things and as their name suggests, they allow us to do the same repetitive tasks with minimum effort (and also because computers are our slaves and do all of the hard work!). If you ever find yourself in a situation where you are repeating yourself, use a loop! Remember: Don't repeat yourself! Say it with me, "Don't repeat yourself!" Wait a second...
Before we begin, I want to ask you readers a classic question:
If you're building a 100-foot fence, with fence posts spaced 10 feet apart, how many fence posts do you need?
The question will be answered near the end.
We will cover the standard while loop first. When typing up a while loop, simply begin with the "while" keyword followed by the condition within parenthesis followed by the body of statements inside a pair of curly braces. Take a look at the following code and its syntax.
The code we have above declares an integer variable called "i" initialized with 0. The condition in the while loop compares the variable i and sees if it is less than 10 and "while the condition is true", the body will be executed. Every time the body is executed, it will print "Don't repeat yourself!" and then increment the i variable.
Note: The operator "++" increments the variable to which it is attached.
Style Note: Usually, the variable "i" is used as a counter or an index.
How many times do you think the will the loop execute?
A successful compilation and run! How many times did it print? Well, by piping our program's output into the "wc" tool to count lines, it says 10! Is this correct? Seems like it! Need to count to verify? Knock yourself out!
The for loop is almost the same thing however, it's a more compressed version of the while loop. Take a loop at the example below and familiarize yourself with the syntax.
If you think this looks like a lot, it isn't, really. You just need to get used to the two little extra initializing and increment part which are separated by semicolons. Note that the increment part does not have the semicolon after it. Can you have more than just one variable? Yes! All you need to do is add it into the appropriate part separating the two variables with a comma.
We should get the same result as the first part if we run this.
Again, printing it and then piping it into wc shows 10 lines, exactly as it should.
The do while loop is also pretty much the same as the while loop. In this case, the content of the loop is executed at least once before checking the condition. If the condition is satisfied, it will execute the loop again. This is especially handy if you wish to execute something at least once before verifying that it should be looped again as required.
The syntax this time looks quite different. You must start off with the "do" keyword followed by a pair of curly braces to create the block where the body is placed, then typing the "while" keyword and a semicolon after the closing curly brace. Remember to put that semicolon!
The condition has changed to "i != 0" which means "i does not equal to zero". How many times will it print this time?
Note: The "!=" comparison operator means "not equal to". We will further discuss comparison operators in another tutorial.
As expected. Since this is a do while loop, it will run the body at least once before checking the condition. When we reached the condition, it failed to satisfy and therefore exited the loop having only printed once.
So, back to that question I gave you at the beginning... Have you got an answer yet? Obviously it's 10, right? Pfft, of course it's 10, how can anything be easier than that? Okay, the answer isn't 10, sorry. If you said 11, then you'd be right! Try draw it out on paper and prove me wrong. This occurs when you've confused the items and spaces. This is called a fencepost error or an off-by-one error.
Once more, off-by-one errors can cause some serious havoc, allowing for the classic buffer overflow to deliver arbitrary code execution (involuntary execution of code), memory corruption and even information leakage. But alas, we have not touched on buffers yet and they sure do seem very interesting! Don't worry, we'll get there... eventually.
A real-world example of an off-by-one error in OpenSSH allowed users to gain unauthorized privileges due to a tiny, tiny bug in an if statement condition! Want to know more? Hop on over to the National Vulnerability Database's (NVD) summary on CVE-2002-0083.
Okay, that's it for loops and control structures. Be sure to practise and play around with what you have currently learned! If you're unsure of anything, ask around or you'll fall behind!