nx_savedata: Ensure heap safety
This commit is contained in:
parent
1b5a7bb302
commit
1e87828db4
4 changed files with 59 additions and 28 deletions
|
@ -102,7 +102,7 @@ uint32_t save_remap_storage_read(remap_storage_ctx_t *ctx, void *buffer, uint64_
|
||||||
}
|
}
|
||||||
uint64_t in_pos = offset;
|
uint64_t in_pos = offset;
|
||||||
uint32_t out_pos = 0;
|
uint32_t out_pos = 0;
|
||||||
uint32_t remaining = count;
|
uint32_t remaining = (u32)count;
|
||||||
|
|
||||||
while (remaining) {
|
while (remaining) {
|
||||||
uint64_t entry_pos = in_pos - entry->entry.virtual_offset;
|
uint64_t entry_pos = in_pos - entry->entry.virtual_offset;
|
||||||
|
@ -135,7 +135,7 @@ uint32_t save_remap_storage_write(remap_storage_ctx_t *ctx, const void *buffer,
|
||||||
}
|
}
|
||||||
uint64_t in_pos = offset;
|
uint64_t in_pos = offset;
|
||||||
uint32_t out_pos = 0;
|
uint32_t out_pos = 0;
|
||||||
uint32_t remaining = count;
|
uint32_t remaining = (u32)count;
|
||||||
|
|
||||||
while (remaining) {
|
while (remaining) {
|
||||||
uint64_t entry_pos = in_pos - entry->entry.virtual_offset;
|
uint64_t entry_pos = in_pos - entry->entry.virtual_offset;
|
||||||
|
|
|
@ -143,6 +143,11 @@ bool save_process(save_ctx_t *ctx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->header.layout.version > VERSION_DISF_5) {
|
||||||
|
EPRINTF("Unsupported save version.\nLibrary must be updated.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize remap storages. */
|
/* Initialize remap storages. */
|
||||||
ctx->data_remap_storage.header = &ctx->header.main_remap_header;
|
ctx->data_remap_storage.header = &ctx->header.main_remap_header;
|
||||||
ctx->meta_remap_storage.header = &ctx->header.meta_remap_header;
|
ctx->meta_remap_storage.header = &ctx->header.meta_remap_header;
|
||||||
|
@ -232,36 +237,64 @@ bool save_process(save_ctx_t *ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_free_contexts(save_ctx_t *ctx) {
|
void save_free_contexts(save_ctx_t *ctx) {
|
||||||
|
if (ctx->data_remap_storage.header) {
|
||||||
for (unsigned int i = 0; i < ctx->data_remap_storage.header->map_segment_count; i++) {
|
for (unsigned int i = 0; i < ctx->data_remap_storage.header->map_segment_count; i++) {
|
||||||
|
if (ctx->data_remap_storage.segments && ctx->data_remap_storage.segments[i].entries)
|
||||||
free(ctx->data_remap_storage.segments[i].entries);
|
free(ctx->data_remap_storage.segments[i].entries);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (ctx->data_remap_storage.segments)
|
||||||
free(ctx->data_remap_storage.segments);
|
free(ctx->data_remap_storage.segments);
|
||||||
|
|
||||||
|
if (ctx->meta_remap_storage.header) {
|
||||||
for (unsigned int i = 0; i < ctx->meta_remap_storage.header->map_segment_count; i++) {
|
for (unsigned int i = 0; i < ctx->meta_remap_storage.header->map_segment_count; i++) {
|
||||||
|
if (ctx->meta_remap_storage.segments && ctx->meta_remap_storage.segments[i].entries)
|
||||||
free(ctx->meta_remap_storage.segments[i].entries);
|
free(ctx->meta_remap_storage.segments[i].entries);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (ctx->meta_remap_storage.segments)
|
||||||
free(ctx->meta_remap_storage.segments);
|
free(ctx->meta_remap_storage.segments);
|
||||||
|
|
||||||
|
if (ctx->data_remap_storage.map_entries)
|
||||||
free(ctx->data_remap_storage.map_entries);
|
free(ctx->data_remap_storage.map_entries);
|
||||||
|
if (ctx->meta_remap_storage.map_entries)
|
||||||
free(ctx->meta_remap_storage.map_entries);
|
free(ctx->meta_remap_storage.map_entries);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 2; i++) {
|
for (unsigned int i = 0; i < 2; i++) {
|
||||||
|
if (ctx->duplex_storage.layers[i].bitmap.bitmap)
|
||||||
free(ctx->duplex_storage.layers[i].bitmap.bitmap);
|
free(ctx->duplex_storage.layers[i].bitmap.bitmap);
|
||||||
|
if (ctx->duplex_storage.layers[i].data_a.base_storage.ctx)
|
||||||
free(ctx->duplex_storage.layers[i].data_a.base_storage.ctx);
|
free(ctx->duplex_storage.layers[i].data_a.base_storage.ctx);
|
||||||
|
if (ctx->duplex_storage.layers[i].data_b.base_storage.ctx)
|
||||||
free(ctx->duplex_storage.layers[i].data_b.base_storage.ctx);
|
free(ctx->duplex_storage.layers[i].data_b.base_storage.ctx);
|
||||||
}
|
}
|
||||||
|
if (ctx->duplex_storage.layers[1].bitmap_storage.base_storage.ctx)
|
||||||
free(ctx->duplex_storage.layers[1].bitmap_storage.base_storage.ctx);
|
free(ctx->duplex_storage.layers[1].bitmap_storage.base_storage.ctx);
|
||||||
|
|
||||||
|
if (ctx->journal_storage.map.map_storage)
|
||||||
free(ctx->journal_storage.map.map_storage);
|
free(ctx->journal_storage.map.map_storage);
|
||||||
|
if (ctx->journal_storage.map.entries)
|
||||||
free(ctx->journal_storage.map.entries);
|
free(ctx->journal_storage.map.entries);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 4; i++) {
|
for (unsigned int i = 0; i < 4; i++) {
|
||||||
|
if (ctx->core_data_ivfc_storage.integrity_storages[i].block_validities)
|
||||||
free(ctx->core_data_ivfc_storage.integrity_storages[i].block_validities);
|
free(ctx->core_data_ivfc_storage.integrity_storages[i].block_validities);
|
||||||
save_cached_storage_finalize(&ctx->core_data_ivfc_storage.levels[i + 1]);
|
save_cached_storage_finalize(&ctx->core_data_ivfc_storage.levels[i + 1]);
|
||||||
}
|
}
|
||||||
|
if (ctx->core_data_ivfc_storage.level_validities)
|
||||||
free(ctx->core_data_ivfc_storage.level_validities);
|
free(ctx->core_data_ivfc_storage.level_validities);
|
||||||
|
|
||||||
if (ctx->header.layout.version >= VERSION_DISF_5) {
|
if (ctx->header.layout.version >= VERSION_DISF_5) {
|
||||||
for (unsigned int i = 0; i < 3; i++) {
|
for (unsigned int i = 0; i < 3; i++) {
|
||||||
|
if (ctx->fat_ivfc_storage.integrity_storages[i].block_validities)
|
||||||
free(ctx->fat_ivfc_storage.integrity_storages[i].block_validities);
|
free(ctx->fat_ivfc_storage.integrity_storages[i].block_validities);
|
||||||
save_cached_storage_finalize(&ctx->fat_ivfc_storage.levels[i + 1]);
|
save_cached_storage_finalize(&ctx->fat_ivfc_storage.levels[i + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ctx->fat_ivfc_storage.level_validities)
|
||||||
free(ctx->fat_ivfc_storage.level_validities);
|
free(ctx->fat_ivfc_storage.level_validities);
|
||||||
|
|
||||||
|
if (ctx->fat_storage)
|
||||||
free(ctx->fat_storage);
|
free(ctx->fat_storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,11 +45,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void storage_init(storage *this, const storage_vt *vt, void *ctx) {
|
|
||||||
this->vt = vt;
|
|
||||||
this->ctx = ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void substorage_init(substorage *this, const storage_vt *vt, void *ctx, uint64_t offset, uint64_t length) {
|
void substorage_init(substorage *this, const storage_vt *vt, void *ctx, uint64_t offset, uint64_t length) {
|
||||||
storage_init(&this->base_storage, vt, ctx);
|
storage_init(&this->base_storage, vt, ctx);
|
||||||
this->offset = offset;
|
this->offset = offset;
|
||||||
|
|
|
@ -51,7 +51,10 @@ typedef struct {
|
||||||
void *ctx;
|
void *ctx;
|
||||||
} storage;
|
} storage;
|
||||||
|
|
||||||
void storage_init(storage *this, const storage_vt *vt, void *ctx);
|
static void ALWAYS_INLINE storage_init(storage *this, const storage_vt *vt, void *ctx) {
|
||||||
|
this->vt = vt;
|
||||||
|
this->ctx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
|
|
Loading…
Reference in a new issue