Malloc è usato per -
char* firstName = malloc(sizeof(char)*50);
char* lastName = malloc(sizeof(char)*50);
Hai ragione nel dire che sono sul mucchio. Ma cosa succede a questi dati? E come funzionano queste funzioni?
Che altro viene letto dall'utente? E come?
Rispondi al tuo commento qui sotto
So as I see it in my limited scope and understanding, the vaulerabilities are: all the printf, the scanf for studentid
studentid è un int. Quindi credo che le operazioni su di esso siano sicure.
, gets for first and last name
But because malloc was used for the first and last name, does that kinda safegaurd all instances of the gets for them.
I dati immediatamente dopo l'ottenimento saranno nello heap sì. Ma questo lo rende sicuro? Cosa succede se l'utente inserisce più di 50 caratteri per entrambi i campi? Suggerirei di leggere su Overflow dell'heap . Anche se il danneggiamento dei dati dell'heap non era un problema, guarda cosa fa il codice con quei dati. Cosa farà lo strcpy e lo strcat?
gets for level / gets for percentage
Sì. Non solo è possibile che entrambi vengano superati, ma cosa succede dopo il "graduateLevel = & level;" Linea?
Rispondi al secondo commento -
confused as about you last point and what happens after "graduateLevel=&level;"?
"livello char [2];" è dichiarato all'interno della parentesi graffa direttamente sopra. Ciò significa che è protetto solo all'interno dello scope di quel blocco. Questo ambito termina sulla linea dopo "graduateLevel = & level;". Così laureatoLevel indica l'indirizzo in cui si trovava il livello. Ma il compilatore non ha più alcun obbligo di assicurarsi che il livello non venga sovrascritto. Qualsiasi operazione che utilizza il livello dopo questo punto è un comportamento indefinito.
Ora questo problema è piuttosto secondario. C'è una probabilità abbastanza alta che il compilatore non la riutilizzi. Rispetto al livello letto da una chiamata get al di sopra del suo livello trascurabile. Ma un codice come questo spesso porta a bug strani e difficili da rintracciare, alcuni dei quali possono essere sfruttati.
I am bit confused cause I have read a few places that strcpy and strcat are issues, but I have also found that they are not?
Prima di tutto è necessario leggere e comprendere le definizioni per strcpy e strcat . Prendiamo strcpy -
Copies the null-terminated byte string pointed to by src, including the null terminator, to the character array whose first element is pointed to by dest.
Quindi, copia i caratteri dall'array sorgente nell'array di destinazione finché non raggiunge un terminatore nullo ('\ 0', in genere il valore 0 del byte). Osserva gli avvertimenti -
The behavior is undefined if the dest array is not large enough. The behavior is undefined if the strings overlap. The behavior is undefined if either dest is not a pointer to a character array or src is not a pointer to a null-terminated byte string.
Quindi - per la linea
strcpy(studentName, firstName);
si applicano? Dest is studentName: un array di 100 caratteri. Source è firstName: un puntatore a un array di 50 caratteri. Ma il nome è nullo? Bene, il suo valore deriva da -
gets(firstName);
gets è definito come -
Reads stdin into the character array pointed to by str until a newline character is found or end-of-file occurs. A null character is written immediately after the last character read into the array. The newline character is discarded but not stored in the buffer.
Con l'avviso -
The gets() function does not perform bounds checking, therefore this function is extremely vulnerable to buffer-overflow attacks. It cannot be used safely (unless the program runs in an environment which restricts what can appear on stdin). For this reason, the function has been deprecated in the third corrigendum to the C99 standard and removed altogether in the C11 standard. fgets() and gets_s() are the recommended replacements.
Never use gets().
. Se dovessi inserire "Dylan" in firstName, conterrebbe "Dylan \ 0". Cosa succede se inserisco 200 byte?
Lo standard dice che è indefinito ma per la maggior parte dei sistemi reali è abbastanza facile da indovinare. Continuerà a scrivere in qualunque memoria sia dopo firstName. Cosa succede allora? Bene - se lascia lo spazio di memoria che il processo può legalmente scrivere sul sistema operativo probabilmente lo ucciderà. Ma se così non fosse, continuerà a rimanere ignaro fino a quando qualcosa non andrà abbastanza bene da causarne l'arresto (qualunque cosa si supponga di essere riposta non ce n'è più) o il programma terminerà. Ora, come hai sottolineato, il danno è limitato: questi dati sono memorizzati nello heap.
. Supponiamo che tutto continui senza problemi fino alla strcpy. Cosa succede lì? strcpy non sa che firstName dovrebbe avere solo 50 caratteri. O quello studentName dovrebbe essere solo di 100 caratteri. Continuerà a copiare finché non raggiungerà un terminatore nullo.
lastName e strcat hanno esattamente lo stesso problema.