...
Code Block | ||
---|---|---|
| ||
char msg[100]; /* ... */ void report_error(const char *error_msg) { char msg[80]; /* ... */ /* Assume error_msg isn't too long */ strcpy(msg, error_msg); return; } int main(void) { /* ... */ /* Ensure error_msg isn't too long */ if (strlen( error_msg) >= sizeof( msg)) { error_msg[sizeof(msg) - 1] = '\0'; } report_error( error_msg); /* oops! */ /* ... */ } |
Furthermore, if the length of the null-terminated byte string referenced by error_msg
is greater than 79 characters in length, a buffer overflow will occur on the stack, which may be exploitable. This occurs in spite of the outer function's attempt to prevent buffer overflow!
...
Code Block | ||
---|---|---|
| ||
char system_msg[100]; /* ... */ void report_error(const char *error_msg) { char default_msg[80]; /* ... */ /* Assume error_msg isn't too long */ strcpy(system_msg, error_msg); return; } int main(void) { /* ... */ /* Ensure error_msg isn't too long */ if (strlen( error_msg) >= sizeof( system_msg)) { error_msg[sizeof(msg) - 1] = '\0'; } report_error( error_msg); /* good */ /* ... */ } |
When the block is small, the danger of reusing variable names is mitigated by the visibility of the immediate declaration. Even in this case, however, variable name reuse is not desirable.
...