Skip to content

Commit 8c826d4

Browse files
rizlikdanielinux
authored andcommitted
disk.c: fix integer underflow in disk_part_read/disk_part_write
fix integer underflow when off is past part->end inside disk_part_read/disk_part_write. This check: if ((p->end - (p->start + off)) < sz) { len = p->end - (p->start + off); will underflow into a very big number being all values unisgned integer.
1 parent 88442f0 commit 8c826d4

1 file changed

Lines changed: 25 additions & 7 deletions

File tree

src/disk.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -277,18 +277,27 @@ int disk_part_read(int drv, int part, uint64_t off, uint64_t sz, uint8_t *buf)
277277
{
278278
struct disk_partition *p = open_part(drv, part);
279279
int len = sz;
280+
uint64_t start;
280281
int ret;
281282
if (p == NULL) {
282283
return -1;
283284
}
284-
if ((p->end - (p->start + off)) < sz) {
285-
len = p->end - (p->start + off);
285+
start = p->start + off;
286+
/* overflow */
287+
if (start < p->start) {
288+
return -1;
289+
}
290+
/* p->end is the last valid byte we can read */
291+
if (start > p->end) {
292+
return -1;
293+
}
294+
if ((p->end - start + 1) < sz) {
295+
len = (uint32_t)(p->end - start + 1);
286296
}
287297
if (len < 0) {
288298
return -1;
289299
}
290-
291-
ret = disk_read(drv, p->start + off, len, buf);
300+
ret = disk_read(drv, start, len, buf);
292301
#ifdef DEBUG_DISK
293302
wolfBoot_printf("disk_part_read: drv: %d, part: %d, off: %llu, sz: %llu, "
294303
"buf: %p, ret %d\r\n", drv, part, p->start + off, len, buf, ret);
@@ -317,17 +326,26 @@ int disk_part_write(int drv, int part, uint64_t off, uint64_t sz, const uint8_t
317326
{
318327
struct disk_partition *p = open_part(drv, part);
319328
int len = sz;
329+
uint64_t start;
320330
int ret;
321331
if (p == NULL) {
322332
return -1;
323333
}
324-
if ((p->end - (p->start + off)) < sz) {
325-
len = p->end - (p->start + off);
334+
start = p->start + off;
335+
/* overflow */
336+
if (start < p->start) {
337+
return -1;
338+
}
339+
if (start > p->end) {
340+
return -1;
341+
}
342+
if ((p->end - start + 1) < sz) {
343+
len = (uint32_t)(p->end - start + 1);
326344
}
327345
if (len < 0) {
328346
return -1;
329347
}
330-
ret = disk_write(drv, p->start + off, len, buf);
348+
ret = disk_write(drv, start, len, buf);
331349
#ifdef DEBUG_DISK
332350
wolfBoot_printf("disk_part_write: drv: %d, part: %d, off: %llu, sz: %llu, "
333351
"buf: %p, ret %d\r\n", drv, part, p->start + off, sz, buf, ret);

0 commit comments

Comments
 (0)