From 60fd6a3298d96ac4b67357fcd41840c186fbc5c9 Mon Sep 17 00:00:00 2001 From: Nimrod Gileadi Date: Thu, 12 Oct 2023 09:27:53 -0700 Subject: [PATCH] Check if there's enough data in the buffer before reading fields while loading MJB. Before this change, loading a truncated MJB file would crash with mjERROR. After this change it will just return NULL. PiperOrigin-RevId: 572928724 Change-Id: I9611eaffcc2e5ef1b957f48162ce2ef29619e087 --- src/engine/engine_io.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/engine/engine_io.c b/src/engine/engine_io.c index 4d71584e..3e2a0ba8 100644 --- a/src/engine/engine_io.c +++ b/src/engine/engine_io.c @@ -770,6 +770,11 @@ mjModel* mj_loadModel(const char* filename, const mjVFS* vfs) { } // read mjModel structure: info only + if (ptrbuf + sizeof(int)*getnint() + sizeof(size_t)*getnsize() > buffer_sz) { + mju_closeResource(r); + mju_warning("Truncated model file - ran out of data while reading sizes"); + return NULL; + } bufread(ints, sizeof(int)*getnint(), buffer_sz, buffer, &ptrbuf); bufread(sizes, sizeof(size_t)*getnsize(), buffer_sz, buffer, &ptrbuf); @@ -802,13 +807,26 @@ mjModel* mj_loadModel(const char* filename, const mjVFS* vfs) { } // read options and buffer + if (ptrbuf + sizeof(mjOption) + sizeof(mjVisual) + sizeof(mjStatistic) > buffer_sz) { + mju_closeResource(r); + mju_warning("Truncated model file - ran out of data while reading structs"); + return NULL; + } bufread((void*)&m->opt, sizeof(mjOption), buffer_sz, buffer, &ptrbuf); bufread((void*)&m->vis, sizeof(mjVisual), buffer_sz, buffer, &ptrbuf); bufread((void*)&m->stat, sizeof(mjStatistic), buffer_sz, buffer, &ptrbuf); { MJMODEL_POINTERS_PREAMBLE(m) - #define X(type, name, nr, nc) \ + #define X(type, name, nr, nc) \ + if (ptrbuf + sizeof(type) * (m->nr) * (nc) > buffer_sz) { \ + mju_closeResource(r); \ + mju_warning( \ + "Truncated model file - ran out of data while reading " #name); \ + mj_deleteModel(m); \ + return NULL; \ + } \ bufread(m->name, sizeof(type)*(m->nr)*(nc), buffer_sz, buffer, &ptrbuf); + MJMODEL_POINTERS #undef X }