Linux - limit pamięci i wychwytywanie syscalli

0

Jeśli umieściłem ten temat w złym dziale to przepraszam [wstyd].. uznałem ten za najodpowiedniejszy.

Piszę system do obsługi zawodów programistycznych (coś pokroju sio.mimuw.edu.pl czy spoj.pl). Istotą działania takiego systemu jest automatyczna kompilacja i uruchamianie programów nadsyłanych przez zawodników. Programy takie powinny mieścić się w wyznaczonym czasie, nie przekraczać limitu pamięci oraz nie wywoływać żadnych system call'i oprócz komunikacji przez std. input / std. output i (de)alokacji pamięci.

O ile z mierzeniem czasu i ubijaniem procesu po jego przekroczeniu sobie poradziłem, o tyle problem sprawia mi limitowanie pamięci oraz zabezpieczenie przed syscallami.

Podczas googlowania natrafiłem na funkcję setrlimit(). W Internecie i w man'ie są niby wyjaśnione zasady posługiwania się, ale z niewiadomego mi powodu ten oto kod:

#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>

int main(int argc, char *argv[])
{
        //if (argc < 4) return -1;
        rlimit limit;
        char* path = argv[1];
        int meml   = atoi(argv[2]);
        int timel  = atoi(argv[3]);

        fprintf(stderr, "  Path: %s\n  Meml: %d bytes\n  Timel: %d secs\n", path, meml, timel);

        limit.rlim_cur = limit.rlim_max = meml;
        fprintf(stderr, "setrlimit 1: %d\n", setrlimit(RLIMIT_AS, &limit));
        limit.rlim_cur = limit.rlim_max = timel;
        fprintf(stderr, "setrlimit 2: %d\n", setrlimit(RLIMIT_AS, &limit));

        system(path);
}

nie uruchamia żadnego programu podanego jako argument. Setrlimit zwraca zera, więc limity niby się ustawiają.. i są wystarczająco duże (10 MB RAMu, 1000 sekund), ale system() zachowuje się tak, jakby go nie było.

Jak już wspomniałem, drugi problem dotyczy syscalli. Chcę ubijać programy natychmiast po wywołaniu czegoś, co wykracza poza kompetencje programu (alokacja pam., wczytanie z wejścia, obliczenia, wypisywanie na wyjście). Czy da się to zrobić w minimalnie inwazyjny sposób (bez modyfikacji kernela)? Znalazłem takie coś na http://qsorix.jogger.pl/startid/282736 :

Zadanie jail'a polega na uruchamianiu programów w środowisku o limitowanym dostępie do funkcji systemowych, pamięci i czasu procesora. Po przekroczeniu narzuconych limitów wykonywany program będzie mordowany.

Programik przydatny do jakichś amatorskich turniejów programistycznych itp. Więcej w paczce w pliku docs/introduction.txt

http://rydznet.pl/~qsorix/jail-0.5.4.tar.bz2

co wydaje się być lekarstwem na me bolączki... ale niestety, za linkiem kryje się 404 ;-(

Będę bardzo, bardzo wdzięczny za pomoc.

0

A nie możesz odpalić tego procesu spod specjalnego użytkownika, który nie ma dostępu do tych syscalli ?? :>

0

może to głupie pytanie, ale jak to zrobić? [glowa] jakoś nie mogę zrozumieć się z google w tym temacie...
szukałem pod paroma hasłami, m.in forbidding system calls linux, ale zwraca same śmieci

0

To się chyba robi tak, że zamiast „normalnych” funkcji bibliotecznych realizujących wywołania systemowe podstawiasz programowi swoje własne funkcje, które „wycinają” zeń całą niepożądaną funkcjonalność (jest to szczególnie łatwe, gdy sam kompilujesz źródła programu, ale możliwe jest nawet wtedy, gdy masz binarkę, o ile korzysta ona z bibliotek dzielonych linkowanych dynamicznie (podstawiasz swoje funkcje za symbole z bibliotek standardowych)).

Oczywiście można to obejść będąc programem nie korzystając w ogóle z żadnych bibliotek, a po prostu wywołujący przerwanie 0x80 (żeby je przechwytywać musiałbyś chyba zmodyfikować jądro). Oczywiście jeśli samemu kompilujesz program możesz wywalić zeń wszystkie wstawki assemblerowe..

0

u mnie na asd mamy system athina (http://asd2.tcs.uj.edu.pl/index.html). wysyła się kody programów.

wydaje mi się, że oni nic specjalnego nie robili tylko powywalali niektóre pliki nagłówkowe (inaczej mówiąc niektóre zostawili), a niektóre zmodyfikowali (czyli wywalili zakazane funkcje).

jeśli ktoś próbuje dołączyć zakazany nagłówek to dostaje cme (compile error).

0

Wywalanie wstawek asemblerowych nic nie da, bo przecież można wstrzyknąć złośliwy kod np. w stringu. Poza tym jeśli się nie mylę, to linux działa w pmode, w którym nie da się bezpośrednio wywoływać przerwań.. dobrze mówię? ale spodobał mi się pomysł z modyfikacją f-cji bibliotecznych. Spróbuję i dam znać :)

0

w każdym trybie chyba da się wywołać przerwania. chyba, że nie ma się uprawnień. chociaż już nie pamiętam.

atsd:
twój system nie musi być bezwzględnie odporny na jakieś działania uczestników. po prostu będzie jury, które będzie sprawdzać wszystkie przepchane rozwiązania w celu wykrycia plagiatów, a przy okazji i innych nadużyć.

1 użytkowników online, w tym zalogowanych: 0, gości: 1