2011-10-24 1 views
1
그것은 여기 내 이전 게시물 그러나 문제처럼 보인다 다른

..이 문제에 대한 C 구조입니다오류 메모리 처리 - mremap_chunk : 어설

- 값이 구조에 제공되는

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으로 변경했습니다.

하지만 여전히 뭔가이 덮어 왜

을 개선 할 필요가 ???

+0

이것은 순수한 추측이지만'stringargument (arg, & temp)'가 평가하는 것이 무엇인지 알고 있습니까? 'realloc' 호출이 매우 큰 크기의 할당을 요청할 때 발생하는'mmap' 호출 (또는'mremap')으로 승격되고있는 것 같습니다. 우연히'stringargument' 함수가 너무 큰 쓰레기 값을 반환하면 재미있는 일이 일어날 수 있습니다. –

+0

내 편집에 봐주세요 –

+0

좋아, 편집을 참조하십시오. 그러나 지금보고있는 것을 분명히해야합니다. 당신은 동일한 단언 실패를 보는가? 아니면 주장을 보지 못하지만, 지금은 약간의 기억을 덮어 쓰고 있습니까? 아니면 둘 다 보았습니까? –

답변

1

key [0] struct hack에는 두 키의 공간이 모두 포함되어 있으므로 둘 다에 대해 메모리를 할당해야합니다.

memcpy (priv->key, source1, sizeofsource1); 
/* and */ 
memcpy (((char*) priv->key) +priv->keylen, source2, sizeofsource2); 
: 두 경우 모두 ('K'와 'K')에서

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

두 개의 키을 연결, 그 하나 산수를 문자 포인터로 u_int32_t 키를 캐스팅 할 가장 쉬운 방법입니다

[memmove()와 유사] 프로그램의 나머지 캐스트는 제거 할 수 있습니다.

+0

고맙습니다. .... 내 하루 종일 주위를 검색하러 갔다. –

0

에서 어설 션 오류가 발생하는 경우malloc 이내에 문제가 발생했습니다. 이 주장은 malloc에 ​​전달 된 매개 변수에 관한 것이 아니라 손상된 메모리의 상태에 관한 것입니다. 이것은 이전에 작성하지 말아야 할 메모리 영역에 이전에 썼다는 것을 의미합니다. 따라서 적절한 traceback (예를 들어 gdb를 사용)을 제공하더라도 문제의 원인을 알려주지는 않습니다. 메모리 문제를 디버깅하는 데는 여러 가지 도구가 있습니다. 가장 널리 사용되는 도구 중 하나는 valgrind입니다.그것은 당신의 프로그램을 무섭게 느리게 만들 것이고 모든 단일 메모리 접근을 살펴봄으로써 가능한 많은 문제들을 보여줄 것입니다. 더 가벼운 또 다른 도구는 mudflap이며, 이것은 연결될 것입니다. 문제를 좁히기위한 가장 기본적인 방법은 코드에 assert(condition) 문을 추가하고 이전에 실패했기를 바랍니다. 경우에 따라 코드의 모든 단일 메모리 액세스를보고이 문제가 해결 될 수 있으며 범위를 벗어나지 않았는지 확인합니다 (또는 확실하지 않으면 어설 션 문을 추가하십시오).

+0

내 편집 –