Zadanie 4: poprawkowe¶
Data ogłoszenia: 12.06.2018
Termin oddania: 04.09.2018
Materiały dodatkowe¶
Wprowadzenie¶
W systemie Linux, dostęp do plików może być ustawiany dla właściciela pliku, grupy pliku lub wszystkich pozostałych. Można też ustawiać uprawnienia dla konkretnego użytkownika lub grupy (ACL), ale wszystkie te operacje dotyczą zawsze całego pliku. Jednak czasem przydałoby się dać użytkownikowi dostęp to części pliku, w szczególności jak ma stałą strukturę.
Zadanie¶
Napisać patch do jądra, dodający rozbudowane ACL do systemu plików ext4,
pozwalające na nadawanie dostępu do części pliku. Mechanizm powinien pozwalać
nadać uprawnienie odczytu i/lub zapisu do części pliku (od-do bajtów) dla
wskazanych użytkowników lub grup. Plik do którego proces nie ma normalnego prawa
odczytu, ale ma prawo odczytu do jego części, powinno dać się otworzyć do
odczytu, ale odczyty spoza dozwolonej części powinny zwracać błąd EACCESS
.
Jeśli odczyt rozpoczyna się w dozwolonej części, ale miałby się skończyć poza
nią, należy pozwolić odczytać tylko tyle bajtów ile jest dozwolonych.
Analogicznie dla zapisu. Dla mmap()
należy pozwolić na mapowania
dozwolonych fragmentów (proces ma dostęp do całego zamapowanego obszaru), z
odpowiadającymi flagami PROT_READ
, PROT_WRITE
. Jeśli obszar do
zamapowania wykracza poza dozwolony w dowolną stronę, syscall mmap()
powinien zakończyć się błędem. Przy decyzji o dostępie do danego fragmentu
pliku decydują uprawnienia z momentu otwarcia pliku.
Prawa do wykonywania dla podzbioru pliku nie obsługujemy. Rozbudowane ACL
dotyczą wyłącznie zwykłych plików, próba ustawienia na dowolnym innym typie
pliku powinna kończyć się błędem EINVAL
.
Pliki bez rozbudowanych ACL powinny zachowywać się bez zmian.
Należy również dostarczyć bibliotekę z funkcjami do ustawiania uprawnień.
Rozszerzone ACL należy przechowywać jako xattr, w przestrzeni nazw “system.”.
Biblioteka może ustawiać uprawnienia bezpośrednio modyfikując te atrybut(y), ale jądro
musi weryfikować zawartość i odrzucać nieprawidłowo sformatowane zmiany.
Nadawać/odbierać uprawnienia powinien móc (wyłącznie) właściciel pliku oraz
procesy posiadające CAP_FOWNER
.
Szczegóły¶
Biblioteka powinna udostępniać następujące funkcje:
struct extacl {
uint16_t type;
uint16_t _pad;
uint32_t uid_gid;
uint64_t range_start;
uint64_t range_len;
}
int extacl_set_file(const char *path, struct extacl *extacl, size_t extacl_len);
int extacl_get_file(const char *path, struct extacl *extacl, size_t extacl_len);
Funckcja extacl_get_file
pobiera rozbudowany ACL z pliku wskazanego przez
path
i zapisuje w buforze extacl
co najwyżej extacl_len
elementów, a
następnie zwraca łączną liczbę wpisów połączonych z danym plikiem (w
szczególności wynik może być większy niż extacl_len
jeśli extacl
jest
za mały żeby pomieścić wszystkie wpisy; ale należy zadbać aby nie zapisywać
poza podany bufor). W przypadku błędu, funkcja zwraca -1
i ustawia
errno
na odpowiednią wartość. Jeśli rozbudowany ACL nie był ustawiony,
funkcja zwraca 0
.
Funkcja extacl_set_file
ustawia rozbudowany ACL na pliku wskazanym przez
path
. Pożądane uprawnienia przekazane są w tablicy extacl
, długości
extacl_len
. Jeśli któregokolwiek z wpisów nie udało się ustawić, funkcja
powinna zwrócić błąd (-1
i odpowienie errno
), pozostawiając ACL bez
zmian. W przeciwnym wypadku, funkcja zwraca exact_len
.
Pole type
może zawierać jedną z wartości:
EXTACL_USER_READ
(0x1
) - prawo do odczytu do zakresu[range_start, range_start+range_len)
dla użytkownika wskazanego w poluuid_gid
.EXTACL_USER_WRITE
(0x2
) - prawo do zapisu do zakresu[range_start, range_start+range_len)
dla użytkownika wskazanego w poluuid_gid
.EXTACL_GROUP_READ
(0x3
) - prawo do odczytu do zakresu[range_start, range_start+range_len)
dla grupy wskazanej w poluuid_gid
.EXTACL_GROUP_WRITE
(0x4
) - prawo do zapisu do zakresu[range_start, range_start+range_len)
dla grupy wskazanej w poluuid_gid
.
Zasady oceniania¶
Za zadanie można uzyskać do 10 punktów. Na ocenę zadania składają się dwie części:
- wynik automatycznych testów (od 0 do 10 punktów)
- ocena kodu rozwiązania (od 0 do -10 punktów)
Punktacja¶
Testów było 18, 10/18 punkta za każdy. Link do archiwum na początku treści.
Punkty z oceny kodu:
- -0.5 wadliwa obsługa nie-zapatchowanego filesystemu w bibliotece (fsetxattr zwraca EOPNOTSUPP) - SEGV, nieskończona pętla itp
- -0 używanie uid zamiast fsuid (ale nie było w treści)
- -1 nieprawidłowa obsługa pread()/pwrite() - np ignorowanie ostatniego parametru (offset)
- -1 możliwość ustawienia extacl z pominięciem walidacji (np. bezpośredni zapis xattr dopuszczony i omija walidację)
- -0.5 extacl_set_file zwraca 0 przy sukcesie
- -1 przy obsłudze mmap, mylenie pgoff (strony) z offsetem w bajtach
- -0.5 nieprawidłowe kody błędów (np EPERM zamiast EACCES)
Testy były uruchamiane z założeniem że powyższe błędy są naprawione, tzn. powyższa lista ma priorytet nad testami, punkty za ten sam błąd nie są odejmowane dwa razy.
Forma rozwiązania¶
Jako rozwiązanie należy wysłać paczkę zawierającą:
- patcha na jądro w wersji 4.9.13, w jednym z następujących formatów:
- patch wygenerowaniy przez diffa z opcjami
-uprN
nakładający się przezpatch -p1
git format-patch
- patch wygenerowaniy przez diffa z opcjami
- plik(i) źródłowy biblioteki, wraz z makefile (lub równoważnym)
- krótki opis rozwiązania
Rozwiązania prosimy nadsyłać na adres marmarek@mimuw.edu.pl
z kopią
do mwk@mimuw.edu.pl
.
Pytania i odpowiedzi¶
Pytania należy wysyłać na adres marmarek@mimuw.edu.pl, odpowiedzi (wiążące) będą zamieszczane tutaj.