From a984a43b6183aa4465059dfe71c09ead06dc4ae9 Mon Sep 17 00:00:00 2001 From: lorenzo Date: Sat, 20 Dec 2025 11:31:24 +0100 Subject: [PATCH] Fixes a memory corruption bug resulting from improper parsing and accessing of array parameters in OSDI models --- src/osdi/osdiparam.c | 12 +++++++----- src/spicelib/devices/dev.c | 6 +++--- src/spicelib/parser/inpgmod.c | 11 +++++++++++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/osdi/osdiparam.c b/src/osdi/osdiparam.c index f4664629d..a129ea9d0 100644 --- a/src/osdi/osdiparam.c +++ b/src/osdi/osdiparam.c @@ -27,7 +27,7 @@ static int osdi_param_access(OsdiParamOpvar *param_info, bool write_value, len = sizeof(double); if (param_info->len) { len *= param_info->len; - val_ptr = &value->v.vec.rVec; + val_ptr = value->v.vec.rVec; } else { val_ptr = &value->rValue; } @@ -36,7 +36,7 @@ static int osdi_param_access(OsdiParamOpvar *param_info, bool write_value, len = sizeof(int); if (param_info->len) { len *= param_info->len; - val_ptr = &value->v.vec.iVec; + val_ptr = value->v.vec.iVec; } else { val_ptr = &value->iValue; } @@ -45,7 +45,7 @@ static int osdi_param_access(OsdiParamOpvar *param_info, bool write_value, len = sizeof(char *); if (param_info->len) { len *= param_info->len; - val_ptr = &value->v.vec.cVec; + val_ptr = value->v.vec.cVec; } else { val_ptr = &value->cValue; } @@ -64,7 +64,9 @@ static int osdi_param_access(OsdiParamOpvar *param_info, bool write_value, static int osdi_write_param(void *dst, IFvalue *value, int param, const OsdiDescriptor *descr) { - if (dst == NULL) { + // value may be NULL as a result of a bad parse from INPgetValue + // catch it before dereferencing it + if (dst == NULL || value == NULL) { return (E_PANIC); } @@ -127,7 +129,7 @@ extern int OSDImParam(int param, IFvalue *value, GENmodel *modelPtr) { static int osdi_read_param(void *src, IFvalue *value, int id, const OsdiDescriptor *descr) { - if (src == NULL) { + if (src == NULL || value == NULL) { return (E_PANIC); } diff --git a/src/spicelib/devices/dev.c b/src/spicelib/devices/dev.c index 7b5268835..3e07b1beb 100644 --- a/src/spicelib/devices/dev.c +++ b/src/spicelib/devices/dev.c @@ -583,10 +583,10 @@ static int osdi_add_device(int n, OsdiRegistryEntry *devs) { DEVicesfl = TREALLOC(int, DEVicesfl, dnum); #endif for (i = 0; i < n; i++) { -#ifdef TRACE - printf("Added device: %s\n", devs[i]->DEVpublic.name); -#endif DEVices[DEVNUM + i] = osdi_create_spicedev(&devs[i]); +#ifdef TRACE + printf("Added device: %s\n", DEVices[DEVNUM + i]->DEVpublic.name); +#endif } DEVNUM += n; relink(); diff --git a/src/spicelib/parser/inpgmod.c b/src/spicelib/parser/inpgmod.c index 64c402d7e..ac3293b45 100644 --- a/src/spicelib/parser/inpgmod.c +++ b/src/spicelib/parser/inpgmod.c @@ -117,9 +117,11 @@ create_model(CKTcircuit *ckt, INPmodel *modtmp, INPtables *tab) #ifdef OSDI /* osdi models don't accept their device type as an argument */ + bool is_osdi = false; if (device->registry_entry){ INPgetNetTok(&line, &parm, 1); /* throw away osdi */ tfree(parm); + is_osdi = true; } #endif @@ -133,6 +135,15 @@ create_model(CKTcircuit *ckt, INPmodel *modtmp, INPtables *tab) IFparm *p = find_model_parameter(parm, device); if (p) { +#ifdef OSDI + if (is_osdi && (p->dataType & IF_VECTOR)){ + // we need to get rid if the leading [ in order to make sure + // that INPgetValue can parse the value properly + // This is because, unlike other SPICEDev, OSDI models receive + // array params in the syntax (param_name=[...]) + ++line; + } +#endif IFvalue *val = INPgetValue(ckt, &line, p->dataType, tab); error = ft_sim->setModelParm(ckt, modtmp->INPmodfast, p->id, val, NULL); if (error)