Nejdéle existující chyba v Linuxu
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
And 1.1.81 is officially BugFree(tm), so if you receive any
bug-reports on it, you know they are just evil lies.
--Linus Torwalds
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á.)
Lars Wirzenius, 7.května 1997
Článek je převzat z prvního čísla Linuxových novin, které si
můžete přečíst na http://www.freesoft.cz/noviny
výheň