SizeofPtr – Verwendung von sizeof() für einen Zeigertyp
Nach oben zu C++-Audits
Beschreibung
SizeofPtr warnt bei unbeabsichtigter Verwendung von sizeof() für Zeigerausdrücke.
Der Code ruft sizeof() für einen mit malloc zugewiesenen Zeigertyp auf, der immer wordsize/8
zurückgibt. Dies kann zu einem unerwarteten Ergebnis führen, wenn der Programmierer die zugewiesene Speichergröße ermitteln wollte.
Beispiel 1
Achten Sie darauf, dass sizeof die Größe der Datenstruktur und nicht die Größe des Zeigers auf die Datenstruktur zurückgibt.
In diesem Beispiel gibt sizeof(foo)
die Größe des Zeigers zurück.
double *foo;
...
foo = (double *)malloc(sizeof(foo));
In diesem Beispiel gibt sizeof(*foo)
die Größe der Datenstruktur und nicht die Größe des Zeigers zurück.
double *foo;
...
foo = (double *)malloc(sizeof(*foo));
Beispiel 2
Dieses Beispiel definiert einen festen Benutzernamen und ein festes Passwort. Die Funktion AuthenticateUser() soll den Benutzernamen und das Passwort von einem nicht autorisierten Benutzer akzeptieren und überprüfen, um deren Übereinstimmung mit dem Benutzernamen und Passwort sicherzustellen. Wenn der Benutzername und das Passwort gültig sind, soll AuthenticateUser() anzeigen, dass die Authentifizierung erfolgreich war.
char *username = "admin";
char *pass = "password";
int AuthenticateUser(char *inUser, char *inPass) {
printf("Sizeof username = %d\n", sizeof(username));
printf("Sizeof pass = %d\n", sizeof(pass));
if (strncmp(username, inUser, sizeof(username))) {
printf("Auth failure of username using sizeof\n");
return(AUTH_FAIL);
}
/* sizeof returns 4 on many platforms and architectures. */
if (! strncmp(pass, inPass, sizeof(pass))) {
printf("Auth success of password using sizeof\n");
return(AUTH_SUCCESS);
}
else {
printf("Auth fail of password using sizeof\n");
return(AUTH_FAIL);
}
}
int main (int argc, char **argv)
{
int authResult;
if (argc < 3) {
ExitError("Usage: Provide a username and password");
}
authResult = AuthenticateUser(argv[1], argv[2]);
if (authResult != AUTH_SUCCESS) {
ExitError("Authentication failed");
}
else {
DoAuthenticatedTask(argv[1]);
}
}
In AuthenticateUser() könnte der sizeof()-Aufruf auf vielen modernen Architekturen 4 zurückgeben, weil sizeof() für einen Parameter mit einem Array-Typ angewendet wird. Als Ergebnis überprüft der strncmp()-Aufruf nur die ersten vier Zeichen des eingegebenen Passworts, was zu einem teilweisen Vergleich und einer inkorrekten Authentifizierung führt.
Aufgrund des teilweisen Vergleichs würden all diese Passwörter zu einer erfolgreichen Authentifizierung für den Benutzer "admin" führen:
pass5 passABCDEFGH passWORD
Weil nur 4 Zeichen überprüft werden, wird der Suchbereich für Angreifer deutlich verringert, und Brute-Force-Angriffe werden durchführbarer.
Dasselbe Problem betrifft auch den Benutzernamen, daher werden Werte, wie adminXYZ
und administrator
, für den Benutzernamen akzeptiert.