Унифицированные значения с использованием valgrind - PullRequest
1 голос
/ 09 февраля 2012

Я запускаю 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 ]

1 голос
/ 09 февраля 2012

Часть проблемы выглядит как проблема с sizeof:

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

В приведенной выше строке sizeof будет иметь значение 4 (при условии 32-битной архитектуры). Возможно, вам нужно ввести size для длины. И тогда это все еще должно быть закончено нулем после этого.

frompwd[size] = '\0';

Вызов fwrite имеет похожую проблему и записывает только 4 байта пароля.

0 голосов
/ 09 февраля 2012

Сначала вы читаете 4 байта (или 8 на 64-битных) из файла:

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

Вы, вероятно, не хотели использовать sizeof(frompwd) здесь.

Затем высравните, используя strcmp:

strcmp(pwdin, frompwd)

strcmp продолжает сравнение до тех пор, пока одна из двух строк не будет содержать нулевой символ '\ 0'.В этом случае вы никогда не заканчиваете строку пароля паролем, отсюда и сообщение.

Вы должны a) использовать правильный размер чтения и b) использовать strncmp, чтобы убедиться, что вы не получите переполнение буфераошибки, подобные этой.

0 голосов
/ 09 февраля 2012

Может быть fread на самом деле ничего не устанавливает size?

Не гарантируется, что так и будет. См. Его возвращаемое значение (из справочная страница ):

ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ

Функции fread () и fwrite () опережают индикатор положения файла для потока по количеству прочитанных или записанных байтов. Они возвращают количество прочитанных или записанных объектов. Если произошла ошибка или конец файл достигнут, возвращаемое значение - короткое число объектов (или ноль).

Функция fread () не различает конец файла и ошибку; вызывающие абоненты должны использовать feof (3) и ferror (3), чтобы определить, что произошло. Функция fwrite () возвращает значение меньше nitems, только если ошибка записи произошло.

Если возвращаемое значение равно, например, 0, то size все еще неинициализировано в строке 165. Хорошей практикой будет проверка того, что возвращает fread, и подтверждение того, что значение действительно было успешно прочитано.

...