Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix command injection due to legacy code #4733

Merged
merged 2 commits into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 88 additions & 64 deletions librz/bin/p/bin_pebble.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,71 +11,96 @@
#define APP_NAME_BYTES 32
#define COMPANY_NAME_BYTES 32

RZ_PACKED(
typedef struct {
ut8 major; //!< "compatibility" version number
ut8 minor;
})
Version;

RZ_PACKED(
typedef struct {
char header[8]; //!< Sentinel value, should always be 'PBLAPP\0\0'
Version struct_version; //!< version of this structure's format
Version sdk_version; //!< version of the SDK used to build this app
Version app_version; //!< version of the app
ut16 size; //!< size of the app binary, including this metadata but not the reloc table
ut32 offset; //!< The entry point of this executable
ut32 crc; //!< CRC of the app data only, ie, not including this struct or the reloc table at the end
char name[APP_NAME_BYTES]; //!< Name to display on the menu
char company[COMPANY_NAME_BYTES]; //!< Name of the maker of this app
ut32 icon_resource_id; //!< Resource ID within this app's bank to use as a 32x32 icon
ut32 sym_table_addr; //!< The system will poke the sdk's symbol table address into this field on load
ut32 flags; //!< Bitwise OR of PebbleAppFlags
ut32 reloc_list_start; //!< The offset of the address relocation list
ut32 num_reloc_entries; //!< The number of entries in the address relocation list
ut8 uuid[16];
})
PebbleAppInfo;

static bool check_buffer(RzBuffer *b) {
#define pebble_get_pai(bf) ((PebbleAppInfo *)bf->o->bin_obj)

typedef struct {
ut8 major; //!< "compatibility" version number
ut8 minor;
} Version;

typedef struct {
char header[8]; //!< Sentinel value, should always be 'PBLAPP\0\0'
Version struct_version; //!< version of this structure's format
Version sdk_version; //!< version of the SDK used to build this app
Version app_version; //!< version of the app
ut16 size; //!< size of the app binary, including this metadata but not the reloc table
ut32 offset; //!< The entry point of this executable
ut32 crc; //!< CRC of the app data only, ie, not including this struct or the reloc table at the end
char name[APP_NAME_BYTES]; //!< Name to display on the menu
char company[COMPANY_NAME_BYTES]; //!< Name of the maker of this app
ut32 icon_resource_id; //!< Resource ID within this app's bank to use as a 32x32 icon
ut32 sym_table_addr; //!< The system will poke the sdk's symbol table address into this field on load
ut32 flags; //!< Bitwise OR of PebbleAppFlags
ut32 reloc_list_start; //!< The offset of the address relocation list
ut32 num_reloc_entries; //!< The number of entries in the address relocation list
ut8 uuid[16];
} PebbleAppInfo;

static bool pebble_check_buffer(RzBuffer *b) {
ut8 magic[8];
if (rz_buf_read_at(b, 0, magic, sizeof(magic)) != sizeof(magic)) {
return false;
}
return !memcmp(magic, "PBLAPP\x00\x00", 8);
}

static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *b, Sdb *sdb) {
return check_buffer(b);
static inline bool parse_pebble_version(RzBuffer *buf, ut64 *offset, Version *v) {
return rz_buf_read8_offset(buf, offset, &v->major) &&
rz_buf_read8_offset(buf, offset, &v->minor);
}

static ut64 baddr(RzBinFile *bf) {
return 0LL;
static bool parse_pebble_app_info(RzBuffer *buf, PebbleAppInfo *pai) {
ut64 offset = 0;
return rz_buf_read_offset(buf, &offset, (ut8 *)pai->header, sizeof(pai->header)) &&
parse_pebble_version(buf, &offset, &pai->struct_version) &&
parse_pebble_version(buf, &offset, &pai->sdk_version) &&
parse_pebble_version(buf, &offset, &pai->app_version) &&
rz_buf_read_le16_offset(buf, &offset, &pai->size) &&
rz_buf_read_le32_offset(buf, &offset, &pai->offset) &&
rz_buf_read_le32_offset(buf, &offset, &pai->crc) &&
rz_buf_read_offset(buf, &offset, (ut8 *)pai->name, sizeof(pai->name)) &&
rz_buf_read_offset(buf, &offset, (ut8 *)pai->company, sizeof(pai->company)) &&
rz_buf_read_le32_offset(buf, &offset, &pai->icon_resource_id) &&
rz_buf_read_le32_offset(buf, &offset, &pai->sym_table_addr) &&
rz_buf_read_le32_offset(buf, &offset, &pai->flags) &&
rz_buf_read_le32_offset(buf, &offset, &pai->reloc_list_start) &&
rz_buf_read_le32_offset(buf, &offset, &pai->num_reloc_entries) &&
rz_buf_read_offset(buf, &offset, (ut8 *)pai->uuid, sizeof(pai->uuid));
}

/* accelerate binary load */
static RzPVector /*<RzBinString *>*/ *strings(RzBinFile *bf) {
return NULL;
static bool pebble_load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *b, Sdb *sdb) {
PebbleAppInfo *pai = RZ_NEW0(PebbleAppInfo);
if (!pai ||
!parse_pebble_app_info(b, pai)) {
free(pai);
rz_warn_if_reached();
return false;
}
obj->bin_obj = pai;
return true;
}

static RzBinInfo *info(RzBinFile *bf) {
static ut64 pebble_baddr(RzBinFile *bf) {
return 0LL;
}

static RzBinInfo *pebble_info(RzBinFile *bf) {
RzBinInfo *ret = NULL;
PebbleAppInfo pai;
memset(&pai, 0, sizeof(pai));
int reat = rz_buf_read_at(bf->buf, 0, (ut8 *)&pai, sizeof(pai));
if (reat != sizeof(pai)) {
RZ_LOG_ERROR("Truncated Header\n");
PebbleAppInfo *pai = pebble_get_pai(bf);
if (!pai) {
RZ_LOG_ERROR("Invalid PebbleAppInfo header\n");
return NULL;
}
if (!(ret = RZ_NEW0(RzBinInfo))) {
RZ_LOG_ERROR("Failed to allocate Pebble RzBinInfo\n");
return NULL;
}

ret->lang = NULL;
ret->file = rz_str_dup(bf->file);
ret->type = rz_str_dup("pebble");
ret->bclass = rz_str_ndup(pai.name, 32);
ret->rclass = rz_str_ndup(pai.company, 32);
ret->bclass = rz_str_ndup(pai->name, sizeof(pai->name));
ret->rclass = rz_str_ndup(pai->company, sizeof(pai->company));
ret->os = rz_str_dup("rtos");
ret->subsystem = rz_str_dup("pebble");
ret->machine = rz_str_dup("watch");
Expand All @@ -87,15 +112,16 @@ static RzBinInfo *info(RzBinFile *bf) {
return ret;
}

static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
static RzPVector /*<RzBinSection *>*/ *pebble_sections(RzBinFile *bf) {
ut64 textsize = UT64_MAX;
RzPVector *ret = NULL;
RzBinSection *ptr = NULL;
PebbleAppInfo pai = { { 0 } };
if (!rz_buf_read_at(bf->buf, 0, (ut8 *)&pai, sizeof(pai))) {
RZ_LOG_ERROR("Truncated Header\n");
PebbleAppInfo *pai = pebble_get_pai(bf);
if (!pai) {
RZ_LOG_ERROR("Invalid PebbleAppInfo header\n");
return NULL;
}

if (!(ret = rz_pvector_new(free))) {
return NULL;
}
Expand All @@ -104,8 +130,8 @@ static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
return ret;
}
ptr->name = rz_str_dup("relocs");
ptr->vsize = ptr->size = pai.num_reloc_entries * sizeof(ut32);
ptr->vaddr = ptr->paddr = pai.reloc_list_start;
ptr->vsize = ptr->size = ((ut64)pai->num_reloc_entries) * sizeof(ut32);
ptr->vaddr = ptr->paddr = pai->reloc_list_start;
ptr->perm = RZ_PERM_RW;
rz_pvector_push(ret, ptr);
if (ptr->vaddr < textsize) {
Expand All @@ -118,7 +144,7 @@ static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
}
ptr->name = rz_str_dup("symtab");
ptr->vsize = ptr->size = 0;
ptr->vaddr = ptr->paddr = pai.sym_table_addr;
ptr->vaddr = ptr->paddr = pai->sym_table_addr;
ptr->perm = RZ_PERM_R;
rz_pvector_push(ret, ptr);
if (ptr->vaddr < textsize) {
Expand Down Expand Up @@ -146,22 +172,22 @@ static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
return ret;
}

static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
static RzPVector /*<RzBinAddr *>*/ *pebble_entries(RzBinFile *bf) {
RzBinAddr *ptr = NULL;
RzPVector *ret;
PebbleAppInfo pai;
if (!rz_buf_read_at(bf->buf, 0, (ut8 *)&pai, sizeof(pai))) {
RZ_LOG_ERROR("Truncated Header\n");
PebbleAppInfo *pai = pebble_get_pai(bf);
if (!pai) {
RZ_LOG_ERROR("Invalid PebbleAppInfo header\n");
return NULL;
}

if (!(ret = rz_pvector_new(free))) {
return NULL;
}
if (!(ptr = RZ_NEW0(RzBinAddr))) {
return ret;
}
ptr->paddr = pai.offset;
ptr->vaddr = pai.offset;
ptr->paddr = ptr->vaddr = pai->offset;
rz_pvector_push(ret, ptr);
return ret;
}
Expand All @@ -170,15 +196,13 @@ RzBinPlugin rz_bin_plugin_pebble = {
.name = "pebble",
.desc = "Pebble Watch App",
.license = "LGPL",
.load_buffer = &load_buffer,
.check_buffer = &check_buffer,
.baddr = &baddr,
.entries = entries,
.load_buffer = &pebble_load_buffer,
.check_buffer = &pebble_check_buffer,
.baddr = &pebble_baddr,
.entries = pebble_entries,
.maps = &rz_bin_maps_of_file_sections,
.sections = sections,
.strings = &strings,
.info = &info,
//.relocs = &relocs
.sections = pebble_sections,
.info = &pebble_info,
};

#ifndef RZ_PLUGIN_INCORE
Expand Down
4 changes: 0 additions & 4 deletions librz/main/rizin.c
Original file line number Diff line number Diff line change
Expand Up @@ -1272,10 +1272,6 @@ RZ_API int rz_main_rizin(int argc, const char **argv) {
ret = 1;
goto beach;
}
if (r->bin->cur && r->bin->cur->o && r->bin->cur->o->info && r->bin->cur->o->info->rclass && !strcmp("fs", r->bin->cur->o->info->rclass)) {
const char *fstype = r->bin->cur->o->info->bclass;
rz_core_cmdf(r, "m /root %s @ 0", fstype);
}
// initalize io subsystem
char *res = rz_io_system(r->io, NULL);
if (res) {
Expand Down
Loading