mirror of
https://github.com/shchmue/Lockpick_RCM.git
synced 2024-11-27 16:34:17 +01:00
nx_savedata: Ensure heap safety
This commit is contained in:
parent
1b5a7bb302
commit
1e87828db4
@ -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;
|
||||||
@ -177,7 +182,7 @@ bool save_process(save_ctx_t *ctx) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize meta remap storage. */
|
/* Initialize meta remap storage. */
|
||||||
substorage_init(&ctx->meta_remap_storage.base_storage, &hierarchical_duplex_storage_vt, &ctx->duplex_storage, 0, ctx->duplex_storage.data_layer->_length);
|
substorage_init(&ctx->meta_remap_storage.base_storage, &hierarchical_duplex_storage_vt, &ctx->duplex_storage, 0, ctx->duplex_storage.data_layer->_length);
|
||||||
ctx->meta_remap_storage.map_entries = calloc(1, sizeof(remap_entry_ctx_t) * ctx->meta_remap_storage.header->map_entry_count);
|
ctx->meta_remap_storage.map_entries = calloc(1, sizeof(remap_entry_ctx_t) * ctx->meta_remap_storage.header->map_entry_count);
|
||||||
if (substorage_read(&ctx->base_storage, remap_buffer, ctx->header.layout.meta_map_entry_offset, meta_remap_entry_size) != meta_remap_entry_size) {
|
if (substorage_read(&ctx->base_storage, remap_buffer, ctx->header.layout.meta_map_entry_offset, meta_remap_entry_size) != meta_remap_entry_size) {
|
||||||
@ -232,37 +237,65 @@ bool save_process(save_ctx_t *ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void save_free_contexts(save_ctx_t *ctx) {
|
void save_free_contexts(save_ctx_t *ctx) {
|
||||||
for (unsigned int i = 0; i < ctx->data_remap_storage.header->map_segment_count; i++) {
|
if (ctx->data_remap_storage.header) {
|
||||||
free(ctx->data_remap_storage.segments[i].entries);
|
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);
|
if (ctx->data_remap_storage.segments)
|
||||||
for (unsigned int i = 0; i < ctx->meta_remap_storage.header->map_segment_count; i++) {
|
free(ctx->data_remap_storage.segments);
|
||||||
free(ctx->meta_remap_storage.segments[i].entries);
|
|
||||||
|
if (ctx->meta_remap_storage.header) {
|
||||||
|
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);
|
if (ctx->meta_remap_storage.segments)
|
||||||
free(ctx->data_remap_storage.map_entries);
|
free(ctx->meta_remap_storage.segments);
|
||||||
free(ctx->meta_remap_storage.map_entries);
|
|
||||||
|
if (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);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 2; i++) {
|
for (unsigned int i = 0; i < 2; i++) {
|
||||||
free(ctx->duplex_storage.layers[i].bitmap.bitmap);
|
if (ctx->duplex_storage.layers[i].bitmap.bitmap)
|
||||||
free(ctx->duplex_storage.layers[i].data_a.base_storage.ctx);
|
free(ctx->duplex_storage.layers[i].bitmap.bitmap);
|
||||||
free(ctx->duplex_storage.layers[i].data_b.base_storage.ctx);
|
if (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[1].bitmap_storage.base_storage.ctx);
|
if (ctx->duplex_storage.layers[1].bitmap_storage.base_storage.ctx)
|
||||||
free(ctx->journal_storage.map.map_storage);
|
free(ctx->duplex_storage.layers[1].bitmap_storage.base_storage.ctx);
|
||||||
free(ctx->journal_storage.map.entries);
|
|
||||||
|
if (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);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 4; i++) {
|
for (unsigned int i = 0; i < 4; i++) {
|
||||||
free(ctx->core_data_ivfc_storage.integrity_storages[i].block_validities);
|
if (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]);
|
||||||
}
|
}
|
||||||
free(ctx->core_data_ivfc_storage.level_validities);
|
if (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++) {
|
||||||
free(ctx->fat_ivfc_storage.integrity_storages[i].block_validities);
|
if (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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(ctx->fat_ivfc_storage.level_validities);
|
if (ctx->fat_ivfc_storage.level_validities)
|
||||||
free(ctx->fat_storage);
|
free(ctx->fat_ivfc_storage.level_validities);
|
||||||
|
|
||||||
|
if (ctx->fat_storage)
|
||||||
|
free(ctx->fat_storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_flush(save_ctx_t *ctx) {
|
static ALWAYS_INLINE bool save_flush(save_ctx_t *ctx) {
|
||||||
|
@ -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 New Issue
Block a user