使用valgrind的未初始化值

时间:2012-02-09 15:32:39

标签: c byte valgrind

我正在运行valgrind而且我收到以下错误.. 在我做备份之前我修好了但是现在我不记得了。错误是由malloc生成的,但我在代码中找不到错误

>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== 

这是功能 command_man:165行是if(size> 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;
}

有人可以帮我解决吗?谢谢

3 个答案:

答案 0 :(得分:1)

部分问题与sizeof的问题相似:

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

在上面的行中,sizeof的值为4(假设为32位架构)。可能需要传递size长度。然后它仍然需要在此之后被终止。

frompwd[size] = '\0';

fwrite调用有类似的问题,只会写4个字节的密码。

答案 1 :(得分:0)

也许fread实际上没有将size设置为任何内容?

不保证它会。查看其返回值(来自the man page):

  

返回值

     

函数fread()和fwrite()使文件位置指示器前进        对于流的读取或写入的字节数。他们回来了        读取或写入的对象数量。如果发生错误,或者结束        到达文件后,返回值是一个短对象计数(或零)。

     

函数fread()不区分文件结束和错误;        呼叫者必须使用feof(3)和ferror(3)来确定发生了什么。该        函数fwrite()仅在写入错误时返回小于nitems的值        已经发生了。

如果返回值为例如0,则行size中的165仍然未初始化。一个好的做法是检查fread返回的内容并确认该值实际上已成功读取。

答案 2 :(得分:0)

首先,您从文件中读取4个字节(或64位上的8个字节):

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

你可能并不想在这里使用sizeof(frompwd)

然后你,使用strcmp进行比较:

strcmp(pwdin, frompwd)

strcmp继续进行比较,直到两个字符串中的一个包含nul'\ 0'字符。在这种情况下,您永远不会终止您的密码字符串,因此消息。

你应该a)使用正确的读取大小,并且b)使用strncmp以确保不会出现像这样的缓冲区溢出错误。