summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Martí <vicent@github.com>2013-08-09 15:30:50 -0700
committerVicent Martí <vicent@github.com>2013-08-09 15:30:50 -0700
commita25519acc106acf6e1f376c81a078c78778015ed (patch)
tree521b63ad899f1fc1d8bad559750b8b3620a18e97
parentd1be9e4ca18caa37c69afb988994a99cd137a3b8 (diff)
parenta1f69452a22689ca2eede7669e79a3e7ab849cdd (diff)
downloadlibgit2-a25519acc106acf6e1f376c81a078c78778015ed.tar.gz
Merge pull request #1770 from ethomson/index_fuzz
Fixes to safely reading the index
-rw-r--r--src/index.c7
-rw-r--r--src/posix.h4
-rw-r--r--src/util.h3
-rw-r--r--src/win32/mingw-compat.h5
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__ */