0

I'm reading some code which mmaps a file, and assigns the returned value to a pointer to a struct:

struct cache_header {
    unsigned int signature;
    unsigned int version;
    unsigned int entries;
    unsigned char sha1[20];
};

struct cache_header *hdr;
map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
hdr = map;

Later the code verifies the struct loaded from the file, this is the part I don't understand:

SHA_CTX c;
    unsigned char sha1[20];
    if (hdr->signature != CACHE_SIGNATURE)
        return error("bad signature");
    if (hdr->version != 1)
        return error("bad version");
    SHA1_Init(&c);
    SHA1_Update(&c, hdr, offsetof(struct cache_header, sha1));
    SHA1_Update(&c, hdr+1, size - sizeof(*hdr));
    SHA1_Final(sha1, &c);
    if (memcmp(sha1, hdr->sha1, 20))
        return error("bad header sha1");
    return 0;

Can you explain why :

1.there's hdr+1 in the second call to SHA1_Update

2.In the call to memcmp, hdr->sha1is a pointer, wouldn't it's value be invalid, since the struct has just been read from the disk, and it was written by another program of the codebase.

Note: size is the size of file

saga
  • 1,933
  • 2
  • 17
  • 44

1 Answers1

2
  1. Perhaps the file is large enough to contain two instances of the struct? What is the value of size?
  2. No, hdr->sha1 is not a pointer, it's an array. That array is part of the struct, and hdr->sha1 evaluates to the address of the first element. There is no pointer stored there.

Also note that this is bad practice, since you're relying on the structs being packed (no padding) without making sure.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Isn't an array name in C just a pointer to the first element of the array? – saga Oct 05 '17 at 13:55
  • @saga No, absolutely not. It *evaluates* to one at times, but it's not the same thing. See [this question](https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer) for more. – unwind Oct 05 '17 at 13:56