Zadanie 1: ELFy i kosmici

Data ogłoszenia: 20.03.2018

Termin oddania: 10.04.2018 (ostateczny 24.04.2018)

Statek kosmitów

W ostatnim czasie w pobliżu wydziału rozbił się statek kosmitów. Udało się nam wydobyć z niego nośniki danych zawierające programy na bardzo zaawansowany technicznie system operacyjny AlienOS, lecz niestety nie przetrwał żaden działający komputer kosmitów – nie możemy więc uruchomić ich programów. Jednak po wielu miesiącach inżynierii wstecznej w końcu udało nam się ustalić, jak działają interfejsy między jądrem systemu AlienOS a programami użytkownika.

Zadanie

Napisać program ładujący i emulujący wywołania systemowe, pozwalający uruchomić programy systemu operacyjnego AlienOS pod systemem Linux. Do testów załączamy przykładowy program wydobyty ze statku kosmicznego (niestety, nie mamy pojęcia, co ten program robi). Napisany program ładujący powinien oczywiście działać z dowolnym programem kosmitów używającym interfejsu systemu AlienOS.

Forma rozwiązania

Jako rozwiązanie należy dostarczyć paczkę zawierającą:

  • dowolną ilość plików źródłowych z kodem rozwiązania
  • plik Makefile kompilujący rozwiązanie, lub odpowiadający plik z innego sensownego systemu budowania (np. cmake)
  • plik readme z krótkim opisem rozwiązania i instrukcjami kompilacji na obrazie qemu z pierwszych zajęć

Kod rozwiązania powinien być napisany w całości w C (ew. C++) i może używać sensownych bibliotek dostępnych w systemie Debian. Rozwiązanie powinno kompilować się do programu o nazwie emu, wywoływanego w następujący sposób:

./emu <program kosmitów> [<parametry dla programu kosmitów>]

Po zakończeniu działania programu kosmitów, program emu powinien się zakończyć z takim samym kodem wyjścia, jak program kosmitów.

Program ładujący powinien sprawdzać poprawność danych wejściowych w sensownym stopniu. W szczególności, należy pamiętać, że rozbity statek kosmitów nie jest zaufanym źródłem kodu – należy zapewnić, żeby kod emulowanego programu nie był w stanie zrobić nic poza używaniem znanych nam wywołań systemowych (np. pisać/czytać dowolne pliki). W razie wykrycia błędu przez program emu, program powinien się skończyć z kodem wyjścia 127.

Programy będą testowane wewnątrz qemu, uruchomionego z obrazem z pierwszych zajęć. Polecamy sprawdzenie, czy rozwiązania kompilują się w tym obrazie.

Rozwiązania prosimy nadsyłać na adres marmarek@mimuw.edu.pl z kopią do mwk@mimuw.edu.pl.

Zasady oceniania

Za zadanie można uzyskać do 10 punktów. Na ocenę zadania składają się dwie części:

  • działanie emulatora (od 0 do 10 punktów)
  • ocena kodu rozwiązania (od 0 do -10 punktów)

Najczęstsze błędy - spis oznaczeń w USOSwebie

Działanie emulatora - każdy element warty 1 punkt:

  1. Walidacja programu obcych, w szczególności adresów z PT_LOAD i PT_PARAMS.
  2. Obsługa błędœ w programie obcych (SEGV, ILL itp).
  3. Przekazywanie argumentów, w tym program bez argumentów, z wieloma argumentami.
  4. (ogólne działanie emulatora)
  5. (ogólne działanie emulatora)
  6. Obsługa wypisywania napisów - pozycja, kolory
  7. Zabijanie programu obcych przy napotkaniu nieprawidłowej operacji (zły syscall, złe argumenty)
  8. (ogólne działanie emulatora)
  9. (ogólne działanie emulatora)
  10. (ogólne działanie emulatora)

Jakość kodu:

  1. -0.5 - brakująca obsługa błędów (alokacji pamięci, fork, etc)
  2. -0.5 - wycieki pamięci
  3. -1 - kopiowanie do pamięci emulowanego programu (zamiast mmap)
  4. -0.5 - brak readme

Wskazówki

Na podstawie dokumentacji znalezionej na pokładzie statku kosmicznego nasz zespół językoznawstwa pozaziemskiego stwierdził, że przykładowy program jest prawdopodobnie sterowany za pomocą klawiszy strzałek, spacji, oraz entera. Przyjmuje jeden parametr, którego sensowne wartości są w zakresie 50-400. Wymaga terminala o rozmiarze co najmniej 80×24.

Najprostszym sposobem emulacji wywołań systemowych AlienOS jest użycie ptrace z opcją PTRACE_SYSEMU (zdefiniowane w asm/ptrace.h – innym miejscu niż większość stałych do ptrace).

Do implementacji wywołania systemowego getrand z systemu AlienOS polecamy użycie Linuxowego wywołania systemowego getrandom, lub sensownego PRNG inicjowanego takim wywołaniem. W glibc dostępnym w naszym obrazie niestety nie istnieje funkcja biblioteczna dla tego wywołania, ale można jej użyć bezpośrednio przez funkcję syscall.

Do obsługi terminala można użyć biblioteki ncurses, bądź samemu emitować stosowne kody (man console_codes).

Kolory znaków podane w dokumentacji są tylko przybliżeniem (kosmici i tak widzą kolory inaczej niż ludzie) i można użyć dowolnych sensownie zbliżonych kolorów w Linuxowym terminalu.