...
Code Block |
---|
|
#include <stdio.h>
int do_auth(void) {
char *username;
char *password;
/* Get username and password from user, return -1 if invalid */
}
void report_error(const char *msg) {
const char *error_log;
char buffer[24];
sprintf(buffer, "Error: %s", error_log);
printf("%s\n", buffer);
}
int main(void) {
if (-1 == do_auth() == -1) {
report_error("Unable to login");
}
return 0;
}
|
...
Code Block |
---|
|
#include <stdio.h>
void report_error(const char *msg) {
printf("Error: %s\n", msg);
}
|
...
Code Block |
---|
|
void f(const char *mbs) {
size_t len;
mbstate_t state;
len #include <wchar.h> /* For mbrlen(), mbstate_t and size_t */
#include <string.h> /* For strlen() */
void func(const char *mbs) {
size_t len;
mbstate_t state;
len = mbrlen(mbs, strlen(mbs), &state);
/* ... */
}
|
...
Before being passed to a multibyte conversion function, an mbstate_t
object must be either initialized to the initial conversion state or set to a value that corresponds to the most recent shift state by a prior call to a multibyte conversion function. The compliant solution sets the mbstate_t
object to the initial conversion state by setting it to all zeros..
Code Block |
---|
|
#include <wchar.h> /* For mbrlen(), mbstate_t and size_t */
#include <string.h> /* For strlen() */
void func |
Code Block |
---|
|
void f(const char *mbs) {
size_t len;
mbstate_t state;
memset(&state, 0, sizeof(state));
len = mbrlen(mbs, strlen(mbs), &state);
/* ... */
}
|
...
In this noncompliant code example, the process ID, time of day, and uninitialized memory junk
is used to seed a random number generator. This behavior is characteristic of some distributions derived from Debian that use uninitialized memory as a source of entropy because the value stored in junk
is indeterminate. However, because accessing indeterminate values is undefined behavior, compilers may optimize out the uninitialized variable access completely, leaving only the time and process ID and resulting in a loss of desired entropy.
Code Block |
---|
bgColor | #FFCCCC |
---|
lang | c |
---|
| #FFCCCC |
---|
lang | c |
---|
|
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
void func(void) {
struct timeval tv;
unsigned long junk;
gettimeofday(&tv, NULL);
srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk);
/* ... */
} |
In security protocols that rely on unpredictability, such as RSA encryption, a loss in entropy results in a less secure system [Wang 2012].
...
Code Block |
---|
|
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
void func(void) {
double cpu_time;
struct timeval tv;
unsigned long junk;
cpu_time = ((double) clock()) / CLOCKS_PER_SEC;
gettimeofday(&tv, NULL);
srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk);
} |
Exceptions
EXP33-EX1: Reading uninitialized memory of type unsigned char
does not trigger undefined behavior. The unsigned char
type is defined to not have a trap representation (see the C Standard, subclause 6.2.6.1, paragraph 3), which allows for moving bytes without knowing if they are initialized. However, on some architectures, such as the Intel Itanium, registers have a bit to indicate whether or not they have been initialized. The C Standard, subclause 6.3.2.1, paragraph 2, allows such implementations to cause a trap for an object that never had its address taken and is stored in a register if such an object is referred to in any way.
...