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 <trast@student.ethz.ch> using valgrind. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michael Haggerty committed
Sep 23, 2011 at 15:38 UTC
d4e85a1afe0a3310a3c8336c2824775901cc27d7
2 files changed
+18
-1
cache.h
+9
@@ -819,7 +819,16 @@ static inline int get_sha1_with_context(const char *str, unsigned char *sha1, st
819
{
820
return get_sha1_with_context_1(str, sha1, orc, 0, NULL);
821
}
822
+
823
+/*
824
+ * Try to read a SHA1 in hexadecimal format from the 40 characters
825
+ * starting at hex. Write the 20-byte result to sha1 in binary form.
826
+ * Return 0 on success. Reading stops if a NUL is encountered in the
827
+ * input, so it is safe to pass this function an arbitrary
828
+ * null-terminated string.
829
+ */
830
extern int get_sha1_hex(const char *hex, unsigned char *sha1);
831
+
832
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
833
extern int read_ref(const char *filename, unsigned char *sha1);
834
extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *);
hex.c
+9
-1
@@ -39,7 +39,15 @@ int get_sha1_hex(const char *hex, unsigned char *sha1)
39
{
40
int i;
41
for (i = 0; i < 20; i++) {
42
- unsigned int val = (hexval(hex[0]) << 4) | hexval(hex[1]);
42
+ unsigned int val;
43
+ /*
44
+ * hex[1]=='\0' is caught when val is checked below,
45
+ * but if hex[0] is NUL we have to avoid reading
46
+ * past the end of the string:
47
+ */
48
+ if (!hex[0])
49
+ return -1;
50
+ val = (hexval(hex[0]) << 4) | hexval(hex[1]);
51
if (val & ~0xff)
52
return -1;
53
*sha1++ = val;