Adicionando uma nova chamada de sistema ao Linux 3.2.x com um módulo de kernel carregável [closed]

10

Eu quero adicionar uma nova chamada de sistema em particular no linux kernel 3.2.x mas como um módulo de kernel carregável (já que eu não quero recompilar o kernel de novo e de novo)

Eu li muitos posts na internet e também sobre o SO, e alguns lugares afirmam que implementar chamadas do sistema como módulos carregáveis não é possível, enquanto outros dizem que é possível.

Qual é? Como isso é feito se for possível?

    
por abhi 10.09.2012 / 13:56

2 respostas

13

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 em tempo de compilação pelo número de syscalls registrados. Isso significa que não há espaço para outro.

Você pode verificar a implementação, por exemplo, da arquitetura x86 no arquivo arch/x86/kernel/syscall_64.c , onde sys_call_table está definido. Seu tamanho é exatamente __NR_syscall_max+1 . __NR_syscall_max é definido em arch/x86/kernel/asm-offsets_64.c como sizeof(syscalls) - 1 (é o número do último syscall), em que syscall é uma tabela com todos os syscalls.

Uma solução possível é reutilizar alguns existentes (ou preteridos, se a arquitetura tiver um, veja sys_setaltroot , por exemplo), o número syscall com 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ê possa usar isso também.

Você pode usar esta técnica se estiver desenvolvendo o novo syscall e quiser apenas evitar a reinicialização enquanto estiver experimentando. Você terá que definir sua nova chamada de sistema, encontrar a entrada existente na tabela syscall e então substituí-la de 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 os módulos a partir da versão 2.6 (a última versão do kernel que tinha este símbolo exportado era 2.5.41 ).

Uma maneira de contornar isso é alterar o kernel para exportar o símbolo sys_call_table para módulos. Para fazer isso, você precisa adicionar duas linhas a kernel/kallsyms.c ( não faça isso em 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 a memória do kernel, comparando cada palavra com um ponteiro para a função de chamada do sistema conhecida. Desde que você conhece o deslocamento deste conhecimento na tabela, você pode calcular o endereço inicial da tabela.

    
por 14.09.2012 / 20:01
1

Infelizmente, você não pode adicionar chamadas do sistema ao kernel como módulos carregáveis. Você tem que ter a dor de compilar o kernel toda vez que você adicionar uma nova chamada de sistema.

    
por 14.09.2012 / 16:58