Large null:// allocation causing negative pointer issues on iobank ##io

* Crash reproducer 9e248945-73a7-4cd7-906b-1544a0a3cc36
This commit is contained in:
pancake 2023-04-11 13:45:26 +02:00 committed by pancake
parent c6ff4a7338
commit 9f90b76155
3 changed files with 21 additions and 16 deletions

View File

@ -110,10 +110,12 @@ static RIOMapRef *_mapref_from_map(RIOMap *map) {
// cb for finding sm by lower boundary vaddr
static int _find_sm_by_from_vaddr_cb(void *incoming, void *in, void *user) {
RIOSubMap *bd = (RIOSubMap *)incoming, *sm = (RIOSubMap *)in;
if (r_io_submap_from (bd) < r_io_submap_from (sm)) {
ut64 a = r_io_submap_from (bd);
ut64 b = r_io_submap_from (sm);
if (a < b) {
return -1;
}
if (r_io_submap_from (bd) > r_io_submap_from (sm)) {
if (a > b) {
return 1;
}
return 0;
@ -778,19 +780,17 @@ R_API bool r_io_bank_read_at(RIO *io, const ut32 bankid, ut64 addr, ut8 *buf, in
// mapref doesn't belong to map
return false;
}
if (!(map->perm & R_PERM_R)) {
node = r_rbnode_next (node);
sm = node ? (RIOSubMap *)node->data : NULL;
continue;
}
const ut64 buf_off = R_MAX (addr, r_io_submap_from (sm)) - addr;
const int read_len = R_MIN (r_io_submap_to ((&fake_sm)),
r_io_submap_to (sm)) - (addr + buf_off) + 1;
if (map->perm & R_PERM_RELOC && map->reloc_map) {
ret &= map->reloc_map->read (io, map, addr + buf_off, &buf[buf_off], read_len);
} else {
const ut64 paddr = addr + buf_off - r_io_map_from (map) + map->delta;
ret &= (r_io_fd_read_at (io, map->fd, paddr, &buf[buf_off], read_len) == read_len);
if (map->perm & R_PERM_R) {
const ut64 buf_off = R_MAX (addr, r_io_submap_from (sm)) - addr;
const int read_len = R_MIN (r_io_submap_to ((&fake_sm)),
r_io_submap_to (sm)) - (addr + buf_off) + 1;
if (map->perm & R_PERM_RELOC && map->reloc_map) {
eprintf (" (%s) %p\n", map->name, map->reloc_map);
ret &= map->reloc_map->read (io, map, addr + buf_off, buf + buf_off, read_len);
} else {
const ut64 paddr = addr + buf_off - r_io_map_from (map) + map->delta;
ret &= (r_io_fd_read_at (io, map->fd, paddr, buf + buf_off, read_len) == read_len);
}
}
// check return value here?
node = r_rbnode_next (node);
@ -941,7 +941,7 @@ R_API void r_io_bank_del_map(RIO *io, const ut32 bankid, const ut32 mapid) {
r_return_if_fail (io);
// no need to check for mapref here, since this is "just" deleting
RIOBank *bank = r_io_bank_get (io, bankid);
RIOMap *map = r_io_map_get (io, mapid); //is this needed?
RIOMap *map = r_io_map_get (io, mapid); // is this needed?
if (!bank || !map) {
return;
}

View File

@ -23,6 +23,7 @@ static RIOMap *io_map_new(RIO* io, int fd, int perm, ut64 delta, ut64 addr, ut64
map->ts = io->mts++;
// RIOMap describes an interval of addresses
// r_io_map_from (map) -> r_io_map_to (map)
map->reloc_map = NULL;
map->itv = (RInterval){ addr, size };
map->perm = perm;
map->delta = delta;

View File

@ -93,6 +93,10 @@ static RIODesc* __open(RIO* io, const char* pathname, int rw, int mode) {
RIONull *null = R_NEW0 (RIONull);
if (null) {
null->size = r_num_math (NULL, pathname + 7) + 1;
if (null->size > ST32_MAX) {
R_LOG_ERROR ("Large null allocation is not valid");
return NULL;
}
null->offset = 0LL;
return r_io_desc_new (io, &r_io_plugin_null, pathname, rw, mode, null);
}