...
It is annotated with the following (footnote 51):
Thus, for example, structure assignment need not copy any padding bits. (footnote 51)
As a result of being uninitialized, padding bytes could have random data (sensitive data). This structure could be passed to functions that do not have privilege. For example, there have been instances in the Linux kernel when uninitialized stack bytes were leaked to unprivileged users as a result of copying structures to user space.
...
In this noncompliant code example, the padding bytes after char b may not be initialized.:
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stddef.h>
struct test{
int a;
char b;
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) {
struct test arg = {.a=1,.b=2,.c=3};
/* ... perform operations on arg ... */
/* copy arg to user space */
copy_to_user(usr_buf, &arg, sizeof(arg));
/* ... */
}
|
...
The following solution assumes it will be run on an IA-32 architecture.:
| Code Block | ||||
|---|---|---|---|---|
| ||||
#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) {
/* make sure c is the next byte after the last padding byte */
static_assert(offsetof(struct test, c) == \
offsetof(struct test, padding_3) + 1, \
"Error: not compiling for IA-32");
struct test arg = {.a=1,.b=2,.c=3};
arg.padding_1 = 0;
arg.padding_2 = 0;
arg.padding_3 = 0;
/* ... perform operations on arg ... */
/* copy arg to user space */
copy_to_user(usr_buf, &arg, sizeof(arg));
/* ... */
}
|
...