Integer-Overflow im DCCP-Code des Linux-Kernels

Der Linux-Kernel ist die Zentraleinheit jedes Linux Systems. Programmierfehler dort erlauben meist lokalen Angreifern, Schaden anzurichten. Von manchen Fehlern können aber auch entfernte Angreifer profitieren, wie dieser Beitrag zeigt.

Eine im Kernel kürzlich entdeckte Schwachstelle führt nämlich dazu, dass ein entfernter Angreifer Denial-of-Service-Attacken durchführen kann. Ursache ist ein Integer-Overflow-Fehler in der Implementierung des Datagram Congestion Control Protocol (DCCP). Dieses in RFC 4340 spezifizierte Protokoll arbeitet auf der Transport-Schicht und ist seit Version 2.6.14 Bestandteil des Kernels. Entwickelt wurde DCCP hauptsächlich für Anwendungen wie Streaming und Internet-Telefonie, bei denen ein Staukontroll-Mechanismus sinnvoll ist.

Der gefundene Integer Overflow tritt in der Funktion “dccp_parse_options()” auf, die DCCP-Optionen verarbeitet. Dies geschieht mit Hilfe eines längeren Case-Blocks, der unter anderem auch “opt==DCCPO_CHANGE_L … DCCPO_CONFIRM_R” abfragt. In diesem Fall wird die Funktion “dccp_feat_parse_options()” aufgerufen. Sie erhält als Argument unter anderem “len-1”, wobei “len” über die Länge der Optionswerte zuvor Buch führt. Ein entfernter Angreifer kann aber nun dafür sorgen, dass “len” an dieser Stelle im Code 0 beträgt, sodass “len-1” zu -1 wird. Der in “dccp_feat_parse_options()” anschließend aufgerufene Code (die Funktion “dccp_feat_change_recv()” beziehungsweise “dccp_feat_confirm_recv()”) kann dadurch über den eigentlichen Puffer für die Optionswerte hinauslesen. Hiermit kann der Angreifer den Kernel zum Absturz bringen. Die Attacke ist durch geschickt konstruierte DCCP Datenpakete möglich.

Der Programmierfehler lässt sich im Kernel sehr einfach mit Hilfe der If-Abfrage

if (len == 0) goto out_invalid_option;

im Case Block “DCCPO_CHANGE_L … DCCPO_CONFIRM_R” vor Aufruf der Funktion “dccp_feat_parse_options()” beheben. Damit kann es zu keinem negativen Wert kommen, und das Problem ist behoben.

Betroffen sind Kernelversionen vor 2.6.33.14.

Nach oben