Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Ugrás a tartalomhoz

„DLL hell” változatai közötti eltérés

A Wikipédiából, a szabad enciklopédiából
[ellenőrzött változat][ellenőrzött változat]
Tartalom törölve Tartalom hozzáadva
→‎Okai: Megoldások
→‎Megoldások: Windows File Protection
51. sor: 51. sor:
==Megoldások==
==Megoldások==
A probléma kezelésére számos megoldást gondoltak ki.
A probléma kezelésére számos megoldást gondoltak ki.
===Statikus linkelés===

A statikus linkelés megkerüli a problémát azzal, hogy egyáltalán nem használ dinamikus linkelést.<ref name="threatormenace"/> C/C++ alkalmazásoknál gyakori, hogy ahelyett, hogy amiatt kellene aggódni, hogy milyen verziója van telepítve például a <code>MFC42.DLL</code> könyvtárnak, az alkalmazás statikusan linkeli ugyanazokat a könyvtárakat. Ezzel viszont csak azokra a könyvtárakra korlátozza magát, melyek statikusan linkelhetők. Ez a megoldás feláldozza azt a célt is, amire a DLL-eket használják: hogy csökkentse a memóriahasználatot. A könyvtári kód duplikálásával a [[Szoftverek felfúvódása|szoftverek mérete megnő]]. Bonyolultabbá válnak a biztonsági frissítések és a függőségek új verzióinak telepítése.
A statikus linkelés megkerüli a problémát azzal, hogy egyáltalán nem használ dinamikus linkelést.<ref name="threatormenace"/> C/C++ alkalmazásoknál gyakori, hogy ahelyett, hogy amiatt kellene aggódni, hogy milyen verziója van telepítve például a <code>MFC42.DLL</code> könyvtárnak, az alkalmazás statikusan linkeli ugyanazokat a könyvtárakat. Ezzel viszont csak azokra a könyvtárakra korlátozza magát, melyek statikusan linkelhetők. Ez a megoldás feláldozza azt a célt is, amire a DLL-eket használják: hogy csökkentse a memóriahasználatot. A könyvtári kód duplikálásával a [[Szoftverek felfúvódása|szoftverek mérete megnő]]. Bonyolultabbá válnak a biztonsági frissítések és a függőségek új verzióinak telepítése.
===Windows File Protection===
A DLL felülírási problémát mérsékli a Windows File Protection,<ref>[http://www.microsoft.com/whdc/winlogo/drvsign/wfp.mspx Windows File Protection and Windows].</ref> amit a [[Windows 2000]]-ben vezették be.<ref name="endofdllhell"/> Ez megelőzi, hogy nem igazolt alkalmazások felülírjanak rendszer DLL-ek, hacsak nem használnak bizonyos meghatározott [[Windows API]]-t, ami ezt megengedi. Továbbra is fennáll az a kockázat, hogy a Microsoft frissítések összeférhetetlenek egyes alkalmazásokkal, de ezt a kockázatot csökkenti a side-by-side assemblyk használata.

Más telepítők nem írhatják felül a rendszer DLL-eket, hacsak nem kötik be a Windows updatert is. Lehetséges még a Windows File Protection letiltása, vagy a Windows Vistától kezdődően a fájlrendszer birtokba vétele és saját maguk feljogosítása. Ezeket a változásokat azonban a [[System File Checker|SFC]] vissza tudja állítani.


== Hasonló problémák más operációs rendszerek alatt ==
== Hasonló problémák más operációs rendszerek alatt ==

A lap 2018. október 25., 19:48-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).[1] 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.[2] Okai:

  • A Microsoft a múltban futás idejű DLL-eket osztott meg, mint megosztott rendszer komponenseket (eredetileg C:\WINDOWS és C:\WINDOWS\SYSTEM).[3] 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.[4]

Inkorrekt COM regisztráció

A side-by-side assemblyk előtt a Registry döntött arról, hogy melyik DLL-t kell használni.[5] Ha a modul egy másik verziója van regisztrálva, akkor az fog betöltődni, és nem az, amit a felhasználó elvár. Okozhatják ütköző telepítések, amelyek ugyanabba a könyvtárba települnek; ekkor az utolsó telepítés verziója érvényes.

Megosztott modulok a memóriában

A 16 bites Windowsok (és a Windows on Windows) egy adott DLL egy példányát töltik be. Minden alkalmazás ezt használja. Ha már nincs rá szükség, akkor törlődik a memóriából. A többi (32 illetve 64 bites) Windowson csak akkor osztoznak programok egy példányon, ha ugyanazt a megosztott DLL-t töltötték be. Így, ha egy program már betöltötte a modult egy másik könyvtárban, akkor nem indítható egy másik program, ami egy ezzel összeférhetetlen verziót használ. Ehhez előbb az összes, az ütköző verziót használó programot be kell zárni, és utána ezt elindítani. Előfordulhat, hogy ezután a másik program újra elindítható; így a probléma csak akkor jelentkezik, ha nem a megfelelő sorrendbe indították az alkalmazásokat.

Használhatóság

Ha egy DLL frissítése nem rontja el az összes programot, ami használja, akkor nehezebb a DLL verziójával kapcsolatos problémákat kezelni. A biztonsági frissítések sürgető és fájdalmas esetek. Ahelyett, hogy csak a legújabb verziót vizsgálná, minden korábbi verziót is tesztelni kell összeférhetőség szempontjából.

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.[6]

Megoldások

A probléma kezelésére számos megoldást gondoltak ki.

Statikus linkelés

A statikus linkelés megkerüli a problémát azzal, hogy egyáltalán nem használ dinamikus linkelést.[7] C/C++ alkalmazásoknál gyakori, hogy ahelyett, hogy amiatt kellene aggódni, hogy milyen verziója van telepítve például a MFC42.DLL könyvtárnak, az alkalmazás statikusan linkeli ugyanazokat a könyvtárakat. Ezzel viszont csak azokra a könyvtárakra korlátozza magát, melyek statikusan linkelhetők. Ez a megoldás feláldozza azt a célt is, amire a DLL-eket használják: hogy csökkentse a memóriahasználatot. A könyvtári kód duplikálásával a szoftverek mérete megnő. Bonyolultabbá válnak a biztonsági frissítések és a függőségek új verzióinak telepítése.

Windows File Protection

A DLL felülírási problémát mérsékli a Windows File Protection,[8] amit a Windows 2000-ben vezették be.[9] Ez megelőzi, hogy nem igazolt alkalmazások felülírjanak rendszer DLL-ek, hacsak nem használnak bizonyos meghatározott Windows API-t, ami ezt megengedi. Továbbra is fennáll az a kockázat, hogy a Microsoft frissítések összeférhetetlenek egyes alkalmazásokkal, de ezt a kockázatot csökkenti a side-by-side assemblyk használata.

Más telepítők nem írhatják felül a rendszer DLL-eket, hacsak nem kötik be a Windows updatert is. Lehetséges még a Windows File Protection letiltása, vagy a Windows Vistától kezdődően a fájlrendszer birtokba vétele és saját maguk feljogosítása. Ezeket a változásokat azonban a SFC vissza tudja állítani.

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).
  1. Avoiding DLL Hell: Introducing Application Metadata in the Microsoft .NET Framework. Microsoft, 2000. október 1.
  2. A summary of CTL3D.DLL articles in Microsoft Support Knowledge Base. Microsoft
  3. Redistribution of the shared C runtime component in Visual C++ 2005 and in Visual C++ .NET.
  4. KB 830490: HP Color LaserJet printer prints only in grayscale or in black-and-white on your Windows 2000 SP4-based computer.
  5. Registration-Free Activation of COM Components: A Walkthrough. Microsoft, 2005. július 1.
  6. Secure Loading of Libraries to Prevent DLL Preloading Attacks. Microsoft, 2011. június 11. (Hozzáférés: 2011. július 19.)
  7. Forráshivatkozás-hiba: Érvénytelen <ref> címke; nincs megadva szöveg a(z) threatormenace nevű lábjegyzeteknek
  8. Windows File Protection and Windows.
  9. Forráshivatkozás-hiba: Érvénytelen <ref> címke; nincs megadva szöveg a(z) endofdllhell nevű lábjegyzeteknek