From: Michael Haggerty Date: Fri, 23 Sep 2011 13:38:36 +0000 (+0200) Subject: get_sha1_hex(): do not read past a NUL character X-Git-Tag: v1.7.8-rc0~19^2~25 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=d4e85a1afe0a3310a3c8336c2824775901cc27d7;p=git.git get_sha1_hex(): do not read past a NUL character Previously, get_sha1_hex() would read one character past the end of a null-terminated string whose strlen was an even number less than 40. Although the function correctly returned -1 in these cases, the extra memory access might have been to uninitialized (or even, conceivably, unallocated) memory. Add a check to avoid reading past the end of a string. This problem was discovered by Thomas Rast using valgrind. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- diff --git a/cache.h b/cache.h index 607c2ea61..e7bbc0deb 100644 --- a/cache.h +++ b/cache.h @@ -819,7 +819,16 @@ static inline int get_sha1_with_context(const char *str, unsigned char *sha1, st { return get_sha1_with_context_1(str, sha1, orc, 0, NULL); } + +/* + * Try to read a SHA1 in hexadecimal format from the 40 characters + * starting at hex. Write the 20-byte result to sha1 in binary form. + * Return 0 on success. Reading stops if a NUL is encountered in the + * input, so it is safe to pass this function an arbitrary + * null-terminated string. + */ extern int get_sha1_hex(const char *hex, unsigned char *sha1); + extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */ extern int read_ref(const char *filename, unsigned char *sha1); extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *); diff --git a/hex.c b/hex.c index bb402fbaa..9ebc05063 100644 --- a/hex.c +++ b/hex.c @@ -39,7 +39,15 @@ int get_sha1_hex(const char *hex, unsigned char *sha1) { int i; for (i = 0; i < 20; i++) { - unsigned int val = (hexval(hex[0]) << 4) | hexval(hex[1]); + unsigned int val; + /* + * hex[1]=='\0' is caught when val is checked below, + * but if hex[0] is NUL we have to avoid reading + * past the end of the string: + */ + if (!hex[0]) + return -1; + val = (hexval(hex[0]) << 4) | hexval(hex[1]); if (val & ~0xff) return -1; *sha1++ = val;