From aee73a902397438f6091db14087b039684b42874 Mon Sep 17 00:00:00 2001 From: Saran Tunyasuvunakool Date: Tue, 9 Aug 2022 00:41:38 -0700 Subject: [PATCH] Fix memory leaks in mj_makeData and mj_makeModel. Currently, if these functions fail to allocate space for the buffer or stack, it will exit without freeing any of the memory successfully allocated so far. PiperOrigin-RevId: 466271030 Change-Id: Id01c115ec976482ac5d28c373b5eb47d77f424be --- src/engine/engine_io.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/engine/engine_io.c b/src/engine/engine_io.c index ee3cb899..c6380960 100644 --- a/src/engine/engine_io.c +++ b/src/engine/engine_io.c @@ -461,8 +461,8 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int njnt, #define X(name) \ if ((m->name) < 0) { \ + mju_free(m); \ mju_warning("Invalid model: negative " #name); \ - mj_deleteModel(m); \ return 0; \ } MJMODEL_INTS; @@ -470,15 +470,15 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int njnt, // nbody should always be positive if (m->nbody == 0) { + mju_free(m); mju_warning("Invalid model: nbody == 0"); - mj_deleteModel(m); return 0; } // nmocap is going to get multiplied by 4, and shouldn't overflow if (m->nmocap >= INT_MAX / 4) { + mju_free(m); mju_warning("Invalid model: nmocap too large"); - mj_deleteModel(m); return 0; } @@ -486,8 +486,8 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int njnt, m->nbuffer = 0; #define X(type, name, nr, nc) \ if (!safeAddToBufferSize(&offset, &m->nbuffer, sizeof(type), m->nr, nc)) { \ + mju_free(m); \ mju_warning("Invalid model: " #name " too large."); \ - mj_deleteModel(m); \ return 0; \ } @@ -497,6 +497,7 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int njnt, // allocate buffer m->buffer = mju_malloc(m->nbuffer); if (!m->buffer) { + mju_free(m); mju_error("Could not allocate mjModel buffer"); } @@ -854,8 +855,8 @@ static mjData* _makeData(const mjModel* m) { d->buffer = d->stack = NULL; #define X(type, name, nr, nc) \ if (!safeAddToBufferSize(&offset, &d->nbuffer, sizeof(type), m->nr, nc)) { \ + mju_free(d); \ mju_warning("Invalid data: " #name " too large."); \ - mj_deleteData(d); \ return 0; \ } @@ -868,12 +869,15 @@ static mjData* _makeData(const mjModel* m) { // allocate buffer d->buffer = mju_malloc(d->nbuffer); if (!d->buffer) { + mju_free(d); mju_error("Could not allocate mjData buffer"); } // allocate stack d->stack = (mjtNum*) mju_malloc(d->nstack * sizeof(mjtNum)); if (!d->stack) { + mju_free(d->buffer); + mju_free(d); mju_error("Could not allocate mjData stack"); }