Posted Jun 10th, 2009 in C/C++, Security |
No Comments »
Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email
Even an expert programmer cannot claim of writing bug free code. Bugs are here to stay during a software development life cycle. But what every programmer needs to do is to test his code before the code goes into the main repository. So, programmers have different techniques to do this. Running Test cases, getting code reviewed, code walk through, running manual tests, ad-hoc tests are various things performed by people and Bang!!! code goes into the repository. Let’s consider the following psuedo-code:
char* someString = (char*) malloc(100);
if(someString != NULL){
// do something
}else{
// handle error condition
}
Continue Reading
Written By
Amit Goel|
Tags: bugs, C, crash, debugging, Efficiency, Languages, programming, safety and security, Security, testing
Posted May 12th, 2009 in General |
No Comments »
Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email
Many people would agree with me when I say that the hardest part of fixing a bug is to find where it is originating from. It has happened to me quite a number of times that a certain module exhibits a particularly wild behaviour making me go mad on its developer but as I dug deeper, the cuplrit turned out to be someone who had not even heard of that module.
Today I bring to you such an example of a nice bug, which I’ll term as (like many others):
OpenOffice.org Cannot Print On Tuesdays Bug
OpenOffice.org (also known as OOo or just Open Office) is a free and widely used MS Office alternative and a lot of its users reported in recently that it would just stop printing on every tuesday. Come Wednesday, everything would be just fine and dandy, but for just less than a week till Tuesday showed its face again. Now, before I continue to unravel the mystery behind this unique bug, let me outrightly clear it out to my Indian friends that OOo is not devotee of Lord Hanuman, deciding to go on a fast on Tuedays to offer its obesceinces.
Well, after days of discussions, and people blaming everything from OOo to cups (the printer daemon), printer drivers, or the printer itself, one enterprising soul decided to investigate and found out that if he changed the “CreationDate” tag in the generated postscript file to replace the “Tue” of Tuesday with something else, the file happily printed.
Read the rest of this entry »
Written By
Shantanu Goel|
Tags: 500 mile email, bugs, debugging, OOo, Open Office Bug, Open Office tuesday print bug, OpenOffice.org
Posted May 5th, 2009 in C/C++, General |
8 Comments »
Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email
First of all, I apologize for the decreased frequency of updates. We have been quite busy with our offline lives and primary livelihoods lately keeping us away from posting much. But we intend to not let it remain like this for much longer. I’m posting a short article today about something that almost everyone of us has had to do at some point of time, i.e., to find the offset (or relative position in bytes) of an element in a structure. Let’s take the following structure as an example:
struct
{
char a;
int b;
char c;
}example;
Now, if I were to ask you to find out the element b’s offset in the above structure, you won’t probably be able to answer with complete confidence unless I tell you the compiler you are working with and whether packing has been turned on or not. The easiest way to find it out is to use a small snippet of code to do it for us and that always works. e.g.
struct example s1;
unsigned int offset;
offset = (unsigned int)&s1.b - (unsigned int)&s1;
The above snippet will work, but not always (Hint). Many people use a much simplified form, which does not involve any pointer arithmetic:
unsigned int offset;
offset = (unsigned int)(&(((example *)(0))->b));
The above code is much simpler/faster but again, it might not be portable. So, what is the best method to do this portably. It’s quite simple really, just use the “offsetof” macro provided by any ANSI-C compliant compiler. It is present in stddef.h and can be used in the following way:
size_t offset;
offset = offsetof(example, b);
If you noticed, offsetof() also presents another advantage to you like the 2nd method, i.e., it does not require an extra structure to be defined. In fact, this macro is defined in forms similar to our method 2 but the benefit is that it ensures portability for your code.
Written By
Shantanu Goel|
Tags: C, element offset, element offset in structure, offsetof, Portability, structure in c, structure offset
Posted Mar 23rd, 2009 in C/C++, General, Security |
3 Comments »
Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email
Every programmer, no matter how great he is, makes mistakes sometime or the other while coding. Although every compiler tries its best to put across every possible error during compilation,many mistakes skip the wrath of compiler. Some are seemingly very innocent and very tough to be caught even during code review, sometimes even get through the cycle of testing. The real face of these mistakes show up always on the customer side by crashing the system.
Consider the following example:
int multiply(int m, int n)
{
int result = 0;
result = m * n;
return result;
}
void func()
{
int m = 32767;
int n = 32767;
int result = 0;
result = multiply( m, n );
}
Read the rest of this entry
Written By
Amit Goel|
Tags: buffer overflow, C, Flex Lint, LINT, MISRA, PC Lint, Safety, warnings
Posted Mar 10th, 2009 in C/C++, Portability |
9 Comments »
Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email
Writing portable code is very important but it is one of the aspects that most people neglect until it is too late to realize its importance. Till few years ago, most people writing code for personal computers were not worried about the data sizes on their machines. They didn’t even think whether the machines, on which their code would be running, would be 32 bit or 64 bit. But the recent advent of 64 bit machines in normal every-day usage has them running helter-skelter to get their programs into shape. Many of these programs would like to run the same code base on 32 bit as well as 64 bit machines. There are many ways to do it. A few allow us to use data types that would work as expected in both machines while in other ways, they explicitly check for the architecture of the machine and carry out their tasks accordingly. Before I give you the code to run this check, let’s see a bit of theory behind it.
First, let’s be clear that the discussion we will be doing now will not always give you the “hardware architecture” of a machine. Rather it’ll allow you to know the “Programming Model” (or Data Model)that the OS or your compiler enforces on you. What I mean is that if you run a 32 bit OS on top of your latest 64 bit processor based system, it will still mean a 32 bit programming model for you. Infact, if you were to compile your programs using the ancient Turbo C compiler, you’d be in for an even bigger surprise
. That said, ultimately the programming model is what you’d be interested in knowing to make sure that your program can compile and run accurately on that particular system. The most common programming models in use are as below:
| Datatype |
LP64 |
ILP64 |
SILP64 |
LLP64 |
ILP32 |
LP32 |
| char |
8 |
8 |
8 |
8 |
8 |
8 |
| short |
16 |
16 |
64 |
16 |
16 |
16 |
| int |
32 |
64 |
64 |
32 |
32 |
16 |
| long |
64 |
64 |
64 |
32 |
32 |
32 |
| long long |
64 |
64 |
64 |
64 |
64 |
64 |
| pointer |
64 |
64 |
64 |
64 |
32 |
32 |
Read the rest of this entry »
Written By
Shantanu Goel|
Tags: 32–bit, 64–bit, Architectue, C, check machine 64 bit, CPP, Data Model, data models, data sizes, data types, function pointers, Hardware Architecture, ILP32, ILP64, LLP64, LP32, LP64, pointers, Portable code, Programming Model, SILP64, writing portable code
Posted Feb 24th, 2009 in C/C++, General, Optimization |
12 Comments »
Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email
Last time we explained the real meaning of const keyword, this time it’s going to be Volatile, the other sibling of this most misunderstood duo in C history. Let’s separate out the myths and the facts first and then we will discuss the how’s and why’s of it.
FACTS:
- A volatile qualifier is important to be used for auto-storage variables within setjmp and longjmp.
- A volatile qualifier must be used when reading the contents of a memory location whose value can change unknown to the current program.
- A volatile qualifier must be used for shared data modified in signal handlers or interrupt service routines.
MYTHS:
- All shared data in multi-threaded programs must be declared volatile.
Now, we’ll see how we made the above classfication.
Read the rest of this entry »
Written By
Shantanu Goel|
Tags: -O2, atomicity, C, const, CPP, gcc, keyword, memory barriers, memory fences, non-atomic access, Optimization, order of access, volatile, volatile keyword
Posted Feb 10th, 2009 in C/C++, General, Security |
7 Comments »
Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email
Everyone must have used rand() sometime or the other while writing C code. The problem with rand() in most of the platforms is that it is easy to predict the output. Being based on unsigned int, it is just a simple function using a seed which is always the last randomly generated some number. This seed is not very tough to guess for an advanced hacker. once this seed is guessed,, any password or information based on random number generation can be easilt cracked and maligned.
following code is abridged code of rand() function implementation referenced from the book The C programming Language written by Brian Kernighan and Dennis Ritchie
unsigned long int next = 1;
int rand(void)
{
next = next * 1103515245 + 12345;
return (unsigned int)(next / 65536) % 32768;
}
This type of function is generally called linear congruential function. As you can notice yourself, that these type of linear congruential functions are very much predictable and are not recommended for security sensitive applications. If you look at the above given code, it is obvious that if the underlying environment does not change, then the random number generation can easily be guessed as it will generate same random number on running the application again and again.
Continue Reading the rest of the entry
Written By
Amit Goel|
Tags: C, Concepts, CryptGenRandom, Cryptography, Efficiency, rand, Random Numbers, Security, security holes
Posted Feb 4th, 2009 in C/C++ |
17 Comments »
Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email
There are a few very basic things in C that are widely misunderstood by programmers of all caders. This is not because these things are very complex, but because books and teachers do not give them their due importance while teaching beginners and the misconceptions stick even years later. A few of these are like the keywords “volatile” (covered in next post) and “const”.
Look at the following piece of code:
#include <stdio .h>
int main()
{
const int a = 1;
a = 2;
printf("%d\n", a);
return 0;
}</stdio>
You’d be quick to point out (correctly) that the above code wouldn’t compile. It would fail with an error on the lines of “assignment of read-only variable a” because a is now a “constant” because of the const type qualifier attached to it. And now comes the issue. Many start assuming (or might even be explicitly taught) that the value of a cannot be changed now. Did you think so too? Well, you thought wrong. Look at the following code:
Read the rest of this entry »
Written By
Shantanu Goel|
Tags: C, compiler, const, keyword, Optimization, read only, volatile
Posted Jan 27th, 2009 in C/C++, Optimization |
5 Comments »
Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email
One of the ways to optimize your code for speed is to unroll the loops you have in your program. If you don’t know what loop unrolling is, then see the following simple example, where we are trying to copy a 5 element long string:
A Simple Loop:
for (i = 0 ; i < 5; ++i)
{
*j++ = *k++;
}
The same loop unrolled:
*j++ = *k++;
*j++ = *k++;
*j++ = *k++;
*j++ = *k++;
*j++ = *k++;
Now, the unrolled version is definitely going to be faster because of the following reasons:
1. There are no branches any more. In a loop, the compiler has to insert branches to jump back to the for statement.
2. There are no condition checks. In a loop, the value of i is checked every time to see what to do next.
3. A third rather hidden, but really important, advantage is that unrolled code can be pipelined efficiently by the processor hence resulting in faster execution.
The above code in itself might not show you any perceivable difference in execution time, but it does become crucial when the loops are of much higher magnitude and especially in embedded/real time scenarios.
Now, the loop unrolling can be done by the compiler or manually by the coder. In this part, we will see how to facilitate compiler to carry out loop unrolling efficiently. Read the rest of this entry »
Written By
Shantanu Goel|
Tags: C, iterations, Loop Unrolling, Loops, Optimization, Optimization techniques, Pipelining
Posted Jan 13th, 2009 in C/C++, Java, Security |
No Comments »
Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email
Except for few good C programmers, others generally tend to ignore variable initialization or I should rather say “proper variable initialization”. Generally seen, the variable declaration itself is not done with a good thinking. Improper local variable initialization might not be good for the working of the program but improper global variable initialization might get your software or system hacked.
The uninitialized variable or a wrongly initialized variable might lead a program to change its normal course of flow from the intended one. For example: If a variable “index” is being used for array navigation and is left uninitialized, it might contain a garbage value which can lead to array index out of bounds error. or if the variable “index” is initialized wrongly to –1, it might lead to serious flaw in code flow. Even if an integer value is being initialized to ‘0’, it might lead to a security check bypass because for some programs, even a ‘0’ is considered a valid value.
Lets take an example of a code piece.
int isMachineRunning = GetMachineStatus();
int state = GetUserState(isMachineRunning);
int userid = 0;
if (state) {
userid = ExtractUserID(state);
}
/* do stuff */
if (uid == 0) {
DoAdminThings();
}
Continue Reading >>
Written By
Amit Goel|
Tags: buffer overflow, C, Efficiency, initialization, Languages, Security, variable declaration, variables