Ошибка при работе с памятью - mremap_chunk: утверждение - PullRequest
1 голос
/ 24 октября 2011

Вроде как мой предыдущий пост, но проблема здесь в другом ..

Это структура C для задачи -

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; 

Значения предоставляются для структуры содержимого во время выполнения следующим образом -

  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;

Теперь есть функция, которая использует значение ключа аутентификации.

Соответствующая часть функции -

    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);

Теперь, когда я попытался запустить следующую программу, получаю эту ошибку, о которой я понятия не имею.

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

Я думаю, что может быть ошибка в функциональной части, но что именно, я не уверен, потому что, когда я комментирую отмеченную строку (упомянутую выше), akeylen является нулевым поэтому, взяв это значение fakekey, программа работает нормально.

Редактировать 1:

Я отредактировал код в трех местах (также отредактированный в приведенном выше коде).

Теперь программа работает, но возникают противоречивые результаты.

Ввод:

 Encryption key - qwerty

 Authentication key - abcdef

Выход:

  Encryption key - qwerab

  Authentication key - abcdef

Ситуация стала более ясной.

Проблема, с которой это связано, наверняка есть в realloc заявлениях.

Пожалуйста, предложите это.

Изначально я добавил длину в оба оператора realloc, но теперь я изменил его на priv->keylen на первом месте и priv->keylen+priv->akeylen на втором месте.

Но что-то еще нужно улучшить

Почему это перезаписывает ???

Ответы [ 2 ]

1 голос
/ 24 октября 2011

Поскольку ключ hack структуры [0], похоже, содержит пространство для обоих ключей, вам необходимо также выделить память для обоих ключей.В обоих случаях ('k' и 'K')

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

При объединении двух ключей проще всего преобразовать ключ u_int32_t в символьный указатель и выполнить арифметическое с ним:

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

[и аналогично для memmove ()] Остальные преобразования в вашей программе можно удалить.

0 голосов
/ 24 октября 2011

Если вы получаете ошибки подтверждения от в пределах malloc, проблема не устранена.Утверждение не о параметрах, переданных в malloc, а о состоянии памяти, которая повреждена.Это означает, что вы ранее писали в область памяти, которую не должны были писать.Таким образом, даже если вы предоставили правильную трассировку (например, используя gdb), это не указало бы на источник проблемы.Существует ряд инструментов для устранения проблем с памятью.Одним из наиболее широко используемых инструментов является valgrind.Это сделает вашу программу ужасно медленной и покажет вам массу возможных проблем, просматривая каждый доступ к памяти.Другим более легким инструментом является брызговик, с которым нужно связываться.Очень простой подход к сужению проблемы заключается в добавлении операторов assert(condition) в ваш код и надежде, что вы потерпите неудачу раньше.Иногда вы можете решить эту проблему, просматривая каждый доступ к памяти в вашем коде и следя за тем, чтобы он не выходил за пределы (или, если вы не уверены, добавьте утверждение утверждения).

...