...
This noncompliant code example temporarily stores data read from a source file into a buffer. The buffer is allocated on the stack as a variable-length array of size bufsize. If bufsize can be controlled by a malicious user, this code can be exploited to cause a denial-of-service attack.
| Code Block | ||||
|---|---|---|---|---|
| ||||
int copy_file(FILE *src, FILE *dst, size_t bufsize) {
char buf[bufsize];
while (fgets(buf, bufsize, src)) {
if (fputs(buf, dst) == EOF) {
/* Handle error */
}
}
return 0;
}
|
...
This compliant solution replaces the variable-length array with a call to malloc(). If malloc() fails, the return value can be checked to prevent the program from terminating abnormally.
| Code Block | ||||
|---|---|---|---|---|
| ||||
int copy_file(FILE *src, FILE *dst, size_t bufsize) {
if (bufsize == 0) {
/* Handle error */
}
char *buf = (char *)malloc(bufsize);
if (!buf) {
return -1;
}
while (fgets(buf, bufsize, src)) {
if (fputs(buf, dst) == EOF) {
/* Handle error */
}
}
/* ... */
free(buf);
return 0;
}
|
...
This noncompliant implementation of the Fibonacci function uses recursion.
| Code Block | ||||
|---|---|---|---|---|
| ||||
unsigned long fib1(unsigned int n) {
if (n == 0) {
return 0;
}
else if (n == 1 || n == 2) {
return 1;
}
else {
return fib1(n-1) + fib1(n-2);
}
}
|
...
This implementation of the Fibonacci functions eliminates the use of recursion.
| Code Block | ||||
|---|---|---|---|---|
| ||||
unsigned long fib2(unsigned int n) {
if (n == 0) {
return 0;
}
else if (n == 1 || n == 2) {
return 1;
}
unsigned long prev = 1;
unsigned long cur = 1;
unsigned int i;
for (i = 3; i <= n; i++) {
unsigned long tmp = cur;
cur = cur + prev;
prev = tmp;
}
return cur;
}
|
...