rwth-irt / FmiWrapper

Simplified C-Interface for fmi2 models. Includes .net wrapper.
MIT License
18 stars 11 forks source link

Sanity check of the component_environment pointer #9

Open Nils12345678901234567 opened 1 month ago

Nils12345678901234567 commented 1 month ago

There is a risk that an invalid pointer is passed as component_environment. This is the case with the current release of https://github.com/NTNU-IHB/PythonFMU (https://github.com/NTNU-IHB/PythonFMU/pull/212)

I could be useful to add a magic number to the wrapped_fmu struct and check the validity of the pointer passed as fmi2ComponentEnvironment:

In fmi_wrapper.c add a new member to the start of the struct (Note: all code the uses the struct must be recompiled):

#define WRAPPED_FMU_MAGIC 0xDEADBEEF

struct wrapped_fmu
{
    // Magic number to check if pointers passed to this library are valid. Shall always be WRAPPED_FMU_MAGIC
    unsigned int magic; 
...

Initialize the value in `create_wrapper':

/*! 
Load the functions from the binary into a wrapper struct.
This is typically the first function you would want to call.
*/
wrapped_fmu *create_wrapper(const char *file_name, log_t log_callback, step_finished_t step_finished_callback)
{
    // Create the wrapper struct
    wrapped_fmu *wrapper = malloc(sizeof(wrapped_fmu));
    wrapper->magic = WRAPPED_FMU_MAGIC;

...

Check the magic number before acessing the pointer:

/*!
Implementation of the logger callback that is passed to the fmu.
This function calls the logCallback of the wrapper.
*/
static void fmuLogCallback(fmi2ComponentEnvironment component_environment, fmi2String instance_name, fmi2Status status, fmi2String category, fmi2String message, ...)
{
    wrapped_fmu *wrapper = (wrapped_fmu*)component_environment;
    if (wrapper->magic != WRAPPED_FMU_MAGIC)
    {
        printf("ERROR: Invalid fmi2ComponentEnvironment\n");
        return;
    }

...
Tuebel commented 1 month ago

Thanks for the heads-up. I do not think that I entirely understand this issue: In the case of PythonFMU, they passed either a pointer to an object of a different type or a nullptr. In this case, the application would also crash when checking for the magic number.

Could you please explain, maybe give an example, in which cases you expect issues?