Dynamiczna aktualizacja oprogramowania
W informatyce dynamiczna aktualizacja oprogramowania ( DSU ) to dziedzina badań dotyczących aktualizacji programów podczas ich działania. DSU nie jest obecnie szeroko stosowany w przemyśle. Jednak naukowcy opracowali szeroką gamę systemów i technik wdrażania DSU. Systemy te są powszechnie testowane w rzeczywistych programach.
Obecne systemy operacyjne i języki programowania zwykle nie są projektowane z myślą o DSU. W związku z tym implementacje DSU zwykle wykorzystują istniejące narzędzia lub implementują specjalistyczne kompilatory . Kompilatory te zachowują semantykę oryginalnego programu, ale opracowują kod źródłowy lub kod obiektowy w celu utworzenia programu, który można aktualizować dynamicznie. Badacze porównują warianty programów obsługujące DSU z oryginalnym programem, aby ocenić ogólne bezpieczeństwo i wydajność.
Wstęp
traktować jako krotkę , gdzie jest programu i programu . Dynamiczne systemy aktualizacji program w wersję ) Aby to zrobić, stan musi zostać przekształcony w reprezentację . Wymaga to transformatora stanu . W ten sposób przekształca program w program ' Aktualizacja jest uważana za ważną wtedy i tylko wtedy, gdy działający program można do krotki punktowej , który jest osiągalny od punktu początkowego nowej wersji programu, .
Miejsce w programie, w którym następuje aktualizacja dynamiczna, jest określane jako punkt aktualizacji . Istniejące implementacje DSU różnią się znacznie pod względem traktowania punktów aktualizacji. W niektórych systemach, takich jak UpStare i PoLUS , aktualizacja może nastąpić w dowolnym momencie podczas wykonywania. Kompilator Ginseng spróbuje wywnioskować dobre lokalizacje dla punktów aktualizacji, ale może również użyć punktów aktualizacji określonych przez programistę. Kitsune i Ekiden wymagają od programistów ręcznego określenia i nazwania wszystkich punktów aktualizacji.
Systemy aktualizacji różnią się typami zmian w programach, które obsługują. Na przykład Ksplice obsługuje tylko zmiany kodu w funkcjach i nie obsługuje zmian w reprezentacji stanu. Dzieje się tak dlatego, że Ksplice koncentruje się przede wszystkim na zmianach w zabezpieczeniach, a nie na ogólnych aktualizacjach. Natomiast Ekiden może zaktualizować program do dowolnego innego możliwego do wykonania programu, nawet napisanego w innym języku programowania. Projektanci systemów mogą uzyskać cenne gwarancje wydajności lub bezpieczeństwa poprzez ograniczenie zakresu aktualizacji. Na przykład każda kontrola bezpieczeństwa aktualizacji ogranicza zakres aktualizacji do aktualizacji, które pomyślnie przejdą tę kontrolę bezpieczeństwa. Mechanizm używany do przekształcania kodu i stanu wpływa na to, jakiego rodzaju aktualizacje będą obsługiwane przez system.
Systemy DSU, jako narzędzia, można również oceniać pod kątem łatwości użytkowania i przejrzystości dla programistów. Wiele systemów DSU, takich jak Żeń-szeń , wymaga, aby programy przechodziły różne analizy statyczne. Chociaż analizy te dowodzą właściwości programów cennych dla DSU, są one z natury wyrafinowane i trudne do zrozumienia. Systemy DSU, które nie korzystają z analizy statycznej, mogą wymagać użycia specjalistycznego kompilatora. Niektóre systemy DSU nie wymagają analizy statycznej ani specjalnych kompilatorów.
Programy aktualizowane przez system DSU są nazywane programami docelowymi . Publikacje naukowe dotyczące systemów DSU zwykle obejmują kilka programów docelowych jako studia przypadków. vsftpd , OpenSSH , PostgreSQL , Tor , Apache , GNU Zebra , memcached i Redis to dynamiczne cele aktualizacji dla różnych systemów. Ponieważ niewiele programów jest napisanych z myślą o obsłudze aktualizacji dynamicznych, modernizacja istniejących programów jest cennym sposobem oceny systemu DSU pod kątem praktycznego zastosowania.
Powiązane pola
Przestrzeń problemowa, której dotyczy aktualizacja dynamiczna, może być traktowana jako przecięcie kilku innych. Przykłady obejmują punkty kontrolne , łączenie dynamiczne i trwałość . Na przykład baza danych, która musi być wstecznie kompatybilna z poprzednimi wersjami swojego formatu plików na dysku, musi wykonywać ten sam typ transformacji stanu, jakiego oczekuje się od dynamicznego systemu aktualizacji. Podobnie program, który ma architekturę wtyczek, musi być w stanie załadować i wykonać nowy kod w czasie wykonywania.
Podobne techniki są czasami stosowane w celu dynamicznej eliminacji martwego kodu w celu usunięcia warunkowo martwego lub nieosiągalnego kodu podczas ładowania lub w czasie wykonywania oraz ponownego połączenia pozostałego kodu w celu zminimalizowania zużycia pamięci lub poprawy szybkości.
Historia
Najwcześniejszym prekursorem dynamicznej aktualizacji oprogramowania są systemy redundantne . W redundantnym środowisku istnieją systemy zapasowe gotowe do przejęcia kontroli nad aktywnymi obliczeniami w przypadku awarii głównego systemu. Systemy te zawierają maszynę główną i zapasową . Gorąca rezerwa byłaby okresowo zapełniana punktem kontrolnym systemu podstawowego. W przypadku awarii zastępstwo zastępcze przejęłoby działanie, a maszyna główna stałaby się nową maszyną zapasową. Ten wzorzec można uogólnić do aktualizacji. W przypadku aktualizacji aktywowałby się zapasowy, system główny aktualizowałby się, a następnie zaktualizowany system wznowiłby kontrolę.
Najwcześniejszym prawdziwym systemem dynamicznej aktualizacji oprogramowania jest DYMOS ( Dynamic Modification System ) . Zaprezentowany w 1983 roku w rozprawie doktorskiej Insup Lee, DYMOS był w pełni zintegrowanym systemem, który miał dostęp do interaktywnego interfejsu użytkownika, kompilatora i środowiska uruchomieniowego dla wariantu Modula oraz kodu źródłowego. Umożliwiło to firmie DYMOS sprawdzenie typu aktualizacji względem istniejącego programu.
Realizacja
Systemy DSU muszą załadować nowy kod do działającego programu i przekształcić istniejący stan do formatu zrozumiałego dla nowego kodu. Ponieważ wiele motywacyjnych przypadków użycia DSU ma krytyczne znaczenie czasowe (na przykład wdrożenie poprawki bezpieczeństwa w działającym i podatnym na ataki systemie), systemy DSU muszą zapewniać odpowiednią dostępność aktualizacji . Niektóre systemy DSU próbują również upewnić się, że aktualizacje są bezpieczne przed ich zastosowaniem.
Nie ma jednego kanonicznego rozwiązania żadnego z tych problemów. Zazwyczaj system DSU, który działa dobrze w jednym obszarze problemowym, robi to kosztem innych. Na przykład empiryczne testy aktualizacji dynamicznych wskazują, że zwiększenie liczby punktów aktualizacji powoduje zwiększenie liczby niebezpiecznych aktualizacji.
Transformacja kodu
Większość systemów DSU używa podprogramów jako jednostki kodu dla aktualizacji; jednak nowsze systemy DSU implementują aktualizacje całego programu.
Jeśli program docelowy jest zaimplementowany w języku maszyny wirtualnej , maszyna wirtualna może wykorzystać istniejącą infrastrukturę do załadowania nowego kodu, ponieważ nowoczesne maszyny wirtualne obsługują ładowanie w czasie wykonywania w innych przypadkach użycia niż DSU (głównie debugowanie ). HotSpot JVM obsługuje ładowanie kodu wykonawczego, a systemy DSU ukierunkowane na język Java (język programowania) mogą korzystać z tej funkcji.
W językach rodzimych, takich jak C lub C++ , systemy DSU mogą używać wyspecjalizowanych kompilatorów, które wstawiają do programu pośrednictwo. W czasie aktualizacji to przekierowanie jest aktualizowane, aby wskazywało najnowszą wersję. Jeśli system DSU nie używa kompilatora do statycznego wstawiania tych wskazówek, wstawia je w czasie wykonywania z przepisywaniem binarnym . Przepisywanie binarne to proces zapisywania kodu niskiego poziomu w obrazie pamięci działającego programu natywnego w celu przekierowania funkcji. Chociaż nie wymaga to statycznej analizy programu, jest wysoce zależne od platformy.
Ekiden i Kitsune ładują nowy kod programu, uruchamiając zupełnie nowy program, albo przez fork-exec , albo ładowanie dynamiczne . Istniejący stan programu jest następnie przenoszony do nowej przestrzeni programu.
Transformacja państwa
Podczas aktualizacji stan programu musi zostać przekształcony z pierwotnej reprezentacji na reprezentację nowej wersji. Nazywa się to transformacją stanu . Funkcja, która przekształca obiekt stanu lub grupę obiektów, nazywana jest funkcją transformatora lub transformatorem stanu .
Systemy DSU mogą albo próbować zsyntetyzować funkcje transformatora, albo wymagać ręcznego dostarczenia ich przez programistę. Niektóre systemy łączą te podejścia, wnioskując o niektórych elementach transformatorów, podczas gdy inne wymagają wkładu programisty.
Te funkcje transformatora można zastosować do stanu programu leniwie, gdy uzyskuje się dostęp do każdego fragmentu stanu starej wersji, lub chętnie, przekształcając cały stan w czasie aktualizacji. Leniwa transformacja zapewnia, że aktualizacja zakończy się w stałym czasie, ale powoduje również narzut związany z dostępem do obiektu w stanie ustalonym. Chętna transformacja wiąże się z większymi kosztami w momencie aktualizacji, co wymaga od systemu zatrzymania świata , podczas gdy wszystkie transformatory działają. Jednak chętna transformacja pozwala kompilatorom w pełni zoptymalizować dostęp do stanu, unikając narzutu stanu ustalonego związanego z leniwą transformacją.
Zaktualizuj bezpieczeństwo
Większość systemów DSU próbuje pokazać pewne właściwości bezpieczeństwa dla aktualizacji. Najpopularniejszym wariantem sprawdzania bezpieczeństwa jest sprawdzanie typu, w którym aktualizacja jest uważana za bezpieczną, jeśli nie spowoduje, że nowy kod będzie działał na starej reprezentacji stanu lub odwrotnie.
Bezpieczeństwo typu jest zwykle sprawdzane przez pokazanie jednej z dwóch właściwości, bezpieczeństwa aktywności lub bezpieczeństwa wad . Program jest uważany za bezpieczny pod względem aktywności, jeśli w czasie aktualizacji nie istnieje żadna zaktualizowana funkcja na stosie wywołań . Dowodzi to bezpieczeństwa, ponieważ kontrola nigdy nie może powrócić do starego kodu, który miałby dostęp do nowych reprezentacji danych.
Cons-Freeness to kolejny sposób na udowodnienie bezpieczeństwa typu, gdzie sekcja kodu jest uważana za bezpieczną, jeśli nie uzyskuje dostępu do stanu danego typu w sposób wymagający znajomości reprezentacji typu. Można powiedzieć, że ten kod nie uzyskuje dostępu do stanu w sposób konkretny , podczas gdy może uzyskiwać dostęp do stanu w sposób abstrakcyjny . Możliwe jest udowodnienie lub obalenie przeciwności dla wszystkich typów w dowolnej sekcji kodu, a system DSU Żeń-szeń wykorzystuje to do udowodnienia bezpieczeństwa typów. Jeśli udowodniono, że funkcja jest pozbawiona wad , można ją zaktualizować, nawet jeśli jest na stosie, ponieważ nie spowoduje błędu typu, uzyskując dostęp do stanu przy użyciu starej reprezentacji.
Empiryczna analiza bezkarności i bezpieczeństwa aktywności przeprowadzona przez Haydena i in. pokazują, że obie techniki zezwalają na większość poprawnych aktualizacji i odrzucają większość błędnych aktualizacji. Jednak ręczne wybranie punktów aktualizacji powoduje zerowe błędy aktualizacji i nadal zapewnia częstą dostępność aktualizacji.
Istniejące systemy
DYMO
DYMOS wyróżnia się tym, że był to najwcześniejszy proponowany system DSU. DYMOS składa się z w pełni zintegrowanego środowiska dla programów napisanych w pochodnej Moduli , dając systemowi dostęp do interpretera poleceń, kodu źródłowego, kompilatora i środowiska uruchomieniowego, podobnego do REPL . W systemie DYMOS aktualizacje są inicjowane przez użytkownika, który wykonuje polecenie w środowisku interaktywnym. To polecenie zawiera dyrektywy określające, kiedy może nastąpić aktualizacja, nazywane when-conditions . Informacje dostępne firmie DYMOS umożliwiają egzekwowanie bezpieczeństwa aktualizacji w odniesieniu do uruchomionego programu docelowego.
Ksplice, kpatch i kGraft
Ksplice to system DSU, który jest przeznaczony tylko dla jądra Linuksa , co czyni go jednym z wyspecjalizowanych systemów DSU, które obsługują jądro systemu operacyjnego jako program docelowy. Ksplice używa różnic na poziomie źródła , aby określić zmiany między bieżącymi i zaktualizowanymi wersjami jądra Linuksa, a następnie używa przepisywania binarnego, aby wstawić zmiany do działającego jądra. Ksplice było utrzymywane przez komercyjne przedsięwzięcie założone przez jego pierwotnych autorów, Ksplice Inc., które zostało przejęte przez Oracle Corporation w lipcu 2011 r. Ksplice jest używane na zasadach komercyjnych i wyłącznie w dystrybucji Oracle Linux .
SUSE opracowało kGraft jako otwartą alternatywę dla łatania jądra na żywo, a Red Hat zrobił to samo z kpatch . Oba pozwalają na zastosowanie zmian na poziomie funkcji do działającego jądra Linuksa, opierając się na mechanizmach łatania na żywo ustanowionych przez ftrace . Podstawową różnicą między kGraft i kpatch jest sposób, w jaki zapewniają one spójność w czasie wykonywania zaktualizowanych sekcji kodu podczas stosowania gorących łat . kGraft i kpatch zostały przesłane do włączenia do głównej linii jądra Linuksa odpowiednio w kwietniu 2014 i maju 2014, a minimalistyczne podstawy łatania na żywo zostały włączone do głównej linii jądra Linuksa w wersji jądra 4.0, która została wydana 12 kwietnia 2015.
Od kwietnia 2015 trwają prace nad przeniesieniem kpatch i kGraft do wspólnego rdzenia łatania na żywo, dostarczanego przez główną linię jądra Linuksa. Jednak implementacja mechanizmów spójności na poziomie funkcji, wymaganych do bezpiecznego przejścia między oryginalnymi i poprawionymi wersjami funkcji, została opóźniona, ponieważ stosy wywołań zapewniane przez jądro Linuksa mogą być zawodne w sytuacjach, które obejmują kod asemblera bez odpowiednich ramek stosu ; w rezultacie prace nad przeniesieniem trwają od września 2015 r. W celu poprawy niezawodności stosów wywołań jądra opracowano również wyspecjalizowane narzędzie do sprawdzania poprawności stosu stosu użytkownika w celu sprawdzania plików obiektowych jądra w czasie kompilacji oraz zapewnienie, że stos wywołań jest zawsze utrzymywany; otwiera również możliwość uzyskania bardziej niezawodnych stosów wywołań jako części ups jądra .
Żeń-szeń
Żeń-szeń to system DSU ogólnego przeznaczenia. Jest to jedyny system DSU, który wykorzystuje cons-freeness , pozwalającą aktualizować funkcje, które są aktywne na stosie, o ile nie zapewniają one konkretnego dostępu do zaktualizowanych typów.
Żeń-szeń jest zaimplementowany jako kompilator typu source-to-source napisany przy użyciu frameworka C Intermediate Language w OCaml . Kompilator ten wprowadza pośrednictwo do wszystkich wywołań funkcji i dostępów do typów, umożliwiając Ginsengowi leniwe przekształcanie stanu kosztem narzucenia stałego narzutu czasu na całe wykonanie programu. Kompilator Ginseng udowadnia przeciw-wolnościowe całego programu początkowego i łatek dynamicznych.
Późniejsze wersje żeń-szenia również wspierają pojęcie bezpieczeństwa transakcji. Pozwala to programistom na opisywanie sekwencji wywołań funkcji jako jednostki logicznej, zapobiegając naruszaniu semantyki programu przez aktualizacje w sposób, który nie jest wykrywalny ani przez bezpieczeństwo aktywności, ani przez bezpieczeństwo wad . Na przykład w dwóch wersjach OpenSSH zbadanych przez autorów Ginseng ważny kod weryfikacyjny użytkownika został przeniesiony między dwiema funkcjami wywoływanymi kolejno. Jeśli pierwsza wersja pierwszej funkcji została wykonana, nastąpiła aktualizacja i została wykonana nowa wersja drugiej funkcji, to weryfikacja nigdy nie zostałaby przeprowadzona. Oznaczenie tej sekcji jako transakcji gwarantuje, że aktualizacja nie uniemożliwi przeprowadzenia weryfikacji.
Spojrzenie w górę
UpStare to system DSU, który wykorzystuje unikalny mechanizm aktualizacji, rekonstrukcję stosu . Aby zaktualizować program za pomocą UpStare, programista określa mapowanie między dowolnymi możliwymi ramkami stosu. UpStare jest w stanie wykorzystać to mapowanie do natychmiastowej aktualizacji programu w dowolnym momencie, z dowolną liczbą wątków i dowolnymi funkcjami działającymi na stosie.
POLUS
PoLUS jest binarnym przepisywaniem systemu DSU dla C . Jest w stanie aktualizować niezmodyfikowane programy w dowolnym momencie ich wykonywania. Aby zaktualizować funkcje, przepisuje preludium do funkcji docelowej, aby przekierować do nowej funkcji, łącząc te przekierowania w wiele wersji. Pozwala to uniknąć narzutu stanu ustalonego w funkcjach, które nie zostały zaktualizowane.
Katany
Katana to system badawczy, który zapewnia ograniczoną dynamiczną aktualizację (podobnie jak Ksplice i jego forki) dla plików binarnych ELF w trybie użytkownika . Model łatania Katana działa na poziomie obiektów ELF, a zatem może być niezależny od języka, o ile celem kompilacji jest ELF.
Kitsune i Ekiden
Ekiden i Kitsune to dwa warianty pojedynczego systemu DSU, który implementuje styl DSU z transferem stanu dla programów napisanych w C . Zamiast aktualizować funkcje w jednym programie, Ekiden i Kitsune wykonują aktualizacje całych programów, przenosząc niezbędny stan między dwoma wykonaniami. Podczas gdy Ekiden osiąga to, uruchamiając nowy program przy użyciu idiomu UNIX fork-exec , serializując stan programu docelowego i przesyłając go, Kitsune używa dynamicznego łączenia do wykonywania transferu stanu „w miejscu”. Kitsune wywodzi się z bazy kodu Ekiden i można go uznać za późniejszą wersję Ekiden.
Ekiden i Kitsune są również godne uwagi, ponieważ są implementowane głównie jako biblioteki na poziomie aplikacji, a nie wyspecjalizowane środowiska wykonawcze lub kompilatory. W związku z tym, aby korzystać z Ekiden lub Kitsune, twórca aplikacji musi ręcznie zaznaczyć stan, który ma zostać przesłany, oraz ręcznie wybrać punkty w programie, w których może nastąpić aktualizacja. Aby ułatwić ten proces, Kitsune zawiera wyspecjalizowany kompilator, który implementuje specyficzny dla domeny język do pisania transformatorów stanu.
Erlang
Erlang obsługuje dynamiczną aktualizację oprogramowania, chociaż jest to powszechnie określane jako „ ładowanie gorącego kodu ”. Erlang nie wymaga żadnych gwarancji bezpieczeństwa dla aktualizacji, ale kultura Erlang sugeruje, że programiści piszą w stylu obronnym, który z wdziękiem poradzi sobie z błędami typograficznymi generowanymi przez aktualizację. [ potrzebne źródło ]
Pymoulta
Pymoult to platforma do prototypowania dynamicznej aktualizacji napisana w Pythonie. Gromadzi wiele technik z innych systemów, umożliwiając ich łączenie i konfigurowanie. Celem tej platformy jest umożliwienie programistom wyboru technik aktualizacji, które uznają za bardziej odpowiednie dla ich potrzeb. Można np. połączyć leniwą aktualizację stanu jak w Ginseng ze zmianą całego kodu aplikacji jak w Kitsune czy Ekiden.
Microsoft VisualC++
Firma Microsoft wykorzystuje wewnętrzną technologię łatania dla programu Microsoft Visual C++, która obsługuje łatanie poszczególnych funkcji C++ przy jednoczesnym zachowaniu funkcjonalnej poprawności poprawek. Obecnie znaną aplikacją jest SQL Server w Azure SQL Database.
Zobacz też
Linki zewnętrzne
- Strona główna Ksplice
- Kod źródłowy Ksplice
- Strona projektu Ginseng i kod źródłowy/ papier UpStare/ papier PoLUS
- Strona główna Erlanga
- Strona główna Katany
- Wpis na blogu Whitepaper na temat poprawek Visual C++