...
In this example, two functions are called one after another. The first function, func1(...)*is passed an integer entered by a user. That integer is stored in variable: *i for the duration of the function. The second function func2()*declares a local integer variable: *j. j is not initialized before being checked against a constant value, CONDITION_CHECK. Since jwas not initialized, it assumes whatever value is at that location in the stack, in this case the value of i from func1(). Thus is the user entered 42, the condition the statement if (j == CONDITION_CHECK) succeeds.
Code Block |
---|
#define CONDITION_CHECK 42
void func1 (int arg) { int i = arg; }
void func2 (void) {
int j;
if (j == CONDITION_CHECK) printf("Condition passed!!\n");
else printf("ERROR: Condition failed\n");
}
int main(int argc, char **argv) {
func1(atoi(argv[1]));
func2();
}
|
Compliant Solution 1
The local, automatic variable j should be initialized to a default value.
Code Block |
---|
#define CONDITION_CHECK 42
void func1 (int arg) { int i = arg; }
void func2 (void) {
int j = 0; /* initialize j to 0 */
if (j == CONDITION_CHECK) printf("Condition passed!!\n");
else printf("ERROR: Condition failed\n");
}
int main(int argc, char **argv) {
func1(atoi(argv[1]));
func2();
}
|
Non-compliant Code Example 2
In this example, user input is copied to a buffer, buf, which has been filled with '\0' characters. The first function, logit(...) copies the user input to another buffer, buffer, and prints it. Next, the runit(...) routine is called. This routine declares an array of 50 characters, buf, and a character pointer, ptr. However, since ptr is not initialized it points to whatever data is on the stack. In this case, the 51st to 55th characters of user controlled data copied in the logit(...) function. When the contents of ptr are copied to buf using an unbounded strcpy(...), ptr is dereferenced and the data in that location is copied to buf. If that data at that location is longer than 50 bytes without a null byte, a buffer overflow will occur.
Code Block |
---|
#define BUF_SIZE 150
void runit(void) {
char buf[50];
char *ptr;
memset(buf,0,50);
strcpy(buf,ptr);
}
void logit(char *str, int size) {
char buffer[BUF_SIZE];
int i;
for (i=0; i < BUF_SIZE; ++i) buffer[i] = '\0';
strncpy(buffer, str, size);
printf("The message: %s\nhas been logged\n",buffer);
}
int main(int argc, char *argv[]) {
char buf[BUF_SIZE];
int i;
for (i=0; i < BUF_SIZE; ++i) buf[i] = '\0';
strncpy(buf, argv[1], BUF_SIZE-1);
logit(buf,strlen(buf));
runit();
}
|
Compliant Solution 2
The local variable ptr should be initialized to a default value.
Code Block |
---|
#define BUF_SIZE 150
void runit(void) {
char buf[50];
char *ptr = 0; /* initialize ptr to 0 */
memset(buf,0,50);
strcpy(buf,ptr);
}
void logit(char *str, int size) {
char buffer[BUF_SIZE];
int i;
for (i=0; i < BUF_SIZE; ++i) buffer[i] = '\0';
strncpy(buffer, str, size);
printf("The message: %s\nhas been logged\n",buffer);
}
int main(int argc, char *argv[]) {
char buf[BUF_SIZE];
int i;
for (i=0; i < BUF_SIZE; ++i) buf[i] = '\0';
strncpy(buf, argv[1], BUF_SIZE-1);
logit(buf,strlen(buf));
runit();
}
|