Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

When passing a pointer to a structure across a trust boundary to a different trusted domain, the programmer must ensure that the padding bytes and bit-field storage unit padding bits of such a structure does do not contain sensitive information.

...

However, compilers are free to implement arg.b = 2 by setting the low byte of a 32-bit register to 2, leaving the high bytes unchanged , and storing all 32 bits of the register into memory. This could implementation could leak the high-order bytes resident in the register to a user.

...

This code ensures that no uninitialized padding bytes are copied to unprivileged users. Note that the The structure copied to user space is now a packed structure and that the copy_to_user() function would need to unpack it to re-create recreate the original padded structure.

...

The 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 See DCL03-C. Use a static assertion to test the value of a constant expression for more details.) . 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 assertions should be true. However, it is necessary to validate these assumptions to ensure that the solution is correct for a particular implementation.

...

GCC allows specifying declaration attributes using the keyword __attribute__((__packed__)). When this attribute is present, the compiler will not add padding bytes for memory alignment unless otherwise required to by the _Alignas alignment specifier, and it will attempt to place fields at adjacent memory offsets when possible.

...

Microsoft Visual Studio  supports #pragma pack() to suppress padding bytes [MSDN]. The compiler adds padding bytes for memory alignment, depending on the current packing mode, but still honors the alignment specified by __declspec(align()). In this compliant solution, the packing mode is set to 1 in an attempt to ensure all fields are given adjacent offsets:

...

This noncompliant code example also runs in kernel space and copies data from struct test to user space. However, padding bits will be used within the structure due to the bit-field member lengths not adding up to the number of bits in an unsigned object. Further, there is an unnamed bit-field which that causes no further bit-fields to be packed into the same storage unit. These padding bits may contain sensitive information, which may then be leaked when the data is copied to user space. For instance, the uninitialized bits may contain a sensitive kernel space pointer value that can be trivially reconstructed by an attacker in user space.

...

However, compilers are free to implement the initialization of arg.a and arg.b by setting the low byte of a 32-bit register to the value specified, leaving the high bytes unchanged , and storing all 32 bits of the register into memory. This could implementation could leak the high-order bytes resident in the register to a user.

...

From this situation, it can be seen that special care must be taken because no solution to the bit-field padding issue will be 100% portable.

 Risk Assessment

Padding units might contain sensitive data because the C Standard allows any padding to take unspecified values. A pointer to such a structure could be passed to other functions, causing information leakage.

...

Numerous vulnerabilities in the Linux Kernel have resulted from violations of this rule. CVE-2010-4083 describes a vulnerability in which the semctl() system call allows unprivileged users to read uninitialized kernel stack memory , because various fields of a semid_ds struct declared on the stack are not altered or zeroed before being copied back to the user.

CVE-2010-3881 describes a vulnerability in which structure padding and reserved fields in certain data structures in QEMU-KVM were not initialized properly before being copied to user space. A privileged host user with access to /dev/kvm could use this flaw to leak kernel stack memory to user space.

CVE-2010-3477 describes a kernel information leak in act_police where incorrectly initialized structures in the traffic-control dump code may allow the disclosure of kernel memory to user space applications.

...