mirror of
https://github.com/git/git.git
synced 2024-11-27 20:14:30 +08:00
Merge branch 'jc/verify-loose-object-header'
Codepaths that read from an on-disk loose object were too loose in validating what they are reading is a proper object file and sometimes read past the data they read from the disk, which has been corrected. H/t to Gustavo Grieco for reporting. * jc/verify-loose-object-header: unpack_sha1_header(): detect malformed object header streaming: make sure to notice corrupt object
This commit is contained in:
commit
71a57ab32d
26
sha1_file.c
26
sha1_file.c
@ -1646,7 +1646,9 @@ unsigned long unpack_object_header_buffer(const unsigned char *buf,
|
||||
return used;
|
||||
}
|
||||
|
||||
int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz)
|
||||
static int unpack_sha1_short_header(git_zstream *stream,
|
||||
unsigned char *map, unsigned long mapsize,
|
||||
void *buffer, unsigned long bufsiz)
|
||||
{
|
||||
/* Get the data stream */
|
||||
memset(stream, 0, sizeof(*stream));
|
||||
@ -1659,13 +1661,31 @@ int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long ma
|
||||
return git_inflate(stream, 0);
|
||||
}
|
||||
|
||||
int unpack_sha1_header(git_zstream *stream,
|
||||
unsigned char *map, unsigned long mapsize,
|
||||
void *buffer, unsigned long bufsiz)
|
||||
{
|
||||
int status = unpack_sha1_short_header(stream, map, mapsize,
|
||||
buffer, bufsiz);
|
||||
|
||||
if (status < Z_OK)
|
||||
return status;
|
||||
|
||||
/* Make sure we have the terminating NUL */
|
||||
if (!memchr(buffer, '\0', stream->next_out - (unsigned char *)buffer))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unpack_sha1_header_to_strbuf(git_zstream *stream, unsigned char *map,
|
||||
unsigned long mapsize, void *buffer,
|
||||
unsigned long bufsiz, struct strbuf *header)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = unpack_sha1_header(stream, map, mapsize, buffer, bufsiz);
|
||||
status = unpack_sha1_short_header(stream, map, mapsize, buffer, bufsiz);
|
||||
if (status < Z_OK)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Check if entire header is unpacked in the first iteration.
|
||||
@ -1756,6 +1776,8 @@ static int parse_sha1_header_extended(const char *hdr, struct object_info *oi,
|
||||
*/
|
||||
for (;;) {
|
||||
char c = *hdr++;
|
||||
if (!c)
|
||||
return -1;
|
||||
if (c == ' ')
|
||||
break;
|
||||
type_len++;
|
||||
|
12
streaming.c
12
streaming.c
@ -337,17 +337,17 @@ static open_method_decl(loose)
|
||||
st->u.loose.mapped = map_sha1_file(sha1, &st->u.loose.mapsize);
|
||||
if (!st->u.loose.mapped)
|
||||
return -1;
|
||||
if (unpack_sha1_header(&st->z,
|
||||
st->u.loose.mapped,
|
||||
st->u.loose.mapsize,
|
||||
st->u.loose.hdr,
|
||||
sizeof(st->u.loose.hdr)) < 0) {
|
||||
if ((unpack_sha1_header(&st->z,
|
||||
st->u.loose.mapped,
|
||||
st->u.loose.mapsize,
|
||||
st->u.loose.hdr,
|
||||
sizeof(st->u.loose.hdr)) < 0) ||
|
||||
(parse_sha1_header(st->u.loose.hdr, &st->size) < 0)) {
|
||||
git_inflate_end(&st->z);
|
||||
munmap(st->u.loose.mapped, st->u.loose.mapsize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
parse_sha1_header(st->u.loose.hdr, &st->size);
|
||||
st->u.loose.hdr_used = strlen(st->u.loose.hdr) + 1;
|
||||
st->u.loose.hdr_avail = st->z.total_out;
|
||||
st->z_state = z_used;
|
||||
|
Loading…
Reference in New Issue
Block a user