2012-02-09 1 views
1

valgrind를 실행 중이며 다음 오류가 발생합니다. 백업을하기 전에 먼저 수정했지만 지금은 기억이 안납니다. 오류가 malloc에 ​​의해 생성 된 그러나 나는이 라인 commands_man 기능 입니다valgrind를 사용하여 단위화된 값

>Insert password for admin: ==5720== Conditional jump or move depends on uninitialised value(s) 
==5720== at 0x40299EB: strcmp (mc_replace_strmem.c:538) 
==5720== by 0x80496C6: adm_log_request (commands_man.c:169) 
==5720== by 0x80521CA: main (mmboxman.c:9) 
==5720== Uninitialised value was created by a heap allocation 
==5720== at 0x4028876: malloc (vg_replace_malloc.c:236) 
==5720== by 0x8049683: adm_log_request (commands_man.c:165) 
==5720== by 0x80521CA: main (mmboxman.c:9) 
==5720== 

코드에서 오류를 찾을 수 없습니다 : (165)은 그 이후 경우 (크기는> 0)

int adm_log_request(void){ 

FILE *password; 
char *pwdin, *frompwd = NULL; 
int primo = 0/*indica se è un primo avvio*/, tentativi = 2, p, size; 

if(!(password = fopen(F_PWD_ADM, "rb"))){ 
    primo = 1; 
    printf("First server boot\n>Insert password for admin: "); 
} 
else{ 
    primo = 0; 
    printf(">Insert password for admin: "); 
} 
p = get_hid_pass(&pwdin); 
if(p < 0) 
    return -1; 
switch(primo){ 
    case 0: 
     if(!(password = fopen(F_PWD_ADM, "r"))) 
      return -1; 
     fread(&size, sizeof(int), 1, password); 
     if(size > 0){ 
      frompwd = (char*)malloc(size + 1); 
      fread(frompwd,sizeof(frompwd),1,password); 
     }else return 0; 
     while(tentativi > 0){ 
      if(strcmp(pwdin, frompwd) != 0){ 
       printf("\nIncorrect password\n%d attempts left\n>Insert password for admin: ", tentativi); 
       tentativi--; 
      } 
      else return 1; 
      p = get_hid_pass(&pwdin); 
      if(p < 0) 
       return -1; 
     } 
     fclose(password); 
     break; 
    case 1:  //primo avvio del server 
     if(!(password = fopen(F_PWD_ADM, "w"))) 
      return -1; 
     size = strlen(pwdin) + 1; 
     fwrite(&size, sizeof(int), 1, password); 
     fwrite(pwdin, sizeof(pwdin), 1, password); 
     fclose(password); 
     break; 
} 
if(tentativi == 0) 
    return -1; 

return 1; 
} 

수 누군가 나를 고칠 수 있도록 도와 주시겠습니까 ?? 당신을 감사 문제의

답변

1

일부는 sizeof에 문제처럼 보인다 : 위의 줄에

 fread(frompwd,sizeof(frompwd),1,password); 

이는 sizeof 4 (가정 32 비트 아키텍처)의 값을가집니다. 길이에 따라 size을 전달해야 할 수도 있습니다. 그리고 나서 여전히 null이 끝나야합니다.

frompwd[size] = '\0'; 

fwrite 호출은 비슷한 문제를 가지고 있으며, 암호 만 4 바이트를 기록합니다.

+0

나는 문제를 발견했다. 그것은 에 있었다. size = strlen (pwdin) + 1; +1이 잘못되었습니다. 감사!! =) – roccocullo

+0

@roccocullo : 널 터미네이터 바이트를 쓰고 싶으면 달라집니다. 그리고'fwrite' 호출은 sizeof 결과 대신 정확한 길이 (size)를 주어질 필요가 있습니다. –

0

아마도 fread은 실제로 무엇이든지 size을 설정하지 않습니까?

보장 할 수 없습니다. (the man page에서) 반환 값을 참조하십시오

RETURN은

기능의 FREAD()와에 fwrite를 VALUES() 바이트를 읽거나 쓸 수만큼 스트림의 파일 위치 표시 를 진행합니다. 그들은 읽거나 쓰여진 객체 수인 을 반환합니다. 오류가 발생하거나 파일 끝에 도달하면 반환 값은 짧은 개체 수 (또는 0)입니다.

fread() 함수는 end-of-file과 error를 구별하지 않습니다. 발신자는 발생한 것을 확인하려면 feof (3) 및 ferror (3)를 사용해야합니다. 함수 fwrite()는 쓰기 오류 이 발생한 경우에만 nitems보다 작은 값을 반환합니다. 반환 값은 예컨대 0이면

다음 size 여전히 광고 165 초기화되지 않은된다. 좋은 예는 fread이 무엇을 반환하는지 확인하고 값이 실제로 성공적으로 읽혔는지 확인하는 것입니다.

0

먼저 당신은 파일에서 4 바이트 (또는 8 64 비트에서)를 읽어

fread(frompwd,sizeof(frompwd),1,password); 

당신은 아마 여기 sizeof(frompwd)를 사용하는 말은하지 않았다.

그런 다음,을 strcmp를 사용하여 비교 :

strcmp(pwdin, frompwd) 

strcmp는 두 문자열 중 하나가 NUL '\ 0'문자를 포함 할 때까지 비교에 전달합니다. 이 경우 암호 문자열, 즉 메시지를 절대 종료하지 않습니다.

a) 올바른 읽기 크기를 사용해야하고 b) strncmp을 사용하여 이와 같은 버퍼 오버런 오류가 발생하지 않도록해야합니다.

+0

사실상 오류는 frompwd [size] = '\ 0'; :) – roccocullo

+0

nul-terminator에 대한 공간을 할당하는 것을 잊지 마십시오. 문자열 크기에 1을 더해야합니다. – ams