( Aikon | 2008. 10. 01., sze – 16:41 )

A válasz az, hogy igen is, meg nem is. Az ilyen kódfuttatások arról szólnak, hogy a hibás program (jelen esetben az mplayer) olyan helyre ír adatot, ahova nem lenne neki szabad. Egy kretén példán bemutatva: a videólejátszó alkalmazás lefoglal magának egy helyet a memóriában, arra a célra, hogy oda beteszti a videó feliratának egy sorát, amire mondjuk azt mondja, legyen 1024 bájt. Ebbe belefér minden normális felirat, de ha geci vagyok, és olyan feliratot csinálok, aminek az egyik sora ezt meghaladja, több dolog történhet. A jó eset, hogy a program ezt kezeli, és max annyi történik, hogy nem látom a felirat egészét. A rossz pedig ha nem kezeli. Ilyenkor fogja, és a feliratot elkezdi bemásolni a kijelölt memóriaterületre. Az első 1024 probléma nélkül felmegy, a probléma ezután kezdődik. Ugyanis ha memóriában a ezen 1024 bájt után megint egy puffer áll, akkor abba íródik bele, holott lehet, hogy az a log puffere. De állhat ezután olyan adat is, ami a későbbiekben utasításként fog értelmeződni. Ekkor olyan feliratot csinálok, ami gépi kódot töltet erre a memóriaterületre, így fordulhatnak elő az ilyen hibák.

A jelenlegi felfogás az, hogy minden (nem kernel szintű) program egy virtuális gépet lát, ami többek között azt jelenti, hogy processz ami memóriaterületet lát, azt csak ő látja, és ő sem látja másik folyamat memóriaterületét. Ha memóriára van szüksége (allokálna magának), akkor az operációs rendszertől kap, ami nyilván tartja, hogy milyeneket adott ki (egyszerre egy nagyobb címtartományt ad ki, ún. lapokat), és gondoskodik arról, hogy azt más user-space program ne lássa. Erre van szoftver, illetve leginkább hardvertámogatás. (Az előző példánál maradva így az is megeshet, hogy amikor túlírom az 1024 bájot, akkor oda írnék, ami az oprendszer szerint nem az egyim, ekkor keletkezik a segfault, és a process futása megszakítódik).

A megoldások alapvetően mind ugyanazon sémára dolgoznak: válasszuk szét a végrehajtandó kódot és az adatot. Ilyen megoldások a Harvard architektúrájú rendszerek, ahol külön van utasítás-memória és adatmemória. Ez jelenleg elsősorban mikrovezérlőkre jellemző. (Ezeknek a cpu-knak is gyakran van olyan utasítása, amivel a két tár szerepe megcserélhető (debug okokból), de ilyenkor az kell, hogy az utasítás-memóriába eleve legyen ilyen utasítás, ami release buildeknél nem jellemző, illetve hogy az adott cpu-prioritás szinten ezen utasítás legyen engedélyezve.) Megjegyzendő, hogy a modern processzorok L1 cache és alatt ugyan harvard architektúrájúak, csak kifele mutatnak Neumann architektúrát, de a cache elévülési mechanizmusok okán a D-cache tartalma bármikor átkerülhet az I-cachebe.

A másik, sok processzoron implementált fícsör a memórialapok futattás-megtagadás bittel való ellátása. Ekkor már fordítás-időben az adatnak fenntartott helyen megtiltódik a kódvégrehajtás (ez is hardveres védelem, ilyenkor a processzor ugyanúgy értesíti az operációsrendszert, mint pl. laphiba esetén). Ezzel ugye megint több gond van: egyfelől nem véd, mert még mindig írhatok utasításokat tartamazó lapokra, legfeljebb megnehezíti azt, de sok körültekintést igényel. (pl: az allokálni kívánt terület adatnak lesz (triviális), vagy esetleg valamilyen dinamikusan linkelt függvénykönyvtáré lesz, ami ugye megint végrehajtható).

Szóval a dolog kb. ennyi, remélem még mások is hozzátesznek.