2012-04-03 15 views
5

Attualmente sto lavorando al back-end del sistema di contest di programmazione pubblica simile ad ACM. In tale sistema, ogni utente può inviare una sorgente di codice, che verrà compilata ed eseguita automaticamente (il che significa che non viene eseguita la pre-moderazione dell'occhio umano nel tentativo di risolvere qualche problema computazionale.Come proibire le chiamate di sistema, GNU/Linux

Il back-end è una macchina dedicata GNU/Linux, in cui verrà creato un utente per ciascun concorrente, tutti gli utenti che fanno parte del gruppo di utenti. Le fonti inviate da un particolare utente verranno archiviate nella directory home dell'utente, quindi compilate ed eseguite per essere verificate rispetto a vari casi di test.

Quello che voglio è vietare l'uso di chiamate di sistema Linux per le fonti. Questo perché i problemi richiedono soluzioni indipendenti dalla piattaforma, mentre l'abilitazione delle chiamate di sistema a fonti non sicure rappresenta una potenziale violazione della sicurezza. Tali fonti possono essere collocate con successo nelle FS, anche compilate, ma mai eseguite. Voglio anche essere informato ogni volta che è stata inviata la sorgente contenente le chiamate di sistema.

Ormai, compaiono i seguenti luoghi in cui tale controllo può essere collocato: analisi

  • front-end/pre-compilazione - fonte già verificato nel sistema, ma non ancora compilata. Semplice controllo del testo rispetto ai nomi delle chiamate di sistema. Soluzione dipendente dalla piattaforma, indipendente dal compilatore e dipendente dalla lingua.
  • Patch del compilatore - arresto anomalo del GCC (o di qualsiasi altro compilatore incluso nella catena di strumenti) ogni volta che viene rilevata una chiamata di sistema. Soluzione indipendente dalla lingua, dipendente dal compilatore e dipendente dalla piattaforma (se mettiamo il controllore "abbastanza lontano"). La compatibilità potrebbe anche andare persa. In effetti, non mi piace più questa alternativa.
  • Controllore di runtime - ogniqualvolta la chiamata di sistema viene richiamata dal processo, interrompere questo processo e segnalare. Questa soluzione è indipendente dal compilatore e dalla lingua, ma dipende dalla piattaforma: sono d'accordo, poiché distribuirò il back-end su piattaforme simili in termini brevi e medi.

Quindi la domanda è: non GNU/Linux l'occasione per provveditore di vietare chiamate di sistema per l'utilizzo di un Gruppo, utente o particolare processo? Potrebbe essere una politica di sicurezza o una utility GNU leggera.

Ho provato a Google, ma Google non mi è piaciuto oggi.

+0

_Front-end/analisi pre-compilazione_ ← I trucchi del preprocessore possono evadere facilmente. Esiste 'seccomp' che è una modalità in cui un processo può solo leggere/scrivere su una pipe pre-aperta. È abilitato tramite una chiamata 'prctl()'. Ci sono domande simili qui su SO: http://www.google.com/search?q=seccomp+site%3Astackoverflow.com&btnG=Buscar&oe=utf-8 – ninjalj

+0

@ninjalj provato, ma non ha trovato. Ti dispiace condividere un link? – iehrlich

+0

Appena aggiunto un collegamento al mio commento precedente. – ninjalj

risposta

7

modalità 1 seccomp consente un processo limitarsi ad esattamente quattro syscalls: read, write, sigreturn e _exit. Questo può essere usato per codice sandbox severamente, come fa seccomp-nurse.

mode 2 seccomp (al momento della scrittura, trovato in Ubuntu 12.04 o patch il proprio kernel) offre una maggiore flessibilità nel filtraggio delle syscalls.È possibile, ad esempio, prima impostare i filtri, quindi il exec il programma in prova. L'uso appropriato di chroot o unshare può essere utilizzato per impedirne il ri-exec altro "interessante".

+1

@suddnely_me Ho appena pensato a un'altra alternativa, se seccomp non viene visualizzato: una sandbox [NaCL] (https://developers.google.com/native-client/) basata su [ZeroVM] (http://zerovm.org/). – ephemient

3

Penso che sia necessario definire meglio la chiamata di sistema. Voglio dire,

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 

dimostra che anche un programma apparentemente banale fa ~ 27 chiamate di sistema. Si presume che voglia consentire le chiamate alla "libreria C standard", ma quelle a loro volta verranno implementate in termini di chiamate di sistema. Immagino che cosa sto cercando di dire è che il controllo in fase di esecuzione è meno fattibile di quanto si possa pensare (usando strace o simili comunque).

Problemi correlati