diff options
author | Vicent Martà <vicent@github.com> | 2013-08-09 15:30:50 -0700 |
---|---|---|
committer | Vicent Martà <vicent@github.com> | 2013-08-09 15:30:50 -0700 |
commit | a25519acc106acf6e1f376c81a078c78778015ed (patch) | |
tree | 521b63ad899f1fc1d8bad559750b8b3620a18e97 | |
parent | d1be9e4ca18caa37c69afb988994a99cd137a3b8 (diff) | |
parent | a1f69452a22689ca2eede7669e79a3e7ab849cdd (diff) | |
download | libgit2-a25519acc106acf6e1f376c81a078c78778015ed.tar.gz |
Merge pull request #1770 from ethomson/index_fuzz
Fixes to safely reading the index
-rw-r--r-- | src/index.c | 7 | ||||
-rw-r--r-- | src/posix.h | 4 | ||||
-rw-r--r-- | src/util.h | 3 | ||||
-rw-r--r-- | src/win32/mingw-compat.h | 5 |
4 files changed, 16 insertions, 3 deletions
diff --git a/src/index.c b/src/index.c index cbdd43bdc..5f53f1e2f 100644 --- a/src/index.c +++ b/src/index.c @@ -1371,7 +1371,7 @@ static int read_reuc(git_index *index, const char *buffer, size_t size) while (size) { git_index_reuc_entry *lost; - len = strlen(buffer) + 1; + len = p_strnlen(buffer, size) + 1; if (size <= len) 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 return -1; #define read_conflict_name(ptr) \ - len = strlen(buffer) + 1; \ + len = p_strnlen(buffer, size) + 1; \ if (size < len) \ 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 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) return 0; diff --git a/src/posix.h b/src/posix.h index 40bcc1ab0..ea97a1349 100644 --- a/src/posix.h +++ b/src/posix.h @@ -93,6 +93,10 @@ extern int p_gettimeofday(struct timeval *tv, struct timezone *tz); # include "unix/posix.h" #endif +#ifndef __MINGW32__ +# define p_strnlen strnlen +#endif + #ifdef NO_READDIR_R # include <dirent.h> GIT_INLINE(int) p_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) diff --git a/src/util.h b/src/util.h index ed9624770..a784390c1 100644 --- a/src/util.h +++ b/src/util.h @@ -55,6 +55,9 @@ GIT_INLINE(char *) git__strndup(const char *str, size_t n) ptr = (char*)git__malloc(length + 1); + if (!ptr) + return NULL; + if (length) memcpy(ptr, str, length); diff --git a/src/win32/mingw-compat.h b/src/win32/mingw-compat.h index 7b97b48db..97b1cb71b 100644 --- a/src/win32/mingw-compat.h +++ b/src/win32/mingw-compat.h @@ -19,6 +19,11 @@ # define S_IFLNK _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 /* INCLUDE_mingw_compat__ */ |