Fixing coverity issues for io_zip, hanging caused by infinite loop in disasm.c,

and io map collisions (which adds file.loadalign, file.loadmethod (append or fail),
and file.suppresswarnings.
This commit is contained in:
Adam Pridgen 2014-01-25 18:06:17 -06:00
parent 67c4daf25f
commit e6fe3354d9
10 changed files with 215 additions and 42 deletions

View File

@ -4,21 +4,25 @@
R_API void r_core_bin_set_by_fd (RCore *core, ut64 bin_fd) {
RListIter *iter;
RBinFile *bf;
RBinFile *bf = NULL;
r_list_foreach (core->bin->binfiles, iter, bf) {
if (bf && bf->fd == bin_fd) {
core->bin->cur = bf;
break;
}
bf = NULL;
}
r_core_bin_bind (core);
if (bf) r_core_bin_bind (core);
}
R_API void r_core_bin_bind (RCore *core) {
r_bin_bind (core->bin, &(core->anal->binb));
r_bin_bind (core->bin, &(core->assembler->binb));
r_bin_bind (core->bin, &(core->file->binb));
if (core->bin) {
r_bin_bind (core->bin, &(core->anal->binb));
r_bin_bind (core->bin, &(core->assembler->binb));
r_bin_bind (core->bin, &(core->file->binb));
}
}
R_API int r_core_bin_refresh_strings(RCore *r) {

View File

@ -4,6 +4,7 @@ static int cmd_open(void *data, const char *input) {
RCore *core = (RCore*)data;
int perms = R_IO_READ;
ut64 addr, baddr = r_config_get_i (core->config, "bin.baddr");
char *suppress_warning = r_config_get (core->config, "file.suppress_warnings");
RIOMap *map = NULL;
RCoreFile *file;
RListIter *iter;
@ -37,7 +38,9 @@ static int cmd_open(void *data, const char *input) {
// MUST CLEAN BEFORE LOADING
if (!isn)
r_core_bin_load (core, fn, baddr);
} else eprintf ("Cannot open file '%s'\n", fn);
} else if (!strcmp (suppress_warning, "false")) {
eprintf ("Cannot open file '%s'\n", fn);
}
} else {
RListIter *iter = NULL;
RCoreFile *f;

View File

@ -833,7 +833,9 @@ R_API int r_core_config_init(RCore *core) {
SETPREF("file.project", "", "Name of current project");
SETPREF("file.sha1", "", "sha1 hash of current file");
SETPREF("file.type", "", "Type of current file");
SETPREF("file.loadmethod", "fail", "What to do when load addresses overlap: fail, overwrite, or append (next available)");
SETI("file.loadalign", 1024, "Alignment of load addresses");
SETPREF("file.suppress_warnings", "false", "Suppress file loading warning messages");
/* magic */
SETI("magic.depth", 100, "Recursivity depth in magic description strings");

View File

@ -1973,7 +1973,7 @@ R_API int r_core_print_fcn_disasm(RPrint *p, RCore *core, ut64 addr, int l, int
ret = handle_print_meta_infos (core, ds, buf,len, idx);
if (ds->mi_found) {
ds->mi_found = 0;
continue;
//continue;
}
/* show cursor */
handle_print_show_cursor (core, ds);

View File

@ -1,6 +1,7 @@
/* radare - LGPL - Copyright 2009-2014 - pancake */
#include <r_core.h>
#include <stdlib.h>
R_API ut64 r_core_file_resize(struct r_core_t *core, ut64 newsize) {
if (newsize==0 && core->file)
@ -296,20 +297,86 @@ R_API int r_core_bin_load(RCore *r, const char *file, ut64 baddr) {
return R_TRUE;
}
R_API RIOMap *r_core_file_get_next_map (RCore *core, RCoreFile * fh, int mode, ut64 loadaddr) {
const char *loadmethod = r_config_get (core->config, "file.loadmethod");
RIOMap *map = r_io_map_add (core->io, fh->fd->fd, mode, 0, loadaddr, fh->size);
char *suppress_warning = r_config_get (core->config, "file.suppress_warnings");
if (map) return map;
r_io_sort_maps (core->io);
if (!map && !strcmp (loadmethod, "overwrite")) {
/*ut64 total_buf_size = 0, idx = 0;
ut64 addr = loadaddr, endaddr = loadaddr + fh->size;
ut8 *buffer = NULL;
RHashTable64 ht = NULL;
RListIter *iter, *t_iter;
// XXX - this will take some work, walk all maps in the range of
// the current RCoreFile
// XXX - this does not handle if from > to.
// 2) Create a new mapping of total size of fh or all fd enumerate (which ever is greater)
// 3) copy old fds into map, close all old fds, map new
RList * maps = r_io_get_maps_in_range (addr, endaddr);
// 1) Count bytes, enumerate fds (if more than one, we will just fail)
r_list_foreach (maps, iter, map) {
ut64 bytes = (map->from < map->to)? map->from - map->to: -map->from - map->to;
total_buf_size += bytes;
}
total_buf_size = total_buf_size > fh->size ? total_buf_size : fh->size;
// Allocate buffer and copy bytes;
buffer = malloc(total_buf_size);
r_list_foreach (maps, iter, map) {
ut64 bytes = (map->from < map->to)? map->from - map->to: -map->from - map->to;
r_core_read_at (core, loadaddr+offset, buffer+offset, bytes);
offset += bytes;
}
ht = r_hashtable64_new();
ht->free = free;
r_list_foreach_safe (maps, iter, map) {
r_core_read_at (core, loadaddr+offset, buffer+offset, bytes);
offset += bytes;
}
*/
} else if (!map && !strcmp (loadmethod, "append")) {
ut64 load_align = r_config_get_i (core->config, "file.loadalign");
map = r_io_map_add_next_available (core->io, fh->fd->fd, mode, 0, loadaddr, fh->size, load_align);
if (map && !strcmp (suppress_warning, "false") ){
eprintf ("Unable to load specified file at current mapping: 0x%08"PFMT64x",", loadaddr);
eprintf (" but loading at 0x%08"PFMT64x".\n", map->from);
}
}
// implicit "fail" here
if (!map && !strcmp (suppress_warning, "false"))
eprintf ("Unable to load specified file at current mapping: 0x%08"PFMT64x"\n", loadaddr);
return map;
}
R_API RCoreFile *r_core_file_open_many(RCore *r, const char *file, int mode, ut64 loadaddr) {
RList *list_fds = NULL;
list_fds = r_io_open_many (r->io, file, mode, 0644);
RCoreFile *fh, *top_file = NULL;
RIODesc *fd;
RListIter *fd_iter;
ut64 current_loadaddr = loadaddr, offset = 0;
ut64 current_loadaddr = loadaddr;
char *suppress_warning = r_config_get (r->config, "file.suppress_warnings");
const char *cp = NULL;
char *loadmethod = NULL;
cp = r_config_get (r->config, "file.loadmethod");
if (cp) loadmethod = strdup (cp);
r_config_set (r->config, "file.loadmethod", "append");
if (!list_fds) return NULL;
r_list_foreach (list_fds, fd_iter, fd) {
fh = R_NEW0 (RCoreFile);
if (!top_file) top_file = fh;
fh->uri = strdup (file);
fh->fd = fd;
fh->size = r_io_desc_size (r->io, fd);
@ -319,10 +386,21 @@ R_API RCoreFile *r_core_file_open_many(RCore *r, const char *file, int mode, ut6
r->io->plugin = fd->plugin;
fh->size = r_io_size (r->io);
// XXX - load addr should be at a set offset
fh->map = r_io_map_add (r->io, fh->fd->fd, mode, 0, current_loadaddr, fh->size);
// XXX - how much padding b/n files?: 1024 + remainder??
offset = (current_loadaddr + fh->size) + (1024 - (current_loadaddr + fh->size) % 1024) + 1024;
current_loadaddr += offset;
fh->map = r_core_file_get_next_map (r, fh, mode, current_loadaddr);
if (!fh->map) {
r_core_file_free(fh);
if (!strcmp (suppress_warning, "false"))
eprintf("Unable to load file due to failed mapping.\n");
continue;
}
current_loadaddr = fh->map->to;
if (!top_file) {
top_file = fh;
// check load addr to make sure its still valid
loadaddr = fh && fh->map ? fh->map->from: loadaddr;
}
r_list_append (r->files, fh);
}
if (!top_file) return top_file;
@ -331,8 +409,9 @@ R_API RCoreFile *r_core_file_open_many(RCore *r, const char *file, int mode, ut6
r_config_set (r->config, "file.path", top_file->filename);
r_config_set_i (r->config, "zoom.to", loadaddr+top_file->size);
if (loadmethod) r_config_set (r->config, "file.loadmethod", loadmethod);
free (loadmethod);
r_core_block_read (r, 0);
return top_file;
}
@ -340,6 +419,8 @@ R_API RCoreFile *r_core_file_open(RCore *r, const char *file, int mode, ut64 loa
const char *cp;
RCoreFile *fh;
RIODesc *fd;
char *suppress_warning = r_config_get (r->config, "file.suppress_warnings");
if (!strcmp (file, "-")) {
file = "malloc://512";
mode = 4|2;
@ -370,19 +451,26 @@ R_API RCoreFile *r_core_file_open(RCore *r, const char *file, int mode, ut64 loa
fh->size = r_io_desc_size (r->io, fd);
fh->filename = strdup (fd->name);
fh->rwx = mode;
r->file = fh;
r->io->plugin = fd->plugin;
fh->size = r_io_size (r->io);
r_list_append (r->files, fh);
cp = r_config_get (r->config, "cmd.open");
if (cp && *cp)
r_core_cmd (r, cp, 0);
r_config_set (r->config, "file.path", file);
r_config_set_i (r->config, "zoom.to", loadaddr+fh->size);
fh->map = r_io_map_add (r->io, fh->fd->fd, mode, 0, loadaddr, fh->size);
fh->map = r_core_file_get_next_map (r, fh, mode, loadaddr);
if (!fh->map) {
r_core_file_free(fh);
if (!strcmp (suppress_warning, "false"))
eprintf("Unable to load file due to failed mapping.\n");
return NULL;
}
// check load addr to make sure its still valid
r_list_append (r->files, fh);
r->file = fh;
r->io->plugin = fd->plugin;
r_core_block_read (r, 0);
loadaddr = fh && fh->map ? fh->map->from: loadaddr;
r_config_set_i (r->config, "zoom.to", loadaddr+fh->size);
return fh;
}

View File

@ -259,6 +259,7 @@ R_API int r_io_accept(RIO *io, int fd);
R_API int r_io_shift(RIO *io, ut64 start, ut64 end, st64 move);
R_API int r_io_create (RIO *io, const char *file, int mode, int type);
R_API int r_io_bind(RIO *io, RIOBind *bnd);
R_API void r_io_sort_maps (RIO *io);
/* io/cache.c */
R_API int r_io_cache_invalidate(RIO *io, ut64 from, ut64 to);
@ -281,6 +282,10 @@ R_API int r_io_map(RIO *io, const char *file, ut64 offset);
R_API ut64 r_io_map_select(RIO *io, ut64 off);
//R_API int r_io_map_read_rest(RIO *io, ut64 off, ut8 *buf, ut64 len);
R_API RIOMap *r_io_map_resolve(RIO *io, int fd);
R_API int r_io_map_sort (void *a, void *b);
R_API RIOMap * r_io_map_add_next_available (RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size, ut64 align);
R_API RIOMap * r_io_map_new(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size);
R_API RList * r_io_get_maps_in_range (RIO *io, ut64 addr, ut64 endaddr);
/* io/section.c */
R_API void r_io_section_init(RIO *io);

View File

@ -15,14 +15,14 @@ R_API void r_io_desc_fini(RIO *io) {
R_API ut64 r_io_desc_size(RIO *io, RIODesc *desc){
RIODesc *old = NULL;
ut64 sz = -1;
if (desc && io->fd != desc){
old = io->fd;
r_io_set_fd(io, desc);
}
if (desc) sz = r_io_size(io);
if(old){
r_io_set_fd(io, old);
}
@ -50,7 +50,7 @@ R_API RIODesc *r_io_desc_new(RIOPlugin *plugin, int fd, const char *name, int fl
desc->fd = ((int) ((size_t) desc) & 0xffffff);
desc->fd = p[0];
for (i=1; i<sizeof (desc->fd); i++)
desc->fd ^= p[i];
desc->fd ^= p[i];
} else desc->fd = fd;
desc->data = data;
return desc;

View File

@ -116,8 +116,9 @@ static inline RIODesc *__getioplugin(RIO *io, const char *_uri, int flags, int m
r_io_desc_add (io, desc);
if (desc->fd != -1)
r_io_plugin_open (io, desc->fd, plugin);
if (desc != io->fd)
iop = plugin;
if (desc != io->fd) {
r_io_set_fd (io, desc);
}
}
}
break;
@ -225,7 +226,7 @@ R_API int r_io_set_fd(RIO *io, RIODesc *fd) {
}
R_API int r_io_set_fdn(RIO *io, int fd) {
if (fd != -1 && io->fd != NULL && fd != io->fd->fd) {
if (fd != -1 && io->fd && fd != io->fd->fd) {
RIODesc *desc = r_io_desc_get (io, fd);
if (!desc)
return R_FALSE;
@ -562,3 +563,8 @@ R_API int r_io_create (RIO *io, const char *file, int mode, int type) {
return r_sys_mkdir (file);
return r_sandbox_creat (file, mode)? R_FALSE: R_TRUE;
}
R_API void r_io_sort_maps (RIO *io) {
r_list_sort (io->maps, (RListComparator) r_io_map_sort);
}

View File

@ -6,10 +6,34 @@
#include <r_io.h>
#include <r_list.h>
R_API RIOMap * r_io_map_new(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size) {
RIOMap *map = R_NEW (RIOMap);
if (!map) return NULL;
map->fd = fd;
map->flags = flags;
map->delta = delta;
map->from = addr;
map->to = addr + size;
r_list_append (io->maps, map);
return map;
}
R_API void r_io_map_init(RIO *io) {
io->maps = r_list_new ();
}
R_API int r_io_map_sort(void *_a, void *_b) {
RIOMap *a = _a, *b = _b;
if (a->from == b->from ){
ut64 a_sz = a->to - a->from,
b_sz = b->to - b->from;
return a_sz < b_sz;
}
return a->from < b->from;
}
R_API RIOMap *r_io_map_get(RIO *io, ut64 addr) {
RIOMap *map;
RListIter *iter;
@ -30,6 +54,19 @@ R_API RIOMap *r_io_map_resolve(RIO *io, int fd) {
return NULL;
}
R_API RList *r_io_get_maps_in_range(RIO *io, ut64 addr, ut64 endaddr) {
RIOMap *map;
RListIter *iter;
RList *maps = r_list_new ();
r_list_foreach (io->maps, iter, map) {
if (map->from <= addr && addr < map->to) r_list_append(maps, map);
//if (map->from == addr && endaddr == map->to) r_list_append(maps, map);
if (map->from < endaddr && endaddr < map->to) r_list_append(maps, map);
if (addr <= map->from && map->to <= endaddr) r_list_append(maps, map);
}
return maps;
}
R_API int r_io_map_del(RIO *io, int fd) {
RIOMap *map;
RListIter *iter;
@ -58,7 +95,7 @@ R_API int r_io_map_del_at(RIO *io, ut64 addr) {
RIOMap *map;
RListIter *iter;
r_list_foreach (io->maps, iter, map) {
if (map->from == addr) {
if (map->from <= addr && addr < map->to) {
r_list_delete (io->maps, iter);
return R_TRUE;
}
@ -66,23 +103,52 @@ R_API int r_io_map_del_at(RIO *io, ut64 addr) {
return R_FALSE;
}
R_API RIOMap *r_io_map_add_next_available(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size, ut64 load_align) {
RIOMap *map;
RListIter *iter;
ut64 next_addr = addr,
end_addr = next_addr + size;
r_list_foreach (io->maps, iter, map) {
// XXX - This does not handle when file overflow 0xFFFFFFFF000 -> 0x00000FFF
if ((map->from <= next_addr && next_addr < map->to) ||
(map->from <= end_addr && end_addr < map->to) ) {
//return r_io_map_add(io, fd, flags, delta, map->to, size);
next_addr = map->to + (load_align - (map->to % load_align));
return r_io_map_add_next_available(io, fd, flags, delta, next_addr, size, load_align);
}
}
return r_io_map_new (io, fd, flags, delta, next_addr, size);
}
R_API RIOMap *r_io_map_add(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size) {
RIOMap *map;
RListIter *iter;
ut64 end_addr = addr + size;
r_list_foreach (io->maps, iter, map) {
// cannot map two files on the same address
if (map->from == addr)
// XXX - This does not handle when file overflow 0xFFFFFFFF000 -> 0x00000000
if ((map->from <= addr && addr < map->to) ||
(map->from <= end_addr && end_addr < map->to) )
//return r_io_map_add(io, fd, flags, delta, map->to, size);
return NULL;
}
map = R_NEW (RIOMap);
if (!map) return NULL;
map->fd = fd;
map->flags = flags;
map->delta = delta;
map->from = addr;
map->to = addr + size;
r_list_append (io->maps, map);
return map;
return r_io_map_new (io, fd, flags, delta, addr, size);
}
R_API ut64 r_io_map_select_current_fd(RIO *io, ut64 addr) {
RIOMap *im = NULL, *map = NULL;
RListIter *iter;
r_list_foreach (io->maps, iter, im) {
if (map && map->fd == io->fd->fd) {
map = im;
break;
}
}
if (map) {
return r_io_seek (io, addr, R_IO_SEEK_SET);
}
return -1;
}
R_API ut64 r_io_map_select(RIO *io, ut64 off) {

View File

@ -262,10 +262,9 @@ static RList *r_io_zip_open_many(RIO *io, const char *file, int rw, int mode) {
char *filename_in_zipfile, *zip_filename = NULL, *zip_uri;
if (!r_io_zip_plugin_open (io, file, 1))
return list_fds;
return NULL;
list_fds = r_list_new ();
zip_uri = strdup (file);
// 1) Tokenize to the '//' and find the base file directory ('/')
zip_filename = strstr(zip_uri, "//");