Aggiunta di una nuova chiamata di sistema a Linux 3.2.x con un modulo kernel caricabile [chiuso]


11

Voglio aggiungere una nuova chiamata di sistema particolare nel kernel linux 3.2.x ma come modulo del kernel caricabile (poiché non voglio ricompilare il kernel ancora e ancora)

Ho letto molti post su Internet e anche su SO, e alcuni posti affermano che l'implementazione delle chiamate di sistema come moduli caricabili non è possibile, mentre altri dicono che è possibile.

Cos'è questo? Come si fa se è possibile?


Questa domanda è fuori tema qui: Unix e Linux riguardano l'uso e l'amministrazione, non la programmazione. Dovresti chiedere su Stack Overflow . Non essere così vago: link ai post che hai trovato su Stack Overflow e spiega cosa hai trovato inconcludente o contraddittorio.
Gilles 'SO- smetti di essere malvagio' il

2
Credo che questa domanda sia molto più legata a Linux come sistema operativo che alla programmazione stessa. È anche molto importante sapere quali sono le possibilità di estendere le nostre capacità di sistema e quali sono i suoi limiti. Questo, ad esempio, ti fa capire perché alcune funzionalità non sono possibili da implementare come modulo caricabile e necessita di patch del kernel. Sapere perché è così può anche darti alcune idee di sicurezza rispetto all'usabilità che gli sviluppatori del kernel devono fare. Quella domanda sarebbe più sull'argomento se l'OP chiedesse solo se è possibile e perché no e non come implementarlo?
Krzysztof Adamski,

1
Ci sono state numerose discussioni <stroke> flames </stroke> sulla Mailing List del kernel Linux, ad esempio reiserfs ha usato le proprie syscalls, che non erano molto amate da alcuni sviluppatori core, incluso Linus. Nel tuo caso userò semplicemente ioctl()s per il compito, sono facilmente modularizzabili. Dopotutto, il motivo principale alla base di rendere tutto questo difficile quanto è possibile che il numero di syscalls sia una cosa fortemente codificata e nessuno vuole il caos ciò che sarebbe entrato in scena. Ma ci sono numerose interfacce del kernel per raggiungere la stessa funzionalità, ad esempio sysfs, ioctls o simili.
Peter - Ripristina Monica il

Risposte:


14

Non è possibile perché la tabella delle chiamate di sistema (chiamata sys_call_table) è un array di dimensioni statiche. E le sue dimensioni sono determinate al momento della compilazione dal numero di syscalls registrati. Ciò significa che non c'è spazio per un altro.

È possibile verificare l'implementazione, ad esempio, per l'architettura x86 nel arch/x86/kernel/syscall_64.cfile, dove sys_call_tableè definita. Le sue dimensioni sono esattamente __NR_syscall_max+1. __NR_syscall_maxè definito arch/x86/kernel/asm-offsets_64.ccome sizeof(syscalls) - 1(è il numero dell'ultima syscall), dove syscallè una tabella con tutte le syscall.

Una possibile soluzione è quella di riutilizzare un numero esistente (o deprecato se l'architettura ne ha uno, vedi sys_setaltrootad esempio) un numero di syscall con il tuo in quanto ciò non richiederà più spazio in memoria. Alcune architetture possono anche presentare buchi nella tabella di syscall (come la versione a 64 bit di x86) in modo da poter usare anche questo.

È possibile utilizzare questa tecnica se si sta sviluppando un nuovo syscall e si desidera semplicemente evitare il riavvio durante la sperimentazione. Dovrai definire la tua nuova chiamata di sistema, trovare la voce esistente nella tabella syscall e quindi sostituirla dal tuo modulo.

Fare questo dal modulo del kernel non è banale poiché il kernel non esporta sys_call_tablein moduli dalla versione 2.6 (l'ultima versione del kernel che aveva questo simbolo esportato era 2.5.41).

Un modo per aggirare questo problema è cambiare il kernel per esportare il sys_call_tablesimbolo in moduli. Per fare questo, devi aggiungere le seguenti due righe a kernel/kallsyms.c( non farlo sulle macchine di produzione ):

extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);

Un'altra tecnica è quella di trovare la tabella di syscall in modo dinamico. Si scorre la memoria del kernel, confrontando ogni parola con un puntatore alla funzione di chiamata di sistema nota. Poiché si conosce l'offset di questo syscall noto nella tabella, è possibile calcolare l'indirizzo iniziale della tabella.


1

Purtroppo non è possibile aggiungere chiamate di sistema al kernel come moduli caricabili. Devi prenderti il ​​disturbo di compilare il kernel ogni volta che aggiungi una nuova chiamata di sistema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.