2014-01-29 3 views
0

Я новичок в C, я получил ошибку сегодня, которая является:ядро ​​ошибки сегментации сбрасывали гр

segmentation fault core dumped 

Я использовал GDB для отслеживания кода, я обнаружил, что ошибка в этой строке:

if (!strcmp(user_pass, passwddata->passwd)) 

Где user_pass это символа массив из и passwddata является структурой, passwd является членом структуры, которая также является типом с хар массив, я попытался изменить код

if (!strcmp(user_pass, "ttt")) 

ошибка не происходит, поэтому я предполагаю, что ошибка происходит на этой структуры, если больше кода необходимо, я могу добавить, здесь я хочу понять, при каких условиях может возникнуть такая ошибка в структуре?

Вот код:

int main(int argc, char *argv[]) { 

mypwent *passwddata; /* this has to be redefined in step 2 */ 
/* see pwent.h */ 

char important[LENGTH] = "***IMPORTANT***"; 

char user[LENGTH]; 
//char *c_pass; //you might want to use this variable later... 
char prompt[] = "password: "; 
char *user_pass; 

sighandler(); 

while (TRUE) { 
    /* check what important variable contains - do not remove, part of buffer overflow test */ 
    printf("Value of variable 'important' before input of login name: %s\n", 
      important); 

    printf("login: "); 
    fflush(NULL); /* Flush all output buffers */ 
    __fpurge(stdin); /* Purge any data in stdin buffer */ 

    if (gets(user) == NULL) /* gets() is vulnerable to buffer */ 
    { 
     exit(0); /* overflow attacks. */ 
    } 
    printf("******************* %s\n",user); 

    /* check to see if important variable is intact after input of login name - do not remove */ 
    printf("Value of variable 'important' after input of login name: %*.*s\n", 
      LENGTH - 1, LENGTH - 1, important); 

    user_pass = getpass(prompt); 
    passwddata = getpwnam(user); 

    printf("^^^^^^^^^^^^^^^^^^^^^^^^^^ %s\n", user_pass); 

    if (passwddata != NULL) { 
     /* You have to encrypt user_pass for this to work */ 
     /* Don't forget to include the salt */ 


     if (!strcmp(user_pass, "ttt")) { 

      printf(" You're in !\n"); 

      /* check UID, see setuid(2) */ 
      /* start a shell, use execve(2) */ 

     } 
    } 
    printf("Login Incorrect \n"); 
} 
return 0; 
} 
+0

Либо 'passwddata', либо' passwd' являются недопустимыми. – cnicutar

+0

Пожалуйста, добавьте код для создания user_pass и passwddata. Я подозреваю, что вы не создавали экземпляр указателя passwddata – AndyG

ответ

3

Скорее всего passwd или passwddata является NULL, в последнем случае -> пытается почтительное на NULL указатель и, таким образом, это сбой.

Изменив код:

if (!strcmp(user_pass, "ttt")) 

Вы выделили первую часть, так что вы знаете user_pass ОК. Вы можете использовать отладчик или некоторые проверки и printf, чтобы получить значения passwddata и passwd, чтобы закрыть проблему.


Теперь, когда вы обновили код, который вы знаете, что проблема с passwd. Вы можете начать с пустым указателем:

mypwent *passwddata; 

Позже вы установите указатель на возвращение getpwnam, предположительно, это указатель на структуру типа mypwent, что вы выделили несколько памяти:

passwddata = getpwnam(user); 

у вас есть чек, чтобы убедиться, что passwddata не равно нулю:

if (passwddata != NULL) { 
    if (!strcmp(user_pass, "ttt")) { 

Так что теперь вы проверили все, кроме passwd, пропусканием null в strcmp() вызовет его сбой с этим сообщением, поэтому я предполагаю, что вы выделили только память для структуры, а не для массива char внутри структуры.

+0

Я думаю, что проблема в том, что «passwd» - «NULL», кстати, что вы подразумеваете под «deference the NULL pointer»? –

+0

@ Zhenxiao - Ваша проверка на 'if (passwddata! = NULL)' защитит вас от этого. В принципе, если 'getpwnam()' не удалось выделить память для вашего указателя, операция '->' потерпит крах ... но, как я уже сказал, это не проблема, связанная с обновлением кода. Это должно быть 'passwd' – Mike

+0

@ Zhenxiao http://www.cprogramming.com/debugging/segfaults.html – Peter

0

Я предполагаю, что passwddata NULL.

или буфер passwddata->passwd указывает на

  • короче строки в user_pass

и

  • не нулевым байтом

Вместе эти два делают ул rcmp доступа за пределы буфера второго аргумента и, следовательно, причиной ошибки.

Смежные вопросы