Search code examples
cmemory-managementmemcpymemmove

Error when dealing with memory - mremap_chunk: Assertion


It seems like my previous post but issue here is different ..

This is the C structure for problem -

typedef struct ip_esp_private {         /* keep track of things privately */
u_int32_t type;        
u_int32_t ivlen;       
u_int32_t icvlen;      
u_int32_t keylen;       /* length of "Encryption key */
u_int32_t akeylen;      /*length of authn key */
u_int32_t key[0];       /* encryption key and authentication key both */

} esp_private; 

The values are provided to structure contents at run time as follows -

  case 'k':       /* Key */
            length = stringargument(arg, &temp);
            priv->keylen = length;


            priv = (esp_private *)realloc(priv,
                            sizeof(esp_private)+/*length*/priv->keylen); 
             /*This one is edited */


        //  if(priv->akeylen)       
          //        memmove(&priv->key[priv->keylen],
                 //                    &priv->key[0],priv->akeylen);
   /*These three are commented*/     

       memcpy(&priv->key[0], temp, priv->keylen);
            pack->private = priv;
             pack->modified |= ESP_MOD_KEY;
            break;



    case 'K':       /* Authentication  Key */  
            length = stringargument(arg, &temp);
            priv->akeylen = length; // marked line(explained below)

            priv = (esp_private *)realloc(priv,
                            sizeof(esp_private)+/*length*/priv->keylen+priv->akeylen);
           /*this one edited too */ 


           memcpy(&priv->key[priv->keylen/sizeof(u_int32_t)],
                                             temp,priv->akeylen);
            pack->private = priv;
            pack->modified |= ESP_MOD_KEY;

Now there is a function which uses the value of authentication key.

The relevant part of the function is -

    if (!epriv->akeylen) {
            key = &fakekey;
            keylen = 1;
    } else {
            key = (u_int8_t *)malloc(epriv->akeylen);
            memcpy(key,&epriv->key[epriv->keylen/sizeof(u_int32_t)]
                             ,epriv->akeylen);

Now when I tried to run the following program , getting this error about which I have no idea.

     sendip: malloc.c:3574: mremap_chunk: Assertion `((size + offset)
                                  & (mp_.pagesize-1)) == 0' failed.

I think may be there is a error in function part but what exactly it is I am not sure, because when I comment the marked line (mentioned above) the akeylen is null so taking that fakekey value and program runs fine.

Edit 1:

I have edited the code at three places (also edited in the above code ).

Now program works but an inconsistent output occurs.

Input :

 Encryption key - qwerty

 Authentication key - abcdef

Output:

  Encryption key - qwerab

  Authentication key - abcdef

The situation is more clear now .

The problem it means is surely there at realloc statements .

Please suggest on this.

Initially I added length at both realloc statements but now I changed it to priv->keylen at first place and priv->keylen+priv->akeylen at secone place.

But something still needs to be improved

Why this is overwriting ???


Solution

  • Since the key[0] struct hack appears to contain space for both keys, you'll need to allocate memory for both, too. In both cases ('k' and 'K' )

    priv = realloc(priv, sizeof *priv +priv->keylen+priv->akeylen);
    

    When concatenating the two keys, it is easiest to cast the u_int32_t key into a character pointer and do arithmatic on that one:

    memcpy ( priv->key, source1, sizeofsource1);
    /* and */ 
    memcpy ( ((char*) priv->key) +priv->keylen, source2, sizeofsource2);
    

    [and similar for the memmove()] The rest of the casts in your program can be removed.