Description
CBMC version: 6.4.0
Operating system: Ubuntu 22.04
Exact command line resulting in the issue: cbmc memcmp.c
What behaviour did you expect: I expected the verification to fail since the memory being compared contains padding bytes. However, CBMC seems to be initializing all the padding bytes with 0s.
What happened instead: Verification succeeded
Example:
#include <string.h>
#include <stdint.h>
struct WPad {
uint8_t u8;
uint32_t u32;
} WPad;
int main() {
struct WPad val = { 255, 0 };
struct WPad new_val = { 255, 0 };
struct WPad copy = val;
assert(memcmp(&val, ©, 8) == 0);
assert(memcmp(&new_val, ©, 8) == 0);
uint8_t* array = (uint8_t*) (void*) &val;
assert(array[0] == 255);
assert(array[1] == 0);
assert(array[2] == 0);
assert(array[3] == 0);
assert(array[4] == 0);
assert(array[5] == 0);
assert(array[6] == 0);
assert(array[7] == 0);
}
From what I can tell, the C spec says that the values of padding bytes are unspecified.
When a value is stored in an object of structure or union type, including in a member object, the
bytes of the object representation that correspond to any padding bytes take unspecified values
Running the same example using gcc
with address sanitizer and maybe uninitialized warnings gives me the following result:
$ gcc -o memcmp -fsanitize=undefined -g -fno-omit-frame-pointer -O2 memcmp.c -Wmaybe-uninitialized In file included from memcmp.c:3: memcmp.c: In function ‘main’: memcmp.c:19:17: warning: ‘val’ may be used uninitialized [-Wmaybe-uninitialized] 19 | assert(array[1] == 0); | ~~~~~^~~ memcmp.c:11:17: note: ‘val’ declared here 11 | struct WPad val = { 255, 0 }; | ^~~ In file included from memcmp.c:3: memcmp.c:20:17: warning: ‘val’ may be used uninitialized [-Wmaybe-uninitialized] 20 | assert(array[2] == 0); | ~~~~~^~~ memcmp.c:11:17: note: ‘val’ declared here 11 | struct WPad val = { 255, 0 }; | ^~~ In file included from memcmp.c:3: memcmp.c:21:17: warning: ‘val’ may be used uninitialized [-Wmaybe-uninitialized] 21 | assert(array[3] == 0); | ~~~~~^~~ memcmp.c:11:17: note: ‘val’ declared here 11 | struct WPad val = { 255, 0 }; | ^~~