Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Toolkit object ID and comment retrieval functions are not safe #814

Open
LRossman opened this issue Sep 25, 2024 · 0 comments
Open

Toolkit object ID and comment retrieval functions are not safe #814

LRossman opened this issue Sep 25, 2024 · 0 comments

Comments

@LRossman
Copy link
Collaborator

Toolkit functions such as EN_getnodeid, EN_getlinkid, etc., and EN_getcomment are potentially unsafe because they use strcpy to copy an object's ID or comment into an output string passed into the function. Although the Toolkit documentation states that the output string should be sized by the client to EN_MAXID+1 for ID names (or EN_MAXMSG+1 for comments) there is no way for the retrieval functions to check for this. If an output string is sized smaller than the string being retrieved a buffer overrun will occur and memory in the client's application will get overwritten with the potential to cause serious problems.

A fix for safely retrieving ID names is as follows:

In epanet2_enums.h add the following definition:

typedef char EN_ID[EN_MAXID+1]; 

and add the following new function declaration to epanet2_2.h:

  int  DLLEXPORT EN_getid(EN_Project ph, int object, int index, EN_ID *out_id);

where object can be EN_NODE, EN_LINK, etc. Then the body of EN_getid in epanet.c would look as follows:

int  DLLEXPORT EN_getid(EN_Project p, int object, int index, EN_ID *id)
{
    strcpy(*id, "");
    if (sizeof(*id) != EN_MAXID+1) return 252;  // May not be needed -- compiler will check this
    if (!p->Openflag) return 102;
    if (index < 1 ) return 203;
    switch (object) {
        case EN_NODE:
            if (index > p->network.Nnodes) return 203;
            strcpy(*id, p->network.Node[index].ID);
            break;
        case EN_LINK:  . . .

        default: return 251;
    }
    return 0;
}

A Toolkit client would use the new EN_getid function with code that looks something like:

EN_ID id;
int err, anIndex = . . . ;
. . .
err = EN_getid(p, EN_NODE, anIndex, &id);
printf("ID of Node[%d] is %s", anIndex, id);

A similar approach could be used to either modify the existing EN_getcomment function (breaking backward compatibility) or create a new function named EN_getcomment_s.

I've tested this safe method for retrieving ID names and it seems to work OK. What I'm not sure about is how to modify the various language bindings (epanet2.vb, epanet2.pas, etc.) so that they use the equivalent of EN_ID in their declaration of EN_getid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant