Chiamate di sistema supportate nell'esecuzione del kernel


9

C'è un modo per ottenere il numero o l'elenco delle chiamate di sistema supportate dal kernel Linux attualmente in esecuzione? Quindi voglio trovare un modo per "leggere" la tabella syscall di un kernel in esecuzione.

Risposte:


15

Il file /proc/kallsymselenca tutti i simboli del kernel in esecuzione. Per convenzione, le chiamate di sistema hanno un nome che inizia con sys_. Su un sistema a 64 bit, le chiamate di sistema per i programmi a 32 bit hanno un nome che inizia con sys32_. A rigor di termini, questo elenca le funzioni interne del kernel, non la chiamata di sistema, ma penso che la corrispondenza funzioni (ogni chiamata di sistema invoca una funzione interna del kernel per fare il lavoro, e penso che il nome sia sempre il nome della chiamata di sistema con sys_anteposto ).

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

Di solito non si tratta di informazioni utili, poiché le chiamate di sistema cambiano molto lentamente. I componenti opzionali forniscono funzionalità in termini di chiamate di sistema esistenti, utilizzando funzionalità generali come dispositivi (con ioctl quando reade writenon lo tagliano), filesystem, socket, ecc. Determinare l'elenco di syscalls supportati non ti dirà nulla sulle funzionalità che il sistema supporta. Altri nomi di funzioni interne non aiuteranno neanche perché cambiano molto rapidamente: il nome della funzione che implementa alcune funzionalità su una versione del kernel potrebbe cambiare sulla versione successiva.


+1. Questo è ciò che intendevo quando ho detto "Lascerò rispondere a qualcuno con più esperienza di me" . Inoltre, poiché /proc/kallsymspuò essere manipolato come qualsiasi altro file, diventa abbastanza facile usarlo in un programma.
John WH Smith,

2
@JohnWHSmith “Può essere manipolato come qualsiasi altro file” ... con l'avvertenza che su sistemi con kernel ASLR, questo file dovrebbe essere leggibile solo da root.
Gilles 'SO- smetti di essere malvagio' il

7

TL; DR

Continuavo a trovare nuove alternative quando scrivevo questa risposta, quindi ho appena scritto un po 'di dettagli su ciascuna di esse e ho creato alcune statistiche. In sostanza, puoi:

  • Leggi la risposta di Gilles, che fornisce un modo pulito e veloce per farlo (fa affidamento /proc).
  • Utilizzare le risorse di documentazione.
  • Usa i file di intestazione C del tuo sistema.
  • Usa il codice sorgente del kernel stesso.
  • Usa la /sysdirectory.

Dopo aver fatto i conti, consiglierei (tra le mie alternative) di usare il /sysfilesystem, poiché sembra dare il miglior risultato in termini di numero di chiamate di sistema. Puoi saltare direttamente a quella sezione se non vuoi leggere degli altri trucchi.

Utilizzo delle risorse di documentazione

Anche se potresti perderne alcuni, puoi usare aproposper elencare tutte le manpage appartenenti alla sezione 2 (chiamate di sistema):

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

Rimuovere columnse non si desidera un output con colonne di fantasia.

L'ho appena scoperto, ma c'è una pagina man di Linux sulle chiamate di sistema e potrai trovarne la maggior parte.

$ man syscalls

Mi sono anche imbattuto in questi due siti Web che potrebbero essere interessanti:

Utilizzo dei file delle intestazioni

Modifica: ora, quando si tratta di determinare programmaticamente (o almeno, senza fare affidamento su funzionalità documentate) quali sono le chiamate di sistema disponibili, temo che il kernel non mantenga una tabella delle sue chiamate di sistema, almeno non sotto forma di un elenco di stringhe (come probabilmente ti aspetteresti di manipolarle). A questo livello, stiamo parlando più di indirizzi e puntatori di funzioni, piuttosto che di nomi di funzioni.

Ho appena sfogliato la mia /usr/includedirectory e grepaggiunto alcune cose: potresti trovare interessanti le seguenti directory. Alcuni potrebbero essere diversi sulla tua macchina, a seconda della tua architettura e distribuzione, ma sono sicuro che sarai in grado di adattarli.

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

Cercando le definizioni delle funzioni in questo file, ti imbatterai in molte chiamate di sistema, anche se non saranno completamente definite in esso. Ho eseguito alcuni grepsecondi in queste directory e sono stato in grado di trovare menzioni di alcune chiamate di sistema. Ecco un esempio:

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

Quindi, immagino che un altro modo per trovarne alcuni sarebbe:

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

Usando il codice sorgente del kernel e la sua tabella syscall

Un'altra soluzione è utilizzare il codice sorgente del kernel stesso (e non solo le intestazioni!) E trovare un modo per cercarlo in modo efficiente. Dal momento che il kernel commette 303395ac3bf3e2cb488435537d416bc840438fcb , potresti trovarlo un po 'più facile di prima. Ecco un esempio per 3.13 (che è il mio 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

Ora che hai ottenuto la tabella syscalls effettiva, basta sfogliarla:

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

È possibile trovare un modo, utilizzando unamee arch, per scaricare il tblfile direttamente da git.kernel.org , in base alla versione e all'architettura del kernel in esecuzione.

Utilizzando il /sysfilesystem

La risposta di Gilles mi ha dato un po 'di ispirazione e potresti trovare quelle chiamate di sistema all'interno /sys/kernel/debug/tracing/events/syscalls. Questa directory viene utilizzata per monitorare l'utilizzo di ciascuna chiamata di sistema sul sistema. Ogni syscall contiene due directory:

  • sys_enter_ [syscall]
  • sys_exit_ [syscall]

Pertanto, utilizzando ls, grepe cut...

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

Statistiche

Sul mio sistema:

  • L'uso delle pagine man ha rivelato 440 chiamate di sistema.
  • grep-ing per __SYSCALLnei file di intestazione ha rivelato 212 chiamate di sistema.
  • La lettura della tabella syscalls dai sorgenti del kernel ha rivelato 346 chiamate di sistema.
  • Utilizzando /sys290 chiamate di sistema rivelate.

Ora, se metto tutto insieme ...

$ 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

Eccoci, 707 chiamate di sistema! Naturalmente, questo numero riflette una definizione molto flessibile di "chiamata di sistema", poiché si suppone che 3.13 fornisca solo 274 chiamate di sistema (la lettura /syssembra essere la soluzione più vicina).


Sto cercando un modo più in termini di "lettura" della tabella delle chiamate di sistema in qualche modo piuttosto che scoprire quali delle chiamate di sistema sono documentate nelle pagine man
Swair,

Non penso che il kernel mantenga un elenco dei suoi syscalls, almeno non come un elenco di stringhe. Ho modificato la mia risposta. Se c'è un modo effettivo per farlo, lascerò che qualcuno con più esperienza di me ti risponda;)
John WH Smith,

quindi mi stavo chiedendo questo dopo aver aggiunto una chiamata di sistema al kernel e provare a usarla stava dando "funzione non implementata", e mi chiedevo se ci fosse un modo per ottenere la tabella syscall per il kernel corrente. quando eseguo "#make install", aggiorno grub e avvio un nuovo kernel, in quale fase il nuovo kernel ottiene i file include pertinenti che contengono la nuova chiamata di sistema?
Swair,

1
Se la chiamata di sistema non viene trovata, non è stata implementata correttamente. La mia risposta ti dice come trovare le chiamate di sistema di Linux, ma non come eseguire il debug delle tue (poiché non è quello che stai chiedendo). Se hai problemi a svilupparlo, dovresti porre una domanda specifica al riguardo ed evitare il problema XY .
John WH Smith,

@swair È estremamente insolito aggiungere funzionalità aggiungendo una chiamata di sistema. Non possiamo dire con certezza cosa c'è che non va dato che non hai fornito alcun codice (e se la tua domanda richiede un codice C, è fuori tema qui, ma a casa su Stack Overflow ). Ho il sospetto che tu abbia implementato una chiamata di sistema (correttamente o meno) e che tu stia provando a usarla da un programma C, e che ti stia perdendo il passo di scrivere una funzione C che fa la chiamata di sistema. Una chiamata di sistema non è una normale chiamata di funzione.
Gilles 'SO- smetti di essere malvagio' il

1

Tutte le risposte vanno bene

Se stai cercando un nome di chiamata di sistema specifico:

$ cat /proc/kallsyms | grep <sys_call_name>

Se stai cercando un elenco di tutte le chiamate di sistema:

$ cat /proc/kallsyms
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.