Versions Compared

Key

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

...

In case of MSVC, use #pragma pack() instead of the __packed__ attribute to ensure no padding bytes are added.

...

The following solution assumes to be implemented in an IA32 machineit will be run on an IA-32 architecture.

Code Block
bgColor#CCCCFF
borderStylesolid
#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));

  /* ... */
}

...

See recommendation DCL03-C. Use a static assertion to test the value of a constant expression

For Exampleexample, In in an IA32 IA-32 machine,

The explicit insertion of the padding bytes inserted into the struct should ensure that no "invisible" padding bytes are added in by the compiler, and thus the expression in static_assert should be truei.e..

For example on IA-32,

offsetof(struct test, c ) = 8

and

offsetof(struct test, padding_3 ) = 7

But, if there is padding bytes added then,

,

and thus, the expression should return 1.

However, if the compiler adds padding bytes, then the The memory would not be continuous contiguous and the expression would return 0. 

This approach ensures that no padding bytes are inserted.

...