diff options
author | Jacques Germishuys <jacquesg@striata.com> | 2014-09-25 13:07:36 +0200 |
---|---|---|
committer | Jacques Germishuys <jacquesg@striata.com> | 2014-09-26 12:12:08 +0200 |
commit | ff97778a7a01eb3661418d4dcc1465dc4519fda3 (patch) | |
tree | 05f47899aad83f8ef054e838651ed9f58201b19b | |
parent | ad8c8d9325397c9c6979e16e889de432beee8c9b (diff) | |
download | libgit2-ff97778a7a01eb3661418d4dcc1465dc4519fda3.tar.gz |
The raw index buffer content is not guaranteed to be aligned
* Ensure alignment by copying the content into a structure on the stack
-rw-r--r-- | src/index.c | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/src/index.c b/src/index.c index b63a0bec6..8b757f269 100644 --- a/src/index.c +++ b/src/index.c @@ -1767,35 +1767,42 @@ static size_t read_entry( git_index_entry **out, const void *buffer, size_t buffer_size) { size_t path_length, entry_size; - uint16_t flags_raw; const char *path_ptr; - const struct entry_short *source = buffer; + struct entry_short source; git_index_entry entry = {{0}}; if (INDEX_FOOTER_SIZE + minimal_entry_size > buffer_size) return 0; - entry.ctime.seconds = (git_time_t)ntohl(source->ctime.seconds); - entry.ctime.nanoseconds = ntohl(source->ctime.nanoseconds); - entry.mtime.seconds = (git_time_t)ntohl(source->mtime.seconds); - entry.mtime.nanoseconds = ntohl(source->mtime.nanoseconds); - entry.dev = ntohl(source->dev); - entry.ino = ntohl(source->ino); - entry.mode = ntohl(source->mode); - entry.uid = ntohl(source->uid); - entry.gid = ntohl(source->gid); - entry.file_size = ntohl(source->file_size); - git_oid_cpy(&entry.id, &source->oid); - entry.flags = ntohs(source->flags); + /* buffer is not guaranteed to be aligned */ + memcpy(&source, buffer, sizeof(struct entry_short)); + + entry.ctime.seconds = (git_time_t)ntohl(source.ctime.seconds); + entry.ctime.nanoseconds = ntohl(source.ctime.nanoseconds); + entry.mtime.seconds = (git_time_t)ntohl(source.mtime.seconds); + entry.mtime.nanoseconds = ntohl(source.mtime.nanoseconds); + entry.dev = ntohl(source.dev); + entry.ino = ntohl(source.ino); + entry.mode = ntohl(source.mode); + entry.uid = ntohl(source.uid); + entry.gid = ntohl(source.gid); + entry.file_size = ntohl(source.file_size); + git_oid_cpy(&entry.id, &source.oid); + entry.flags = ntohs(source.flags); if (entry.flags & GIT_IDXENTRY_EXTENDED) { - const struct entry_long *source_l = (const struct entry_long *)source; - path_ptr = source_l->path; + uint16_t flags_raw; + size_t flags_offset; - flags_raw = ntohs(source_l->flags_extended); - memcpy(&entry.flags_extended, &flags_raw, 2); + flags_offset = offsetof(struct entry_long, flags_extended); + memcpy(&flags_raw, (const char *) buffer + flags_offset, + sizeof(flags_raw)); + flags_raw = ntohs(flags_raw); + + memcpy(&entry.flags_extended, &flags_raw, sizeof(flags_raw)); + path_ptr = (const char *) buffer + offsetof(struct entry_long, path); } else - path_ptr = source->path; + path_ptr = (const char *) buffer + offsetof(struct entry_short, path); path_length = entry.flags & GIT_IDXENTRY_NAMEMASK; @@ -1846,14 +1853,12 @@ static int read_header(struct index_header *dest, const void *buffer) static size_t read_extension(git_index *index, const char *buffer, size_t buffer_size) { - const struct index_extension *source; struct index_extension dest; size_t total_size; - source = (const struct index_extension *)(buffer); - - memcpy(dest.signature, source->signature, 4); - dest.extension_size = ntohl(source->extension_size); + /* buffer is not guaranteed to be aligned */ + memcpy(&dest, buffer, sizeof(struct index_extension)); + dest.extension_size = ntohl(dest.extension_size); total_size = dest.extension_size + sizeof(struct index_extension); |