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.c
file, dove sys_call_table
è definita. Le sue dimensioni sono esattamente __NR_syscall_max+1
. __NR_syscall_max
è definito arch/x86/kernel/asm-offsets_64.c
come 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_setaltroot
ad 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_table
in 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_table
simbolo 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.