Programozási katasztrófák 2. rész

Ha tetszett, oszd meg ismerőseiddel!

Bárkivel előfordul, hogy követ el hibákat munkahelyén. Ahogy mondani szokták: ahol fát gyalulnak ott hullik a forgács. Velünk, programozókkal sincs ez másként: néha elfelejtünk egy-egy sorvégi pontosvesszőt, különböző eseteket hagyunk figyelmen kívül, és még sorolhatnám.

Ezeket teszteléskor gyakran észrevesszük vagy észreveszi a tesztelő, de ha benne is maradnak a kódban sem mindig járnak katasztrofális következményekkel.

Máskor ezek a programkódban maradt hibák komoly biztonsági résként tátongva édesgetik magukhoz a jó- vagy rossz szándékú hackereket, akik így tetemes kárt is tehetnek az informatikai rendszerben. Ezekről gyakran beszélünk a Random Generátor Podcast adásaiban is, és olvashatjátok a hírekben.

Aztán vannak olyan hibák, amelyeknek ennél is súlyosabb következményei vannak. Ablakon kidobott dollár milliárdok, több évnyi tudományos kutató munka eredménye vagy akár emberéletek vesznek kárba egyetlen rosszul megírt kód miatt.

Ebben a bejegyzésben, az első résztől eltérően, olyan programhibákat fogok bemutatni nektek, amelyek ember életeket követeltek. Minden esetben átnézzük az eseményeket, majd hosszabb-rövidebb magyarázat közben kibontakoznak az eseményekhez vezető hibák.

Boeing 737 MAX – 2019

Forrás: Wikipedia

2019. március 10-én helyi idő szerint 8 óra 38 perckor felszállt az ET-AVJ lajstromjelű Boeing 737 MAX8 típusú repülőgép a kenyai Addisz-Abebából, fedélzetén 149 utassal és 8 fős személyzettel. Hat perccel később, 8 óra 44 perckor, a repülőgép 2621 méteres magasságról lezuhant.

A tragédia megrendítette az embereket, az egész világsajtó beszámolt róla, és rögtön megindult a nyomozás a lehetséges okokról. Először a pilótákat hibáztatták a baleset bekövetkezése miatt, majd karbantartások elmaradásáról szóltak a hírek, végül a Boeing magára vállalta a felelősséget.

A márciusi eset nyomozása közben került elő egy másik eset. 2018. októberében történt kísértetiesen hasonló indonéz eset. Ott is egy Boeing 737 MAX8 volt a lezuhant repülőgép típusa, fedélzetén 187 emberrel.

A két eset lefolyása teljesen megegyezett, szinte ugyanaz történt mindkét géppel. A felszállást követően a gép átesést észlelve erőteljesen lefelé nyomta a repülőgép orrát. A pilóták ezért elkezdték felfelé húzni a gépet, ám a fedélzeti számítógép továbbra is – hibásan – átesést észlelt, ezért az folyamatosan lefelé nyomta a gép elejét. A pilóták így hiába próbálták visszahúzni, az automatika győzött. Folyamatosan fel-le bukdácsolva egyre alacsonyabb magasságra került a gép, míg végül a földbe csapódott.

Mi okozta a tragédiát?

Egy repülőgép lezuhanásához egyetlen tényező nem elegendő, ez ebben az esetben sincs másképp. A Boeing az Airbus-szal versenyezve hasonló módosítást szeretett volna létrehozni a 737-esen mint az Airbus az A320-ason. 15%-al megnövelt turbóventillátoros gázturbinás sugárhajtóművet építeni, mely alacsonyabb fogyasztás mellett, nagyobb erőt és hatékonyabb üzemeltetést eredményezett.

A MAX-8 és a 800-as típus oldalnézeti képe

Csakhogy míg az Airbus minimális változtatásokkal abszolválni tudta a módosítást az A320 neon típusú gépekkel, a 737-esek az alacsonyabb hasmagasság miatt erre nem voltak alkalmasak, erőteljesebb átalakítást igényelt a szerkezet.

A mérnökök azt találták ki, hogy az egész turbinát picit feljebb tolják, így a szárny alatt lesz elegendő hely a terjeszkedéshez. Csakhogy ez változtatott a gép viselkedésén, és ezzel a mérnökök is tisztában voltak. Ezért beépítették az MCAS rendszert, ami a túlzott emelkedés majd veszélyes átesés ellen védte volna a gépet. 

Az első hibát a Boeing ott követte el, hogy a pilótáknak nem szólt erről a rendszerről. 1-2 órás iPaden lefolytatott gyorstalpaló után már vezethették az új MAX8-as típust, azok a pilóták akiknek a korábbi MCAS nélküli változatra már megvolt az engedélye.

Így amikor hibásan átesést észlelt a gép, a pilóták nem tudták, hogyan tudnák visszaszerezni a gép feletti uralmat.

Később arra gyanakodtak, hogy szenzor hiba állhat a probléma mögött, ám hamar az MCAS központi számítógépére és annak vezérlőszoftverére terelődött a gyanú.

Amikor szimulátorba helyezték, még a tapasztalt pilóták is, akik tudtak az MCAS rendszerről, és annak kikapcsolásának lehetőségéről is arról panaszkodtak, hogy a gép nagyon erőszakosan nyomja az orrát a föld felé, és még számukra is gondot okozott a gép feletti uralom visszanyerése. Gondolhatjuk, hogy mennyi esélye volt az online tanfolyamot elvégzett pilótáknak az automatika ellen.

Az MCAS rendszer működése

A szoftver kifejlesztése során számos hibát vétettek a programozók, bár konkrét forráskód részleteket nem tudunk, de nagy vonalakban ismertek a szoftver működésének részletei. Az MCAS-nak akkor kellett volna működésbe lépnie, ha:

  • túl meredek az állásszög
  • a robotpilóta ki van kapcsolva
  • a fékszárny be van húzva

Csakhogy a való életben a pilóták néha máshogy repülték a gépeket, és a fenti feltételrendszernek megfelelő szituációt voltak képesek előidézni, anélkül, hogy a gép valóban átesett volna. Emellett szerepet játszhatott a rosszul kalibrált állásszög adó, a felszálláskor lassabb gép, meredek emelkedés és az, hogy a pilóták kézzel repülték a gépet, nem robotpilótával, valamint behúzták a fékszárnyakat. Ezekből már látható, hogy az MCAS miért érzékelte tévesen veszélyesnek a helyzetet.

Tovább rontotta a helyzetet, hogy sem a kézikönyvekbe nem került bele az MCAS, sem pedig jelzőfény vagy hibaüzenet formájában nem került kiírásra, hogy épp az MCAS aktiválódott. Így a pilótáknak fogalma sem lehetett arról, hogy miért nyomja lefelé a gép az orrát.

Ezután maga a Boeing vezérigazgatója ismerte el, hogy a hiba az MCAS rendszerben van, és szoftverfrissítéssel úrrá tudnak lenni a problémán.

Mindenképp meg kell említeni, hogy itt nem csak szoftveres probléma volt, menedzsment problémák is súlyosbították a helyzetet, elbagatelizálták a helyzet súlyosságát, valamint meggyőzték a hatóságokat is arról, hogy nem kell az egész típust újra engedélyeztetni.

344 ember halála, mellett szinte eltörpül a Boeing presztízs és pénzvesztesége, amit egy rosszul megírt vezérlőszoftver okozott.

Therac-25 – 1985

Az 1980-as években a kanadai Atomic Energy of Canada Limited (AECL) úgy döntött ,hogy ideje továbbfejleszteni a Therac-6 és Therac-20 egységeit, így 1982-ben el is kezdték gyártani a Therac-25-ös típust.

A nagy újdonsága a készüléknek az volt, hogy elődeitől eltérően, számítógéppel mozgatható védőlapjai voltak. Így az operátor a monitor mögött ülve, biztonságban kezelhette a gépet, illetve gyorsította a betegek ellátását is. Az évtized közepére egyre több intézményben is elkezdték használni a modern és drága berendezést rákos betegek gyógyítására.

A készülék kétféle sugarat tudott kibocsátani: az alacsonyabb energiájú elektronsugarat, illetve a nagyobb erősségű röntgen sugarat. A védőlemezt a röntgen sugaras üzemmódban a beteg elé kellett helyezni, a komolyabb sérülések elkerülése érdekében. 

Csakhogy hamar feltűnt, hogy a kezelésre járó betegek állapota nem javult. Sőt néhányan kimondottan sugárbetegség tüneteit kezdték mutatni. A vizsgálatok megdöbbentő hiányosságokat fedeztek fel a berendezés szoftverében.

Mi okozta a problémát?

Az operációs rendszer nagyjából megegyezett a Therac-20-as típuson használttal, némi módosítást eszközöltek rajta, azt sem körültekintően. Míg a korábbi verzióban hardveres lockok megakadályozták a rossz beállításokat, az új modelből ezek teljesen hiányoztak. Viszont mivel a korábbi verzió nem jelezte semmilyen módon a hibás beállításokat, így a hibák nem kerültek dokumentálásra, és emiatt nem kerültek bele az új operációs rendszer szoftverébe.

Az egyik ilyen, nagyon súlyos hiba, hogy röntgen sugarat a védőlemez behelyezése nélkül is lehetett indítani, így a pácienst közvetlenül sugározták be. Többen áramütésszerű élményekről számoltak be, amikor ilyen történt.

Másik hiba, hogy a kezelést végző operátor sokszor késve kapta meg, hogy a páciens mekkora sugárdózist kapott, így akár többször is megnyomta az elsütés gombot. Ezáltal a kezelésen résztvevő beteg több dózist is megkapott egyszerre.

Bizonyíthatóan legalább hat halálesetről lehet tudni, és legalább kilenc esetet regisztráltak, mikor nagyobb sugárdózist kapott a kezelésre érkező beteg az előírtnál.

Ez az eset rávilágított arra, hogy a szoftvereket nem lehet minden esetben újrafelhasználni. Kidolgozásra kerültek az orvosi szoftverekkel kapcsolatos szigorú előírások, valamint a teszt- és üzemeltetési protokollok. Például az eset óta kötelező ellenőrizni, hogy a védőlemez a helyén van-e a beállításokat követően.

Toyota – 2007

2007. február 25-én Bulent Ezal és felesége, Anne Ezal beült a 2005-ös évjáratú Toyota Camry-ba, hogy egy kis sétakocsikázásra menjenek kettesben. Prismo Beach-en egy parkolóban megálltak kicsit, ám az autó hirtelen sebességbe kapcsolt, és egyenesen belerohant a sziklákkal szegélyezett szakadékba, onnan pedig bele a Csendes-óceánba. A férj, Bulent túlélte a 70 láb magasról történt zuhanást. Felesége, Anne azonban nem volt ilyen szerencsés: belehalt a sérüléseibe.

Az esetet megelőző években a Toyotának már volt egy nagyobb visszahívása, a pedálok alá gyűrődő szőnyegek miatt. A hiba miatt beragadhatott a gázpedál, vagy a sofőrök nem tudták megfelelően lenyomni a fékpedált. Ez a tervezési/gyártási hiba több ember életét is követelte a 2005 és azt megelőző években.

Ezal-ék esetét azonban a szakértői vizsgálatok nem tudták megmagyarázni a felgyűrődő szőnyeggel, és más tényezőket is kizártak. Eközben a Toyota a férj felelősségét próbálta hangsúlyozni.

5 évnek kellett eltelnie, hogy végül 2013. októberében bebizonyosodjon: a Toyoták vezérlőszoftverével volt probléma.

Amikor Michael Barr és Philip Koopman szakértők megvizsgálták a Toyotákra telepített szoftvert, akkor megdöbbentő hanyagságokat találtak. 

A vezérlőszoftver átvizsgálása

Az autókhoz szoftvereket gyártó cégeknek egy ún. MISRA szabályrendszernek kell megfelelnie, mely gyakorlatilag egy guideline a fejlesztők számára. Összegyűjti, hogy hogyan érdemes felépíteni a kódot, hogy az később is karbantartható és tesztelhető legyen. Mire érdemes odafigyelni, milyen rossz beidegződéseket érdemes elkerülni, és milyen gyakorlatokat érdemes követni fejlesztés során.

Amikor a szakértők ráeresztették a MISRA-C teszteket a Toyota szoftverére az 7.134 hibajelzést eredményezett. Barr később elvégezte az akkor legújabbnak számító MISRA-2004-es teszteket is. Ekkor 81.514 hibajelzést kapott. Minden 30 hibajelzésre jutott három kisebb és egy súlyosabb szoftver bug. Ebből azért látható, hogy több száz, illetve ezer súlyosabb hiba volt a vezérlőszoftverben.

Továbbá kimutatták, hogy 256.000 fel nem kommentezett sor volt a kódban. Ebből arra lehet következtetni, hogy a kód dokumentációjára sem adtak.

Rengeteg, nagyon komplex, ezáltal nehezen tesztelhető függvényt fedeztek fel. Volt olyan, ami 1500 soros volt (ez úgy kb 35 darab A4-es oldalnak felelne meg 12-es betűmérettel teleírva, sorközök nélkül). Ez a gigantikus függvényszörny mindenféle dokumentáció nélkül létezett a szoftverben. Gyakorlatilag a fejlesztők nem mertek hozzányúlni, mert nem értették, hogyan működik, és komplexitása miatt nem tudtak rá tesztet írni.

Az egyes kódrészletek komplexitása meghaladta az ajánlott értéket. Az ún. ciklomatikus komplexitás egy olyan mérőszám, amit sok kódminőség ellenőrző szoftver használ.Minden elágazásnál és ciklusnál növekedik 1-gyel az értéke, minden új függvénynél lenullázódik, ezzel megadható, hogy egy adott függvény, mennyire bonyolult.

Iparági sztenderdek alapján elmondható, hogy 50-es komplexitás alatt az adott kódrészlet könnyen tesztelhető, efölött már nehezen vagy egyáltalán nem. 67 függvény volt a forráskódban, ami 50-es komplexitás feletti értékkel bírt. A gyorsításért felelős függvény 1300 soros volt, 146-os komplexitás értékkel. Ezzel lényegében teljesen tesztelhetetlenné vált az adott programegység.

Banális hibák a kódban

Ráadásul nem csak az ipari szabványokat hagyták figyelmen kívül. Sokszor a saját szabályaikat sem követték: a változó és függvény elnevezések például nem voltak következetesek.

A mai felfogás szerint globális változókat nem használunk, ha nem muszáj. Mivel azok bárhol átírhatók és ezzel befolyásolni lehet a szoftver működését. A szakértői jelentésben az áll, hogy ha csak négyet ötöt vagy tízet találtak volna, akkor az még rendben lenne, de a Toyota szoftverében tízezer globális változót találtak az ellenőrzéskor. Ez gyakorlatilag azt jelenti, hogy bárki aki hozzáfér a szoftverhez, szinte bármit át tud benne írni. Ez azért elég ijesztő.

Elmondható, hogy gyakorlatilag mindent elszúrtak a Toyota programozói. Szinte csodával határos, hogy csak pár haláleset történt bizonyítottan a hibás szoftver miatt, mely a legváratlanabb pillanatokban késztette extrém gyorsításra a gépjárművet.

A Toyota saját maga, házon belül fejlesztette ki a szoftvert C nyelven. Úgy gondolták ugyanis, hogy túl költséges lenne külsős céget megbízni ezzel a feladattal. Végül a kirótt bírságok és kártérítések meghaladták az 1.2 milliárd dollárt. Valószínűleg egy adott pontot túl már ők is rájöttek, hogy jobban jártak volna, ha kiszervezik az egészet egy olyan cégnek, akik értenek is hozzá.

Patriot rakéta -1991

1991. február 25-én az Öböl-háború idején a szaúd-arábiai Dharan közelében szolgálatot teljesítő Patriot rakéta rendszer csődöt mondott. Így nem tudta időben megállítani az iraki Scud rakétát, ami a barakkok közé csapódott. A rakéta 28 amerikai katonát megölt, és körülbelül 100 másik embert eltérő mértékben megsebesített.

A vizsgálat eredménye szerint a Patriot rakéta a támadás napján már több, mint 100 órája folyamatosan üzemelt. A programkódban lévő kerekítési hiba annyira megnőtt, hogy a rakéta teljesen célt tévesztve, közel 600 méterrel arrébb csapódott be, mint ahol kellett volna.

A Patriot fegyverrendszert nem tervezték ilyen hosszú üzemidőre. Mivel egy nagy mobilitású rendszerről van szó, tehát a gyors telepítést és a rakétaindítást követően áttelepül, ami pedig a rendszer ki-, majd újbóli bekapcsolását jelenti. Normál körülmények között tehát legfeljebb 14 órát üzemel.

Mi okozta a gondot?

A rakéta indító rendszer belső órája tizedmásodpercekben mérte az időt, ahhoz hogy megkapjuk a másodperceket ezt egyszerűen fel kellett szorozni tízzel. 

Tehát ha a bekapcsolás óta eltelt 20 másodperc, akkor a rendszerben ez 200 egységnek felelt meg, és ahhoz, hogy megkapjuk a másodperceket a 200 egységet el kellett osztani tízzel.

Számítógépes rendszerről beszélünk, tehát a számítás nem ilyen egyszerű: hiszen nem tízes számrendszert, hanem binárisat használnak. A rendszer 24 biten ábrázolta a tizedmásodperceket, ez viszont egy végtelen tizedes törtet eredményez, ezért a végét egyszerűen levágták. Ez a levágás bizonyult később végzetesnek.

Már 8 órás üzemidő mellett is 0.0275 másodperces eltérést észleltek, 100 órányi üzemidő után már tetemes 0.34 másodpercre duzzadt a késés. 

Ezalatt a Scud rakéta kiért az időablakból, és így a Patriotnak már esélye se volt elkapni azt.

Az egészben az a legszörnyűbb, hogy az izraeli hadsereg két héttel korábban már figyelmeztette az amerikaiakat, hogy gond lehet a Patriot rakétákkal, folyamatos üzemeltetés mellett, és ők javasolták az időnkénti újraindítást.

A fejlesztő cég a tragédia másnapján, február 26-án nyújtotta át a frissített szoftvert az amerikai hadseregnek. Az irányítószoftver még a 70-es években írták Assembly nyelven, később több helyen is módosítottak a kódon, de nem igazán figyeltek arra, hogy a módosítások milyen kihatással lesznek az egész rendszerre nézve.

Források

https://pvs-studio.com/en/blog/posts/0439/

https://www.edn.com/design/automotive/4423428/Toyota-s-killer-firmware–Bad-design-and-its-consequences

http://www.safetyresearch.net/blog/articles/toyota-unintended-acceleration-and-big-bowl-%E2%80%9Cspaghetti%E2%80%9D-code

https://hvg.hu/tudomany/20110213_bug_toplista

http://www.raketaezred.hu/index.php/hirek/szakmai-hirek/237-patriot-hiba-a-celt-teveszt-raketa

http://www-users.math.umn.edu/~arnold/disasters/Patriot-dharan-skeel-siam.pdf

Hogy tetszett a poszt?

Van bármi észrevételed?


Ha tetszett, oszd meg ismerőseiddel!