Erreur lors de l’utilisation de la mémoire – mremap_chunk: Assertion

Il semble que mon post précédent, mais la question ici est différente ..

C’est la structure C du problème –

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; 

Les valeurs sont fournies pour structurer le contenu au moment de l’exécution comme suit –

  case 'k': /* Key */ length = ssortingngargument(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 = ssortingngargument(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; 

Maintenant, il existe une fonction qui utilise la valeur de la clé d’authentification.

La partie pertinente de la fonction est –

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

Maintenant, quand j’ai essayé d’exécuter le programme suivant, obtenir cette erreur dont je n’ai aucune idée.

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

Je pense qu’il ya peut-être une erreur dans la partie fonction mais je ne suis pas sûr de cela. En effet, lorsque je commente la ligne marquée (mentionnée ci-dessus), la valeur akeylen est nulle.

Modifier 1:

J’ai édité le code à trois endroits (également édité dans le code ci-dessus).

Le programme fonctionne maintenant mais une sortie incohérente se produit.

Consortingbution :

  Encryption key - qwerty Authentication key - abcdef 

Sortie:

  Encryption key - qwerab Authentication key - abcdef 

La situation est plus claire maintenant.

Le problème que cela signifie est sûrement là pour les déclarations de realloc .

S’il vous plaît suggérer à ce sujet.

Au départ, j’avais ajouté des longueurs dans les deux déclarations realloc , mais maintenant j’ai changé en priv->keylen en première place et priv->keylen+priv->akeylen à secone place.

Mais quelque chose doit encore être amélioré

Pourquoi est-ce écraser ???

Étant donné que la clé [0] struct hack semble contenir de l’espace pour les deux clés, vous devrez également allouer de la mémoire pour les deux. Dans les deux cas (‘k’ et ‘K’)

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

Lors de la concaténation des deux clés, il est plus facile de convertir la clé u_int32_t en un pointeur de caractère et de l’arithmatique sur celui-ci:

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

[et similaire pour le memmove ()] Le rest des dissortingbutions de votre programme peut être supprimé.

Si vous obtenez des échecs d’affirmation de malloc , le problème est extérieur. L’assertion ne concerne pas les parameters transmis à malloc, mais l’état de la mémoire, qui est corrompue. Cela signifie que vous avez précédemment écrit dans une zone mémoire que vous n’étiez pas censé écrire. Ainsi, même si vous fournissiez une trace appropriée (en utilisant gdb par exemple), cela ne vous indiquerait pas la source du problème. Il existe un certain nombre d’outils pour résoudre les problèmes de mémoire. Valgrind est l’un des outils les plus utilisés. Votre programme sera horriblement lent et vous montrera des tonnes de problèmes possibles en examinant chaque access mémoire. Un autre outil plus léger est le mudflap, qui doit être associé. Une approche très simple pour réduire le problème consiste à append des instructions assert(condition) à votre code et à espérer que vous échouerez plus tôt. Parfois, vous pouvez résoudre ce problème en examinant chaque access mémoire de votre code et en vous assurant qu’il n’est pas hors de scope (ou, en cas de doute, ajoutez une déclaration d’assertion).