GLibc: Denial-of-Service Attacke

Eine Sicherheitslücke in der Bibliothek GLibc führt dazu, dass ein lokaler Angreifer Denial-of-Service-Attacken ausführen kann. Der Programmierfehler befindet sich in der Implementierung der Funktion “getaddrinfo()”. Hier kann der Angreifer durch geschickte Anfragen einen Stack Overflow auslösen und damit Anwendungen, welche die Bibliothek verwenden, zum Absturz bringen. Die Attacke lässt sich beispielsweise durch eine große Anzahl von IPv6-Einträgen in der Datei “/etc/hosts”auslösen. “getaddrinfo()-Anfragen an diese führen dann zum Overflow.

Ein Proof-of-Concept-Exploit sieht folgendermaßen aus:

  1. Anlegen einer großen “/etc/hosts-Datei”: 50 000 Einträge mit “127.0.0.1 host-fubar” und 50 000 mit “::1 host-fubar”
  2. Aufrufen von “getaddrinfo()” für “host-fubar ohne Flags und “AF_INET” für “hints->ai_family”

Dies wird einen Segmentation Fault auslösen (Signal “SIGSEGV”). Der Programmierfehler befindet sich in der Quelltextdatei “sysdeps/posix/getaddrinfo.c”.

Das Patch zur Behebung sieht wie folgt aus:

--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -197,7 +197,21 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, &rc, &herrno, NULL, &localcanon)); if (rc != ERANGE || herrno != NETDB_INTERNAL) break;
- tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
+ if (!malloc_tmpbuf && __libc_use_alloca (alloca_used + 2 * tmpbuflen))
+ tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
+ else
+ {
+ char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
+ 2 * tmpbuflen);
+ if (newp == NULL)
+ {
+ result = -EAI_MEMORY;
+ goto free_and_return;
+ }
+ tmpbuf = newp;
+ malloc_tmpbuf = true;
+ tmpbuflen = 2 * tmpbuflen;
+ } } if (status == NSS_STATUS_SUCCESS && rc == 0) h = &th;
@@ -209,7 +223,8 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, { __set_h_errno (herrno); _res.options |= old_res_options & RES_USE_INET6;
- return -EAI_SYSTEM;
+ result = -EAI_SYSTEM;
+ goto free_and_return; } if (herrno == TRY_AGAIN)

Er ändert die Speicherallokation des “tmpbuf”-Puffers so, dass der Code auch mit größeren Anfragen umgehen kann und es nicht mehr zu einem Speicher-Überlauf kommt.

 

Nach oben