2012-04-03 9 views
5

Obecnie pracuję nad zapleczem systemu konkursowego publicznego programowania ACM. W takim systemie każdy użytkownik może przesłać źródło kodu, które zostanie skompilowane i uruchomione automatycznie (co oznacza, że ​​nie zostanie wykonane wstępne moderowanie ludzkiego oka) w celu rozwiązania problemu obliczeniowego.Jak zabronić wywołań systemowych, GNU/Linux

Back-end to maszyna dedykowana dla systemu GNU/Linux, w której użytkownik zostanie utworzony dla każdego uczestnika, a wszyscy tacy użytkownicy będą należeć do grupy użytkowników. Źródła wysłane przez konkretnego użytkownika będą przechowywane w katalogu domowym użytkownika, a następnie kompilowane i wykonywane w celu weryfikacji w różnych przypadkach testowych.

Chcemy zakazać używania wywołań systemowych systemu Linux dla źródeł. Dzieje się tak dlatego, że problemy wymagają rozwiązań niezależnych od platformy, a umożliwienie wywołań systemowych dla niezabezpieczonego źródła jest potencjalnym naruszeniem bezpieczeństwa. Takie źródła można z powodzeniem umieścić w FS, nawet skompilować, ale nigdy nie uruchamiać. Chcę również otrzymywać powiadomienie o wysłaniu źródła zawierającego wywołania systemowe.

Teraz widzę następujące miejsca, gdzie takie sprawdzanie może być umieszczone: analiza

  • Czołowy/pre-kompilacji - źródło sprawdzonych już w systemie, ale nie jest jeszcze skompilowany. Proste sprawdzanie tekstu przed nazwami wywołań systemowych. Zależne od platformy, niezależne od kompilatora, zależne od języka rozwiązanie.
  • Poprawka kompilatora - awaria GCC (lub dowolnego innego kompilatora dołączonego do łańcucha narzędzi) po napotkaniu wywołania systemowego. Zależne od platformy, zależne od kompilatora rozwiązanie niezależne od języka (jeśli umieścimy kontroler "wystarczająco daleko"). Kompatybilność może również zostać utracona. W rzeczywistości najbardziej nie lubię tej alternatywy.
  • Sprawdzanie w czasie pracy - zawsze, gdy wywołanie systemowe jest wywoływane z procesu, zakończ ten proces i zgłoś. To rozwiązanie jest niezależne od kompilatora i języka, ale zależy od platformy - nie przeszkadza mi to, ponieważ wdrożę back-end na podobnych platformach w krótkich i średnich terminach.

Pytanie brzmi: czy GNU/Linux daje administratorowi możliwość zablokowania wykorzystania wywołań systemowych dla grupy użytkowników, użytkownika lub określonego procesu? Może to być polityka bezpieczeństwa lub lekkie narzędzie GNU.

Próbowałem użyć Google, ale Google mnie dzisiaj nie podobało.

+0

_Front-end/analiza przed kompilacją_ ← Preprocesorowe triki mogą łatwo tego uniknąć. Istnieje 'seccomp', który jest trybem, w którym proces może tylko odczytać/zapisać do wstępnie otwartej rury. Jest włączony przez wywołanie 'prctl()'. Podobne pytania są tutaj: http://www.google.com/search?q=seccomp+site%3Astackoverflow.com&btnG=Buscar&oe=utf-8 – ninjalj

+0

@ninjalj próbował, ale nie znalazł. Chcesz udostępnić link? – iehrlich

+0

Właśnie dodano link do mojego poprzedniego komentarza. – ninjalj

Odpowiedz

7

tryb 1 seccomp umożliwia proces ograniczyć się do dokładnie cztery syscalli: read, write, sigreturn i _exit. To może być użyte do poważnego kodu piaskownicy, tak jak robi to seccomp-nurse.

mode 2 seccomp (w chwili pisania, znalezione w Ubuntu 12.04 lub łatania własnego jądra) zapewnia większą elastyczność w filtrowaniu linii.Możesz na przykład najpierw skonfigurować filtry, a następnie exec testowany program. Właściwe użycie chroot lub unshare może być użyte w celu zapobieżenia ponownemu "innemu" zainteresowaniu.

+1

@suddnely_me Pomyślałem o innej alternatywie, jeśli seccomp się nie wyświetla: piaskownica [NaCL] (https://developers.google.com/native-client/) taka jak [ZeroVM] (http://zerovm.org/). – ephemient

3

Myślę, że trzeba lepiej zdefiniować wywołanie systemowe. Mam na myśli,

cat <<EOF > hello.c 
#include <stdio.h> 
int main(int argc,char** argv) { 
    fprintf(stdout,"Hello world!\n"); 
    return 0; 
} 
EOF 
gcc hello.c 
strace -q ./a.out 

pokazuje, że nawet pozornie trywialny program wywołuje ~ 27 wywołań systemowych. Ty (zakładam) chcesz zezwolić na połączenia do "standardowej biblioteki C", ale te z kolei będą realizowane pod względem wywołań systemowych. Sądzę, że próbuję powiedzieć, że sprawdzanie w czasie wykonywania jest mniej wykonalne niż mogłoby się wydawać (przy użyciu strace lub podobnego).

Powiązane problemy