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>
This commit is contained in:

committed by
Junio C Hamano

parent
3793ac56b4
commit
d4e85a1afe
9
cache.h
9
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);
|
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 int get_sha1_hex(const char *hex, unsigned char *sha1);
|
||||||
|
|
||||||
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
|
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
|
||||||
extern int read_ref(const char *filename, unsigned char *sha1);
|
extern int read_ref(const char *filename, unsigned char *sha1);
|
||||||
extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *);
|
extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *);
|
||||||
|
10
hex.c
10
hex.c
@ -39,7 +39,15 @@ int get_sha1_hex(const char *hex, unsigned char *sha1)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 20; 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)
|
if (val & ~0xff)
|
||||||
return -1;
|
return -1;
|
||||||
*sha1++ = val;
|
*sha1++ = val;
|
||||||
|
Reference in New Issue
Block a user