Commit 57f31f05 by Edward Thomson

Fixes to safely reading the index

Avoid wrapping around extension size when reading, avoid walking off
the end of the buffer when reading names.
parent 5e96f316
...@@ -1371,7 +1371,7 @@ static int read_reuc(git_index *index, const char *buffer, size_t size) ...@@ -1371,7 +1371,7 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
while (size) { while (size) {
git_index_reuc_entry *lost; git_index_reuc_entry *lost;
len = strlen(buffer) + 1; len = p_strnlen(buffer, size) + 1;
if (size <= len) if (size <= len)
return index_error_invalid("reading reuc entries"); return index_error_invalid("reading reuc entries");
...@@ -1444,7 +1444,7 @@ static int read_conflict_names(git_index *index, const char *buffer, size_t size ...@@ -1444,7 +1444,7 @@ static int read_conflict_names(git_index *index, const char *buffer, size_t size
return -1; return -1;
#define read_conflict_name(ptr) \ #define read_conflict_name(ptr) \
len = strlen(buffer) + 1; \ len = p_strnlen(buffer, size) + 1; \
if (size < len) \ if (size < len) \
return index_error_invalid("reading conflict name entries"); \ return index_error_invalid("reading conflict name entries"); \
\ \
...@@ -1571,7 +1571,8 @@ static size_t read_extension(git_index *index, const char *buffer, size_t buffer ...@@ -1571,7 +1571,8 @@ static size_t read_extension(git_index *index, const char *buffer, size_t buffer
total_size = dest.extension_size + sizeof(struct index_extension); total_size = dest.extension_size + sizeof(struct index_extension);
if (buffer_size < total_size || if (dest.extension_size > total_size ||
buffer_size < total_size ||
buffer_size - total_size < INDEX_FOOTER_SIZE) buffer_size - total_size < INDEX_FOOTER_SIZE)
return 0; return 0;
......
...@@ -93,6 +93,10 @@ extern int p_gettimeofday(struct timeval *tv, struct timezone *tz); ...@@ -93,6 +93,10 @@ extern int p_gettimeofday(struct timeval *tv, struct timezone *tz);
# include "unix/posix.h" # include "unix/posix.h"
#endif #endif
#ifndef __MINGW32__
# define p_strnlen strnlen
#endif
#ifdef NO_READDIR_R #ifdef NO_READDIR_R
# include <dirent.h> # include <dirent.h>
GIT_INLINE(int) p_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) GIT_INLINE(int) p_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
......
...@@ -19,6 +19,11 @@ ...@@ -19,6 +19,11 @@
# define S_IFLNK _S_IFLNK # define S_IFLNK _S_IFLNK
# define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK) # define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK)
GIT_INLINE(size_t) p_strnlen(const char *s, size_t maxlen) {
const char *end = memchr(s, 0, maxlen);
return end ? (end - s) : maxlen;
}
#endif #endif
#endif /* INCLUDE_mingw_compat__ */ #endif /* INCLUDE_mingw_compat__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment