...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <assert.h>
#include <stddef.h>
struct test {
int a;
char b;
char padding_1, padding_2, padding_3;
int c;
};
/* Safely copy bytes to user space */
extern int copy_to_user(void *dest, void *src, size_t size);
void do_stuff(void *usr_buf) {
/* Ensure c is the next byte after the last padding byte */
static_assert(offsetof(struct test, c) ==
offsetof(struct test, padding_3) + 1,
"Structure contains intermediate padding");
/* Ensure there is no trailing padding */
static_assert(sizeof(struct test) ==
offsetof(struct test, c) + sizeof(int),
"Structure contains trailing padding");
struct test arg = {.a = 1, .b = 2, .c = 3};
arg.padding_1 = 0;
arg.padding_2 = 0;
arg.padding_3 = 0;
copy_to_user(usr_buf, &arg, sizeof(arg));
}
|
The C11 C Standard static_assert() macro accepts a constant expression and an error message. The expression is evaluated at compile time, and, if false, the compilation is terminated and the error message is output. See DCL03-C. Use a static assertion to test the value of a constant expression for more details.For example, on an x86-32 machine, the The explicit insertion of the padding bytes into the struct should ensure that no additional padding bytes are added by the compiler, and consequently both static_assert expressions should be true. However, it is still necessary to assert validate these details assumptions to ensure the safety of the solution for a particular implementation.
Compliant Solution (Structure Packing—GCC)
...
Compliant Solution (Structure Packing—Microsoft Visual Studio)
Microsoft Visual Studio Studio supports #pragma pack() instead of the __packed__ attribute to attempt to suppress padding bytes [MSDN]. The compiler will add padding bytes for memory alignment depending on the current packing mode, but still honors alignment specified by __declspec(align()). In this compliant solution, the packing mode is set to one in an attempt to ensure all fields are given adjacent offsets.
...
The pack pragma takes effect at the first struct declaration after the pragma is seen. The alignment of a member will be on a boundary that is a multiple of one byte unless otherwise specified.
Risk Assessment
Padding bytes might contain sensitive data because the C Standard allows any padding bytes can take unspecified values. A pointer to such a structure could be passed to other functions, causing information leakage.
...