Não é possível porque a tabela de chamadas do sistema (chamada sys_call_table
) é uma matriz de tamanho estático. E seu tamanho é determinado no tempo de compilação pelo número de chamadas de sistema registradas. Isso significa que não há espaço para outro.
Você pode verificar a implementação, por exemplo, da arquitetura x86 no arch/x86/kernel/syscall_64.c
arquivo, onde sys_call_table
está definido. Seu tamanho é exatamente __NR_syscall_max+1
. __NR_syscall_max
é definido arch/x86/kernel/asm-offsets_64.c
como sizeof(syscalls) - 1
(é o número do último syscall), onde syscall
é uma tabela com todos os syscalls.
Uma solução possível é reutilizar um sys_setaltroot
número de syscall existente (ou descontinuado, se sua arquitetura tiver um, veja, por exemplo) o seu, pois isso não exigirá mais espaço na memória. Algumas arquiteturas também podem ter buracos na tabela syscall (como a versão de 64 bits do x86) para que você também possa usá-lo.
Você pode usar essa técnica se estiver desenvolvendo um novo syscall e apenas desejar evitar a reinicialização durante a experiência. Você precisará definir sua nova chamada do sistema, localizar a entrada existente na tabela syscall e substituí-la do seu módulo.
Fazer isso a partir do módulo do kernel não é trivial, pois o kernel não exporta sys_call_table
para módulos a partir da versão 2.6 (a última versão do kernel que teve esse símbolo exportado foi 2.5.41
).
Uma maneira de contornar isso é mudar o seu kernel para exportar o sys_call_table
símbolo para os módulos. Para fazer isso, você deve adicionar as duas linhas a seguir kernel/kallsyms.c
( não faça isso nas máquinas de produção ):
extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);
Outra técnica é encontrar a tabela syscall dinamicamente. Você itera na memória do kernel, comparando cada palavra com um ponteiro com a função de chamada do sistema conhecida. Como você conhece o deslocamento desse syscall conhecido na tabela, é possível calcular o endereço inicial da tabela.