„DLL hell” változatai közötti eltérés
[ellenőrzött változat] | [ellenőrzött változat] |
22. sor: | 22. sor: | ||
* A Windows alkalmazások jogosultak voltak arra, hogy telepítőjük frissítéseket végezzen az operációs rendszeren. Sok Microsoft DLL szabadon terjeszthető volt, saját verziójukat telepítették. |
* A Windows alkalmazások jogosultak voltak arra, hogy telepítőjük frissítéseket végezzen az operációs rendszeren. Sok Microsoft DLL szabadon terjeszthető volt, saját verziójukat telepítették. |
||
* A Windows Installer előtt a telepítőket a fejlesztők készítették, így akár figyelmetlenségből vagy tapasztalatlanságból is elronthatták a verziók kezelését. A fejlesztőkörnyezetek sem mind adták hozzá automatikusan a megfelelő verziót. Csak arra volt lehetőség, hogy ellenőrizzék az adatokat, felülírják a fájlokat vagy kihagyják a felülírást, ha már telepítve van a DLL. |
* A Windows Installer előtt a telepítőket a fejlesztők készítették, így akár figyelmetlenségből vagy tapasztalatlanságból is elronthatták a verziók kezelését. A fejlesztőkörnyezetek sem mind adták hozzá automatikusan a megfelelő verziót. Csak arra volt lehetőség, hogy ellenőrizzék az adatokat, felülírják a fájlokat vagy kihagyják a felülírást, ha már telepítve van a DLL. |
||
* Néha az operációs rendszer is régebbiekre cserélt DLL-eket, amelyek akár elavultak is lehettek. Így például ha egy színes nyomtató után fekete-fehér nyomtatót telepítettek, akkor a színeket ismerő nyomtató DLL-eket felülírta színeket nem ismerő DLL-ekkel. |
* Néha az operációs rendszer is régebbiekre cserélt DLL-eket, amelyek akár elavultak is lehettek. Így például ha egy színes nyomtató után fekete-fehér nyomtatót telepítettek, akkor a színeket ismerő nyomtató DLL-eket felülírta színeket nem ismerő DLL-ekkel.<ref>[http://support.microsoft.com/kb/830490 KB 830490: HP Color LaserJet printer prints only in grayscale or in black-and-white on your Windows 2000 SP4-based computer<!-- Bot generated title -->].</ref> |
||
==Okai== |
==Okai== |
A lap 2018. október 24., 09:32-kori változata
A DLL-hell (DLL pokol) egy színes kifejezés arra a helyzetre, amikor a Windows operációs rendszer képtelen helyesen kezelni a telepített DLL-eket (dinamikus linkelésű könyvtárakat). Az általánosabb verziópokol speciális este. Ennek több oka is lehet:
- A futtatott DLL számára szükséges másik DLL nem található vagy inkompatibilis a verziója;
- Ugyanannak a DLL-nek több verziója is fenn van a rendszeren;
Bővebben
A DLL-ek lényege, hogy több program is használhatja ugyanazokat az eljárásokat, így memóriát és lemezterületet takarítva meg, valamint a programok készítése is egyszerűsödik, mivel ugyanazt a rutineljárást csak egyszer kell elkészíteni. A statikus könyvtárakat az egyes programok tartalmazzák, így növelik azok méretét. Azonban, ha egy új program úgy telepít egy DLL-t, hogy felülírja annak régebbi változatát, ez eredményezheti, hogy régebb telepített programok (amelyek a régi DLL-t használták) többet nem fognak futni, vagy hibásan működnek.
A DLL-ekbe nincs beépítve a visszafelé kompatibilitás. Emiatt még a kisebb változások miatt is olyan DLL fordulhat, melynek belső szerkezete annyira különbözik az előzőektől, hogy a korábbi verziókat használó programok összeomlanak. A statikus könyvtárakkal nincs ilyen probléma, mivel azok együtt vannak a program többi részével, egy egységben.
A DLL-ek szerkezetének változása azért olyan fontos, mivel a kliens programok a bennük található adattípusokat, függvényeket és eljárásokat aszerint hivatkozzák, hogy hányadikként szerepelnek a DLL-ekben.
Okozhatja a káoszt az is, ha egy alkalmazás nem törli le a csak általa használt DLL-t, mikor a rendszerből eltávolítják. Konfliktusba kerülhetnek különböző verziók vagy nehéz lehet megszerezni a szükséges DLL-eket.
Extrém esetben ez az operációs rendszer teljes összeomlását is eredményezheti: a Microsoft Windows rendszerekben ez kék halálként ismeretes.
A Microsoft már előzetesen megpróbált megoldást találni. A .Net keretrendszerben az assemblyk nyújtanak lehetséges alternatívát.
Összeférhetetlenség
Egy DLL adott verziója megfelelő lehet egyes programok számára, míg mások számára nem. A Windows is sebezhetővé vált, mivel támogatta a dinamikus linkelést a C++ könyvtárak és az Object Linking and Embedding (OLE) objektumok között. A C++ osztályok exportálják metódusaikat, de például már az is inkompatibilitást okozhat, hogy hozzáadnak egy új metódust vagy virtuálissá tehetnek egy már létezőt. Ezt az Object Linking and Embedding megpróbálja úgy kivédeni, hogy az interfészeknek stabilnak kell maradniuk, és a memóriakezelők nem közösek. Ez azonban nem elégséges, mivel a szemantika is változhat. Egy alkalmazás javítása okozhatja azt, hogy egy másikban elvész egy képesség. A Windows 2000 előtti Windowsok sebezhetőségét okozta, hogy közösek voltak a COM osztálytáblák a felhasználók és a folyamatok között. Egy DLL/EXE csak egy COM-ot definiálhatott; ha egy programnak szüksége volt ennek egy példányára, akkor mindig csak a központit kaphatta. Emiatt, ha egy új program a DLL új verzióját telepítette, azzal használhatatlanná tehette a gépen már meglevő programokat.
Régebbi verziók
Nemcsak az újabb, hanem a korábbi verziók is okozhatnak problémát. A Windows 3.1-ben gyakori probléma volt a ctl3d.dll és a ctl3dv2.dll felülírása. Ezeket a Microsoft hozta létre, de a telepített programok nem az aktuális, hanem a korábbi verziókkal érkeztek, és írták felül.[1] DLL stomping occurs because:
- A Microsoft a múltban futás idejű DLL-eket osztott meg, mint megosztott rendszer komponenseket (eredetileg C:\WINDOWS és C:\WINDOWS\SYSTEM).[2] Ezzel próbáltak takarékoskodni a hellyel és a memóriával. Ezt a többi fejlesztő csak lemásolta.
- A telepítők rendszerint privilegizált szinten futnak, hogy jogosultak arra, hogy DLL-eket telepítsenek rendszerkönyvtárba, DLL-eket és COM-okat regisztráljanak. Egy nem megfelelően működő telepítő emiatt a rendszer DLL-eket legacy verziókkal írhatja felül. Ezen nem segíthet sem a Windows File Protection, sem a Windows Resource Protection. A Windows Vistától kezdve csak megbízható telepítő szerezhet ilyen jogosultságot.
- A Windows alkalmazások jogosultak voltak arra, hogy telepítőjük frissítéseket végezzen az operációs rendszeren. Sok Microsoft DLL szabadon terjeszthető volt, saját verziójukat telepítették.
- A Windows Installer előtt a telepítőket a fejlesztők készítették, így akár figyelmetlenségből vagy tapasztalatlanságból is elronthatták a verziók kezelését. A fejlesztőkörnyezetek sem mind adták hozzá automatikusan a megfelelő verziót. Csak arra volt lehetőség, hogy ellenőrizzék az adatokat, felülírják a fájlokat vagy kihagyják a felülírást, ha már telepítve van a DLL.
- Néha az operációs rendszer is régebbiekre cserélt DLL-eket, amelyek akár elavultak is lehettek. Így például ha egy színes nyomtató után fekete-fehér nyomtatót telepítettek, akkor a színeket ismerő nyomtató DLL-eket felülírta színeket nem ismerő DLL-ekkel.[3]
Okai
A DLL-ek között konfliktust okozhatnak a következők:
- A memória korlátjai, 16 bites Windowsoknál az, hogy a folyamatoknak nincs külön memóriatere.
- A DLL-ekbe nincs beépítve a visszafelé kompatibilitás. Nincs konvenció a verziókra, nincsenek szabványok az elnevezésekre, hiányoznak a fájlrendszer lokalizációs szabályok.
- Nincs kikényszeríthető szabványos módszer a telepítésre és eltávolításra (csomagkezelés)
- Nincs központosított támogatás a DLL bináris alkalmazói interfészek kezelésére és védelmére, emiatt lehetnek összeférhetetlen DLL verziók ugyanazzal a névvel és belső verziószámozással.
- Túlegyszerűsített kezelőeszközök, amelyek nem segítik, hogy a felhasználók megtalálják, hogy melyik DLL okozta a problémát.
- Az elosztott modulok fejlesztői megtörhetik a visszafelé kompatibilitást.
- Az operációs rendszer futásidejű komponenseinek frissítési rendszere.
- A régebbi Windows verziók képtelensége arra, hogy több verziót futtassanak egy adott könyvtárból.
- Az aktuális könyvtárra vagy a %PATH% környezeti változóra hagyatkozás, amikor a DLL-eket keresi a gép.
- A fejlesztőknek meg van engedve, hogy újrahasználják alkalmazásaik COM interfészeinek minta alkalmazásainak ClassID-jét, holott generálhatnának új GUID-eket.
A Windows NT előtti verziókban gyakori jelenség volt a DLL-pokol. Ez főként amiatt volt, hogy a 16 bites Windowsok nem különítették el az egyes alkalmazások által használt memóriát, emiatt nem tölthették be saját verziójukat az osztott könyvtárra. A telepítőktől elvárták, hogy verifikálják DLL-információjukat, mielőtt felülírják a rendszer DLL-eket. A Microsoft és mások különböző eszközöket adtak a fejlesztések megkönnyítésére, amelyek magukkal vitték a rendszer DLL-eket. A terjesztőknek szabvány telepítőt kellett használniuk, aminek megfelelően kellett működnie, mielőtt megkapták a Microsoft logót. A jó polgár megközelítés nem segítette a probléma kezelését, mivel az Internet terjedése miatt számos más programot lehetett letölteni és telepíteni, amelyek nem feltétlenül viselkedtek jó polgár módjára.
A problémák nagy része még azóta is fennáll, amit kihasználnak a kártevők készítői is. Ez további sebezhetőséget jelent, ami érint minden programterjesztőt, aki Windowsra ad ki programokat, köztük a Microsoftot is.[4]
Hasonló problémák más operációs rendszerek alatt
A "DLL hell", magyarul "DLL pokol" szakkifejezés definíció szerint kizárólag Windows operációs rendszerre vonatkozhat, mivel a több processz által is használható megosztott eljáráskönyvtárakat egyedül itt hívják DLL-nek, ugyanis eredetileg ez a kiterjesztés tartozott hozzájuk.
Ugyanakkor megosztott eljáráskönyvtárak minden modernebb operációs rendszerben előfordulnak, csak a nevük más. Például Linux/Unix rendszerekben shared lib a nevük. A "DLL hell" probléma megfelelője elvileg velük kapcsolatban is előállhat, ám a ma használatos Linux rendszerek esetén több tényező is gátat vet neki:
- Linux (és a legtöbb Unix) alatt a kernel és a userspace folyamatok mind koncepcionálisan, mind strukturálisan élesen elhatárolódnak. Teljes rendszerleállást csak kernelhiba tud okozni, ám a shared libek teljes mértékben userspace-ben vannak. Ezért bármilyen shared lib-eredetű programhiba csak egyes programok hibás működését tudja okozni, magát a rendszert nem állíthatja le.
- A rendszer nyílt forráskódú volta miatt az egyes shared libek kezelői felülete is teljes mértékben megismerhető, és általában jól is dokumentált, ezért könnyebb őket a különböző verzióik között egymással kompatibilisre megírni
- A rendszer dinamikus linkere felhasználóként, akár futásidőben is beállítható, ezért nagyon könnyen kivitelezhető, hogy az egyes szoftverek más és más shared libeket használjanak. Erre szolgáló mechanizmus később a Windows-ban is megjelent (GAC: Global Assembly Cache).
- ↑ A summary of CTL3D.DLL articles in Microsoft Support Knowledge Base. Microsoft
- ↑ Redistribution of the shared C runtime component in Visual C++ 2005 and in Visual C++ .NET.
- ↑ KB 830490: HP Color LaserJet printer prints only in grayscale or in black-and-white on your Windows 2000 SP4-based computer.
- ↑ Secure Loading of Libraries to Prevent DLL Preloading Attacks. Microsoft, 2011. június 11. (Hozzáférés: 2011. július 19.)