Versions Compared

Key

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

...

Code Block
bgColor#CCCCFF
borderStylesolid
#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};
  /* May be larger than strictly needed */
  unsigned char buf[sizeof(arg)];
  size_t sizeoffset = 0;
  
  *((int *)(memcpy(buf + size)) = offset, &arg.a, sizeof(arg.a));
  sizeoffset += sizeof(arg.a);
  *((char *)(memcpy(buf + size)) = offset, &arg.b, sizeof(arg.b));
  sizeoffset += sizeof(arg.b);
  *((int *)(memcpy(buf + size)) = offset, &arg.c, sizeof(arg.c));
  sizeoffset += sizeof(arg.c);

  copy_to_user(usr_buf, buf, offset /* size of info copied */);
} 

This code ensures that no uninitialized padding bytes are copied to unprivileged users. Note that 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 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 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 both static _assert expressions assertions should be true. However, it is necessary to validate these assumptions to ensure that the solution is correct for a particular implementation.

...

Microsoft Visual Studio  supports #pragma pack() to suppress padding bytes [MSDN]. The compiler will add adds 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 1 in an attempt to ensure all fields are given adjacent offsets:

...