Chamadas do sistema suportadas na execução do Kernel

9

Existe uma maneira de obter o número ou a lista de chamadas do sistema suportadas pelo Kernel do Linux atualmente em execução? Então eu quero encontrar uma maneira de 'ler' a tabela syscall de um kernel em execução.

    
por Swair 28.10.2014 / 23:58

3 respostas

14

O arquivo /proc/kallsyms lista todos os símbolos do kernel em execução. Por convenção, as chamadas do sistema têm um nome que começa com sys_ . Em um sistema de 64 bits, as chamadas do sistema para programas de 32 bits têm um nome que começa com sys32_ . Estritamente falando, isso lista as funções internas do kernel, não a chamada do sistema, mas acho que a correspondência funciona (cada chamada do sistema invoca uma função do kernel interno para fazer o trabalho, e acho que o nome é sempre o nome da chamada do sistema com sys_ prefixado).

</proc/kallsyms sed -n 's/.* sys_//p'

Isso geralmente não é uma informação útil, porque as chamadas do sistema mudam muito lentamente. Componentes opcionais fornecem funcionalidade em termos de chamadas de sistema existentes, usando recursos gerais, como dispositivos (com ioctl quando read e write não o corta), sistemas de arquivos, sockets, etc. A determinação da lista de syscalls suportadas não informa nada sobre os recursos que o sistema suporta. Outros nomes de funções internas também não ajudam, porque eles mudam muito rapidamente: o nome da função que implementa algum recurso em uma versão do kernel pode mudar na próxima versão.

    
por 29.10.2014 / 01:49
7

TL; DR

Eu continuei encontrando novas alternativas ao escrever esta resposta, então eu apenas escrevi um pouco de detalhes sobre cada uma delas, e fiz algumas estatísticas. Basicamente, você pode:

  • Leia a resposta de Gilles, que fornece uma maneira clara e rápida de fazer isso (depende de /proc ).
  • Use os recursos de documentação.
  • Use os arquivos de cabeçalho C do seu sistema.
  • Use o próprio código-fonte do kernel.
  • Use o diretório /sys .

Depois de fazer as contas, recomendo (entre minhas alternativas) usar o sistema de arquivos /sys , já que parece dar o melhor resultado em termos de número de chamadas do sistema. Você pode ir direto para essa seção se não quiser ler sobre os outros truques.

Usando os recursos de documentação

Enquanto você pode perder alguns deles, você pode usar apropos para listar todos os manpages pertencentes à seção 2 (chamadas do sistema):

$ apropos -s2 . | awk '{print $1}' | column

Remove column se você não quiser uma saída em colunas sofisticada.

Acabei de descobrir, mas existe uma página man do Linux sobre chamadas ao sistema, e você poderá encontrar a maioria delas nele.

$ man syscalls

Eu também encontrei esses dois sites que poderiam ser interessantes:

Usando arquivos de cabeçalhos

Edit: Agora, quando se trata de programaticamente (ou pelo menos, sem depender de recursos documentados) determinar quais chamadas de sistema estão disponíveis, eu tenho medo que o kernel não mantenha uma tabela de suas chamadas do sistema, pelo menos não sob a forma de uma lista de seqüências de caracteres (como você provavelmente esperaria manipulá-los). Neste nível, estamos falando mais sobre endereços e ponteiros de funções, em vez de nomes de funções.

Acabei de navegar no meu diretório /usr/include e grep -ed algumas coisas: você pode achar os seguintes diretórios interessantes. Alguns deles podem ser diferentes em sua máquina, dependendo de sua arquitetura e distribuição, mas tenho certeza que você será capaz de adaptá-los.

  • / usr / include / linux
  • / usr / include / x86_64-linux-gnu
  • / usr / include / sys
  • / usr / include / asm-generic

Ao procurar por definições de funções neste arquivo, você encontrará muitas chamadas do sistema, mesmo que elas não estejam totalmente definidas lá. Eu corri alguns grep s nesses diretórios e pude encontrar menções de algumas chamadas do sistema. Aqui está um exemplo:

$ grep 'sys_exit' /usr/include -R
asm-generic/unistd.h:__SYSCALL(__NR_exit, sys_exit)

Então, acredito que outro jeito de encontrar alguns deles seria:

$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')'

Usando o código-fonte do kernel e sua tabela syscall

Outra solução é usar o próprio código-fonte do kernel (e não apenas os cabeçalhos!) e encontrar uma maneira de pesquisá-lo com eficiência. Desde o kernel commit 303395ac3bf3e2cb488435537d416bc840438fcb , você pode achar isso um pouco mais fácil do que antes. Aqui está um exemplo para o 3.13 (que é meu kernel):

$ wget https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/plain/arch/x86/syscalls/syscall_64.tbl?id=refs/tags/v3.13 -O syscall_64.tbl

Agora que você tem a tabela syscalls real, basta navegar:

$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl

Você poderia encontrar uma maneira, usando uname e arch , para baixar o arquivo tbl diretamente do git.kernel. org , com base na versão e arquitetura do kernel em execução.

Usando o sistema de arquivos /sys

A resposta de Gilles me deu um pouco de inspiração, e você pode encontrar essas chamadas de sistema dentro de /sys/kernel/debug/tracing/events/syscalls . Esse diretório é usado para monitorar o uso de cada chamada do sistema no sistema. Cada syscall tem dois diretórios:

  • sys_enter_ [syscall]
  • sys_exit_ [syscall]

Portanto, usando ls , grep e cut ...

$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3

Estatísticas

No meu sistema:

  • O uso das páginas man revelou 440 chamadas de sistema.
  • grep -ing para __SYSCALL nos arquivos de cabeçalho revelados 212 chamadas de sistema.
  • A leitura da tabela syscalls das origens do kernel revelou 346 chamadas de sistema.
  • O uso de /sys revelou 290 chamadas de sistema.

Agora, se eu juntar tudo ...

$ apropos -s2 . | awk '{print $1}' > system_calls.txt
$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')' >> system_calls.txt
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl >> system_calls.txt
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3 >> system_calls.txt

$ sort < system_calls.txt | uniq | wc -l
707

Lá vamos nós, 707 chamadas de sistema! Naturalmente, esse número reflete uma definição muito flexível de uma "chamada de sistema", já que 3.13 deve fornecer apenas 274 chamadas de sistema (a leitura de /sys parece ser a solução mais próxima ).

    
por 29.10.2014 / 00:09
1

Todas as respostas estão bem.

Se você estiver procurando por um nome específico de chamada de sistema:

$ cat /proc/kallsyms | grep <sys_call_name>

Se você estiver procurando uma lista de todas as chamadas do sistema:

$ cat /proc/kallsyms
    
por 04.11.2014 / 10:30