2009-05-22 23 views
5

Mam zestaw aplikacji Win32, które udostępniają informacje przy użyciu segmentu pamięci współużytkowanej utworzonego z CreateFileMapping() i MapViewOfFile(). Jedną z aplikacji jest usługa systemowa; pozostałe są uruchamiane przez zalogowanego użytkownika. W systemie Windows XP nie było problemu. Nazwaliśmy nasze segmenty "Global \ Something" i wszystko było dobrze.Jak współużytkować pamięć między usługami a procesami użytkownika?

Dodatkowe zabezpieczenia w systemie Vista (i prawdopodobnie Windows 7) wydają się uniemożliwiać działanie tej architektury. Normalni użytkownicy nie mogą tworzyć obiektów (błąd Win32 5) w globalnej przestrzeni nazw. MSDN wskazuje, że jeśli konto ma uprawnienie "twórz globalne", wszystkie powinny być dobrze, ale nie wydaje się, aby tak było w praktyce. Również funkcje "integralności" Visty wydają się uniemożliwiać procesom użytkownika "niskiej integralności" dostęp do obiektu pamięci wspólnej o wysokiej integralności utworzonego przez usługę. Wygląda na to, że powinienem to naprawić za pomocą jakiegoś magicznego zaklęcia, ale mam trudności w nauce mówienia sacl.

Pytanie brzmi: Jaki jest właściwy sposób korzystania z segmentu pamięci dzielonej między usługami a normalnymi procesami użytkownika?

Aby uniknąć łatwej odpowiedzi "po prostu wyłącz UAC", jesteśmy w dość zamkniętym środowisku, a to nie jest możliwe.

Edytuj: Zarówno usługa, jak i proces użytkownika, wymagają dostępu do segmentu w trybie odczytu/zapisu.

Odpowiedz

9

Najprostszy sposób to utworzenie usługi pamięci współużytkowanej i określenie listy DACL w obszarze Utwórz plik, która zapewnia zwykłym użytkownikom prawo odczytu dostępu do pamięci współużytkowanej.

Zwykli użytkownicy nie mają uprawnień do tworzenia globalnego, ale usługi mogą mieć to uprawnienie. Jeśli musisz mieć użytkowników, którzy utworzą pamięć współużytkowaną, a następnie sondę serwisową, możesz mieć schemat IPC, w którym twój kod użytkownika wysyła wiadomość do usługi zawierającej uchwyt mapowania pliku, a usługa wywoła funkcję DuplicateHandle, aby uzyskać odniesienie do niego. To wymagałoby uruchomienia usługi z uprawnieniem do debugowania.

Najprostszym sposobem utworzenia DACL jest użycie ConvertStringSecurityDescriptorToSecurityDescriptor, który pobiera ciąg w formacie SDDL określającym listę ACL.

Writing Secure Code zawiera doskonały rozdział na temat tworzenia DACL-ów za pomocą SDDL.

// Error handling removed for brevity 
SECURITY_ATTRIBUTES security; 
ZeroMemory(&security, sizeof(security)); 
security.nLength = sizeof(security); 
ConvertStringSecurityDescriptorToSecurityDescriptor(
     L"D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GR;;;IU)", 
     SDDL_REVISION_1, 
     &security.lpSecurityDescriptor, 
     NULL); 

CreateFileMapping(INVALID_HANDLE_VALUE, &security, 
       PAGE_READWRITE, sizeHigh, sizeLow, L"Global\\MyObject"); 

LocalFree(securityDescriptor.lpSecurityDescriptor); 

"D: P (A, OICI; GA ;;; SY) (A, OICI; GA ;;; Ba) (A, OICI; GR ;;; jm)" określa DACL. D: P oznacza, że ​​jest to lista DACL (zamiast SACL ... rzadko używasz SACL), a następnie kilka ciągów ACE, które kontrolują, kto uzyskuje dostęp. Każdy z nich to A (zezwolenie) i pozwala na obiekt i zawiera dziedziczenie (OICI). Pierwszy, który przyznał wszystkim dostęp (GA - przyznać wszystko) systemowi (SY) i administratorom (BA, wbudowane administracje). Ostatnia akceptuje odczyt (GR) użytkownikom interaktywnym (IU), którzy są faktycznie zalogowani do sesji.

Po wykonaniu tej czynności normalni użytkownicy powinni móc wywoływać funkcję OpenFileMapping, aby uzyskać uchwyt do udostępnionego odwzorowania i móc zmapować go do swojego procesu. Ponieważ zwykli użytkownicy mają ograniczone prawa do obiektu, będą musieli go otworzyć i zmapować do odczytu.

Jeśli użytkownicy potrzebują zapisu, należy zastąpić GR z GWGR. Zauważ, że nie jest to bezpieczne - ograniczony użytkownik byłby wtedy w stanie modyfikować pamięć współdzieloną, podczas gdy twoja usługa czyta i próbuje analizować informacje, powodując awarię twojej usługi.

+1

Niestety, normalni użytkownicy również muszą mieć dostęp do zapisu – Clay

+1

Zaktualizowana odpowiedź. Trzeba tylko poprawić deskryptor bezpieczeństwa. – Michael

+0

Dobra odpowiedź - jesteśmy w dziwnej sytuacji bezpieczeństwa. Użytkownicy końcowi mają zaufanie do interakcji z systemem (w ten sposób mogą modyfikować pamięć należącą do usługi), ale jesteśmy zobowiązani do ograniczenia ich dostępu (UAC musi być włączony itp.). Witamy w szaleństwie świata sieci rządowej. – Clay

Powiązane problemy