3

这似乎是我以前的帖子,但这里的问题不同..

这是问题的 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

现在情况更清楚了。

它意味着的问题肯定存在于reallocstatements 中。

请就此提出建议。

最初我在两个realloc语句中都添加了长度,但现在我将其更改为priv->keylen在第一和priv->keylen+priv->akeylen第二位置。

但仍有一些地方需要改进

为什么这是覆盖???

4

2 回答 2

1

由于 key[0] struct hack 似乎包含两个键的空间,因此您也需要为两者分配内存。在这两种情况下('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() 类似] 可以删除程序中的其余演员表。

于 2011-10-24T16:33:42.260 回答
0

如果您从内部 malloc得到断言失败,则问题出在外部。断言不是关于传递给 malloc 的参数,而是关于已损坏的内存状态。这意味着您之前写入了您不应该写入的内存区域。因此,即使您提供了适当的回溯(例如使用 gdb),也不会指出问题的根源。有许多用于调试内存问题的工具。使用最广泛的工具之一是 valgrind。它会让你的程序变得非常慢,并通过查看每一次内存访问来向你展示大量可能的问题。另一个更轻量级的工具是挡泥板,它是用来链接的。缩小问题范围的一个非常基本的方法是添加assert(condition)声明你的代码,并希望你早点失败。有时您可以通过查看代码中的每个内存访问并确保它没有超出范围来解决此问题(或者如果您不确定,请添加断言语句)。

于 2011-10-24T13:48:56.100 回答