3

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 ???

Udit Gupta
  • 3,162
  • 11
  • 43
  • 71
  • This is pure speculation, but do you know what `stringargument(arg, &temp)` evaluates to? It looks like your `realloc` call is being promoted to an `mmap` call (or `mremap`) which happens when you request a very large size to be allocated. If by chance your `stringargument` function is returning some garbage value which is way too large, funny things might happen. – tdenniston Oct 24 '11 at 13:49
  • please have a look on my edit – Udit Gupta Oct 24 '11 at 15:09
  • Ok, I see your edit. But you need to clarify what you are seeing now. Do you see the same assertion failure? Or do you not see the assertion, but now you're overwriting some memory? Or have you seen both? – tdenniston Oct 24 '11 at 15:12
  • now no error is there.I have shown input and output above ,Please look at the keys , the encryption key is being overwritten by authentication key – Udit Gupta Oct 24 '11 at 15:16
  • why is the VLA key[0] an uint32_t ? it seems to be used as a character array only. Also, the stringconcatenation that you attempt with "&epriv->key[epriv->keylen/sizeof(u_int32_t)] " will overwrite stuff if keylen is not a multiple of u_int32_t. – wildplasser Oct 24 '11 at 15:24
  • `key[0] must be uint32_t` I can't changed that its mandatory ,actually its just a small part of a large application so can't describe why so ya I can change in `&epriv->key[epriv->keylen/sizeof(u_int32_t)`. please suggest what change I could do here . – Udit Gupta Oct 24 '11 at 15:41

2 Answers2

1

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.

wildplasser
  • 43,142
  • 8
  • 66
  • 109
0

If you get assertion failures from within malloc, the problem is outside. The assertion is not about the parameters passed to malloc, but about the state of the memory, which is corrupted. This means that you previously wrote to a memory area you were not supposed to write. So even if you provided a proper traceback (using gdb for instance), this would not point you to the source of the problem. There are a number of tools for debugging memory problems. One of the most widely used tools is valgrind. It will make your program horribly slow and show you tons of possible problems by looking at every single memory access. Another more lightweight tool is mudflap, which is to be linked against. A very basic approach to narrowing down the problem is to add assert(condition) statements to your code and hope that you fail earlier. Sometimes you can solve this problem by looking at every single memory access in your code and ensure that it is not out of bounds (or if you are unsure, add an assertion statement).

Helmut Grohne
  • 6,578
  • 2
  • 31
  • 67