Skip to content

Commit f35f43f

Browse files
committed
Merge branch 'jk/ewah-bounds-check'
The code to read compressed bitmap was not careful to avoid reading past the end of the file, which has been corrected. * jk/ewah-bounds-check: ewah: adjust callers of ewah_read_mmap() ewah_read_mmap: bounds-check mmap reads
2 parents 1663e2b + 1140bf0 commit f35f43f

File tree

5 files changed

+38
-7
lines changed

5 files changed

+38
-7
lines changed

dir.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2853,7 +2853,8 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
28532853
struct read_data rd;
28542854
const unsigned char *next = data, *end = (const unsigned char *)data + sz;
28552855
const char *ident;
2856-
int ident_len, len;
2856+
int ident_len;
2857+
ssize_t len;
28572858
const char *exclude_per_dir;
28582859

28592860
if (sz <= 1 || end[-1] != '\0')

ewah/ewah_io.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,23 @@ int ewah_serialize_strbuf(struct ewah_bitmap *self, struct strbuf *sb)
122122
return ewah_serialize_to(self, write_strbuf, sb);
123123
}
124124

125-
int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len)
125+
ssize_t ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len)
126126
{
127127
const uint8_t *ptr = map;
128+
size_t data_len;
128129
size_t i;
129130

131+
if (len < sizeof(uint32_t))
132+
return error("corrupt ewah bitmap: eof before bit size");
130133
self->bit_size = get_be32(ptr);
131134
ptr += sizeof(uint32_t);
135+
len -= sizeof(uint32_t);
132136

137+
if (len < sizeof(uint32_t))
138+
return error("corrupt ewah bitmap: eof before length");
133139
self->buffer_size = self->alloc_size = get_be32(ptr);
134140
ptr += sizeof(uint32_t);
141+
len -= sizeof(uint32_t);
135142

136143
REALLOC_ARRAY(self->buffer, self->alloc_size);
137144

@@ -141,15 +148,25 @@ int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len)
141148
* the endianness conversion in a separate pass to ensure
142149
* we're loading 8-byte aligned words.
143150
*/
144-
memcpy(self->buffer, ptr, self->buffer_size * sizeof(eword_t));
145-
ptr += self->buffer_size * sizeof(eword_t);
151+
data_len = st_mult(self->buffer_size, sizeof(eword_t));
152+
if (len < data_len)
153+
return error("corrupt ewah bitmap: eof in data "
154+
"(%"PRIuMAX" bytes short)",
155+
(uintmax_t)(data_len - len));
156+
memcpy(self->buffer, ptr, data_len);
157+
ptr += data_len;
158+
len -= data_len;
146159

147160
for (i = 0; i < self->buffer_size; ++i)
148161
self->buffer[i] = ntohll(self->buffer[i]);
149162

163+
if (len < sizeof(uint32_t))
164+
return error("corrupt ewah bitmap: eof before rlw");
150165
self->rlw = self->buffer + get_be32(ptr);
166+
ptr += sizeof(uint32_t);
167+
len -= sizeof(uint32_t);
151168

152-
return (3 * 4) + (self->buffer_size * 8);
169+
return ptr - (const uint8_t *)map;
153170
}
154171

155172
int ewah_deserialize(struct ewah_bitmap *self, int fd)

ewah/ewok.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ int ewah_serialize_native(struct ewah_bitmap *self, int fd);
9191
int ewah_serialize_strbuf(struct ewah_bitmap *self, struct strbuf *);
9292

9393
int ewah_deserialize(struct ewah_bitmap *self, int fd);
94-
int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len);
94+
ssize_t ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len);
9595

9696
uint32_t ewah_checksum(struct ewah_bitmap *self);
9797

pack-bitmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static struct ewah_bitmap *read_bitmap_1(struct bitmap_index *index)
120120
{
121121
struct ewah_bitmap *b = ewah_pool_new();
122122

123-
int bitmap_size = ewah_read_mmap(b,
123+
ssize_t bitmap_size = ewah_read_mmap(b,
124124
index->map + index->map_pos,
125125
index->map_size - index->map_pos);
126126

t/t5310-pack-bitmaps.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,4 +331,17 @@ test_expect_success 'pack reuse respects --incremental' '
331331
git show-index <empty.idx >actual &&
332332
test_cmp expect actual
333333
'
334+
335+
test_expect_success 'truncated bitmap fails gracefully' '
336+
git repack -ad &&
337+
git rev-list --use-bitmap-index --count --all >expect &&
338+
bitmap=$(ls .git/objects/pack/*.bitmap) &&
339+
test_when_finished "rm -f $bitmap" &&
340+
head -c 512 <$bitmap >$bitmap.tmp &&
341+
mv -f $bitmap.tmp $bitmap &&
342+
git rev-list --use-bitmap-index --count --all >actual 2>stderr &&
343+
test_cmp expect actual &&
344+
test_i18ngrep corrupt stderr
345+
'
346+
334347
test_done

0 commit comments

Comments
 (0)