Fixes a memory corruption bug resulting from improper parsing

and accessing of array parameters in OSDI models
This commit is contained in:
lorenzo 2025-12-20 11:31:24 +01:00 committed by Holger Vogt
parent d610fa070a
commit a984a43b61
3 changed files with 21 additions and 8 deletions

View File

@ -27,7 +27,7 @@ static int osdi_param_access(OsdiParamOpvar *param_info, bool write_value,
len = sizeof(double); len = sizeof(double);
if (param_info->len) { if (param_info->len) {
len *= param_info->len; len *= param_info->len;
val_ptr = &value->v.vec.rVec; val_ptr = value->v.vec.rVec;
} else { } else {
val_ptr = &value->rValue; val_ptr = &value->rValue;
} }
@ -36,7 +36,7 @@ static int osdi_param_access(OsdiParamOpvar *param_info, bool write_value,
len = sizeof(int); len = sizeof(int);
if (param_info->len) { if (param_info->len) {
len *= param_info->len; len *= param_info->len;
val_ptr = &value->v.vec.iVec; val_ptr = value->v.vec.iVec;
} else { } else {
val_ptr = &value->iValue; val_ptr = &value->iValue;
} }
@ -45,7 +45,7 @@ static int osdi_param_access(OsdiParamOpvar *param_info, bool write_value,
len = sizeof(char *); len = sizeof(char *);
if (param_info->len) { if (param_info->len) {
len *= param_info->len; len *= param_info->len;
val_ptr = &value->v.vec.cVec; val_ptr = value->v.vec.cVec;
} else { } else {
val_ptr = &value->cValue; 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, static int osdi_write_param(void *dst, IFvalue *value, int param,
const OsdiDescriptor *descr) { 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); 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, static int osdi_read_param(void *src, IFvalue *value, int id,
const OsdiDescriptor *descr) { const OsdiDescriptor *descr) {
if (src == NULL) { if (src == NULL || value == NULL) {
return (E_PANIC); return (E_PANIC);
} }

View File

@ -583,10 +583,10 @@ static int osdi_add_device(int n, OsdiRegistryEntry *devs) {
DEVicesfl = TREALLOC(int, DEVicesfl, dnum); DEVicesfl = TREALLOC(int, DEVicesfl, dnum);
#endif #endif
for (i = 0; i < n; i++) { 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]); DEVices[DEVNUM + i] = osdi_create_spicedev(&devs[i]);
#ifdef TRACE
printf("Added device: %s\n", DEVices[DEVNUM + i]->DEVpublic.name);
#endif
} }
DEVNUM += n; DEVNUM += n;
relink(); relink();

View File

@ -117,9 +117,11 @@ create_model(CKTcircuit *ckt, INPmodel *modtmp, INPtables *tab)
#ifdef OSDI #ifdef OSDI
/* osdi models don't accept their device type as an argument */ /* osdi models don't accept their device type as an argument */
bool is_osdi = false;
if (device->registry_entry){ if (device->registry_entry){
INPgetNetTok(&line, &parm, 1); /* throw away osdi */ INPgetNetTok(&line, &parm, 1); /* throw away osdi */
tfree(parm); tfree(parm);
is_osdi = true;
} }
#endif #endif
@ -133,6 +135,15 @@ create_model(CKTcircuit *ckt, INPmodel *modtmp, INPtables *tab)
IFparm *p = find_model_parameter(parm, device); IFparm *p = find_model_parameter(parm, device);
if (p) { 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); IFvalue *val = INPgetValue(ckt, &line, p->dataType, tab);
error = ft_sim->setModelParm(ckt, modtmp->INPmodfast, p->id, val, NULL); error = ft_sim->setModelParm(ckt, modtmp->INPmodfast, p->id, val, NULL);
if (error) if (error)