- předchozí článek - následující článek - obsah - úvodní stránka -

Linuxové noviny Říjen 1997

Nejdéle existující chyba v Linuxu

Lars Wirzenius, 7.května 1997

Na jaře a v létě roku 1991 se můj přítel Linus pohrával s operačnímu systému se podobajícím programem, ze kterého se později stal Linux. Chtěl do svého jádra funkci podobnou printf, ale nevěděl, jak ji implementovat (ještě neznal dokonale jazyk C). Proto jsem mu napsal funkci sprintf, kterou po několika změnách použil.

V září 1994 použil Friedemann Baitinger ze společnosti IBM, který vyvíjel ovladač zařízení pro jiný operační systém, moji funkci sprintf při ladění (ale ne v konečném produktu). Chyba přežívala tři nebo tři a půl roku bez povšimnutí. Bohužel, byla objevena ihned poté, co se někdo pokusil ji použít obvyklým způsobem. Nikdo to předtím neudělal, ani já, když jsem ji psal. Nikdy po mně nechtějte, abych psal kód, který má fungovat.

Chyba byla v obsluze šířky tisknutého argumentu zadané jako parametr. Funkce sprintf může být např. použita takto:

sprintf(buf, "%s", str);

Tento příkaz umístí řetězec str do buf. sprintf umožňuje i formátování výstupu:

sprintf(buf, "%10s", str);

Tento příkaz udělá řetězec buf nejméně 10 znaků dlouhý (delší, pokud je str delší). Šířka řetězce může být zadána konstantou nebo jako oddělený parametr:

sprintf(buf, "%*s", 10, str);

Tento příkaz má stejný efekt jako předchozí, ale odhalí moji chybu.

Moje funkce sprintf byla implementována jako smyčka, které procházela formátovací řetězec a zvyšovala index po zpracování jeho další části. Kromě situace, kdy zpracovávala "*". A je to tady.

(Proč to vysvětluji tak důkladně? Můj divný smysl pro humor mne donutil umístit text "Author of the longest-living linux bug" do souboru CREDITS ve zdrojových textech jádra a mnoho lidí se mne na to někdy ptá.) *


- předchozí článek - následující článek - obsah - úvodní stránka -