...
Wiki Markup |
---|
The following example is based on a flaw discovered in the OpenBsd operating system \[[ref]\]. An integer, {{skip_member}}, is added as an offset to a pointer of type {{struct big}} and the sum is then used as a destination address in a call to {{memset()}}. However, when {{skip_member }} is added to the {{struct big}} pointer, it is automatically scaled by the size of {{struct big}}, which is 32 bytes (assuming 4 byte integers, 8 byte long long integers, and no structure padding). This results in the call to {{memset()}} writing to unintended memory. |
Code Block | ||
---|---|---|
| ||
struct big { unsigned long long ull_1; /* typically 8 bytes */ unsigned long long ull_2; /* typically 8 bytes */ unsigned long long ull_3; /* typically 8 bytes */ int si_4; /* typically 4 bytes */ int si_5; /* typically 4 bytes */ }; /* ... */ size_t skip_member = sizeof(unsigned long long); struct big *s = malloc(sizeof(struct big)); if (!s) { /* Handle malloc() error */ } memset(s + skip_member, 0, sizeof(struct big) - skip_member); /* ... */ free(s); |
Compliant Solution 2
...
Code Block | ||
---|---|---|
| ||
struct big { unsigned long long ull_1; /* typically 8 bytes */ unsigned long long ull_2; /* typically 8 bytes */ unsigned long long ull_3; /* typically 8 bytes */ int si_4; /* typically 4 bytes */ int si_5; /* typically 4 bytes */ }; /* ... */ size_t skip_member = sizeof(unsigned long long); struct big *s = malloc(sizeof(struct big)); if (!s) { /* Handle malloc() error */ } memset((char *)s + skip_member, 0, sizeof(struct big) - skip_member); /* ... */ free(s); |
Risk Assessment
...