Panggilan sistem didukung dalam menjalankan Kernel

9

Apakah ada cara untuk mendapatkan nomor atau daftar panggilan sistem yang didukung oleh Linux Kernel yang saat ini dijalankan? Jadi saya ingin mencari cara untuk 'membaca' tabel syscall dari kernel yang sedang berjalan.

Swair
sumber

Jawaban:

15

File ini /proc/kallsymsmencantumkan semua simbol kernel yang sedang berjalan. Secara konvensi, panggilan sistem memiliki nama yang dimulai dengan sys_. Pada sistem 64-bit, panggilan sistem untuk program 32-bit memiliki nama yang dimulai dengan sys32_. Sebenarnya, ini mencantumkan fungsi kernel internal, bukan panggilan sistem, tapi saya pikir korespondensi berfungsi (setiap panggilan sistem memanggil fungsi kernel internal untuk melakukan pekerjaan, dan saya pikir namanya selalu nama panggilan sistem dengan sys_prepended ).

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

Ini biasanya bukan informasi yang berguna, karena panggilan sistem berubah sangat lambat. Komponen opsional menyediakan fungsionalitas dalam hal panggilan sistem yang ada, menggunakan fitur umum seperti perangkat (dengan ioctl ketika readdan writetidak memotongnya), sistem file, soket, dll. Menentukan daftar syscalls yang didukung tidak akan memberi tahu Anda apa-apa tentang fitur-fitur tersebut. yang didukung sistem. Nama fungsi internal lainnya juga tidak akan membantu karena perubahan ini sangat cepat: nama fungsi yang mengimplementasikan beberapa fitur pada satu versi kernel dapat berubah pada versi berikutnya.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
+1. Nah, itu yang saya maksud ketika saya berkata, "Saya akan membiarkan seseorang dengan pengalaman lebih banyak daripada saya menjawab Anda" . Selain itu, karena /proc/kallsymsdapat dimanipulasi seperti file lainnya, menjadi sangat mudah untuk menggunakannya dalam suatu program.
John WH Smith
2
@JohnWHSmith "Dapat dimanipulasi seperti file lainnya" ... dengan peringatan bahwa pada sistem dengan kernel ASLR, file ini harus dapat dibaca hanya oleh root.
Gilles 'SO- berhenti bersikap jahat'
7

TL; DR

Saya terus mencari alternatif baru ketika menulis jawaban ini, jadi saya hanya menulis sedikit detail tentang masing-masing, dan membuat beberapa statistik. Pada dasarnya, Anda dapat:

  • Baca jawaban Gilles, yang menyediakan cara yang bersih dan cepat untuk melakukannya (bergantung pada /proc).
  • Gunakan sumber dokumentasi.
  • Gunakan file header C sistem Anda.
  • Gunakan kode sumber kernel itu sendiri.
  • Gunakan /sysdirektori.

Setelah melakukan perhitungan, saya akan merekomendasikan (di antara alternatif saya) menggunakan sistem /sysfile, karena tampaknya memberikan hasil terbaik dalam hal jumlah panggilan sistem. Anda dapat melompat langsung ke bagian itu jika Anda tidak ingin membaca tentang trik lain.

Menggunakan sumber dokumentasi

Meskipun Anda mungkin melewatkan beberapa di antaranya, Anda dapat menggunakan aproposuntuk mendaftar semua halaman manual milik bagian 2 (panggilan sistem):

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

Hapus columnjika Anda tidak ingin output columnised mewah.

Saya baru saja mengetahuinya, tetapi ada halaman manual Linux tentang panggilan sistem, dan Anda akan dapat menemukan sebagian besar di antaranya.

$ man syscalls

Saya juga menemukan dua situs web ini yang menarik:

Menggunakan file header

Sunting: Sekarang, ketika datang ke pemrograman (atau setidaknya, tanpa bergantung pada fitur-fitur yang didokumentasikan) menentukan panggilan sistem apa yang tersedia, saya khawatir kernel tidak menyimpan tabel panggilan sistemnya, setidaknya tidak dalam bentuk daftar string (seperti yang mungkin Anda harapkan untuk memanipulasi mereka). Pada level ini, kita berbicara lebih banyak tentang fungsi alamat dan pointer, daripada nama fungsi.

Saya baru saja melihat-lihat /usr/includedirektori saya dan grep-ed beberapa hal: Anda mungkin menemukan direktori berikut menarik. Beberapa dari mereka mungkin berbeda pada mesin Anda, tergantung pada arsitektur dan distribusi Anda, tetapi saya yakin Anda akan dapat menyesuaikannya.

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

Dengan mencari definisi fungsi dalam file ini, Anda akan menemukan banyak panggilan sistem, meskipun mereka tidak akan sepenuhnya didefinisikan di sana. Saya menjalankan beberapa greps di direktori ini dan saya dapat menemukan menyebutkan beberapa panggilan sistem. Ini sebuah contoh:

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

Jadi, saya menduga cara lain untuk menemukan beberapa di antaranya adalah:

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

Menggunakan kode sumber kernel dan tabel syscall-nya

Solusi lain adalah dengan menggunakan kode sumber kernel itu sendiri (dan bukan hanya header!), Dan menemukan cara untuk mencarinya secara efisien. Karena kernel mengkomit 303395ac3bf3e2cb488435537d416bc840438fcb , Anda mungkin menemukan ini sedikit lebih mudah dari sebelumnya. Berikut adalah contoh untuk 3.13 (yang merupakan kernel saya):

$ 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

Sekarang setelah Anda mendapatkan tabel syscalls yang sebenarnya, cukup telusuri:

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

Anda dapat menemukan cara, menggunakan unamedan arch, untuk mengunduh tblfile langsung dari git.kernel.org , berdasarkan versi dan arsitektur kernel yang Anda jalankan.

Menggunakan /syssistem file

Jawaban Gilles memberi saya sedikit inspirasi, dan Anda mungkin menemukan panggilan sistem itu di dalam /sys/kernel/debug/tracing/events/syscalls. Direktori ini digunakan untuk memantau penggunaan setiap pemanggilan sistem pada sistem. Setiap syscall memiliki dua direktori di dalamnya:

  • sys_enter_ [syscall]
  • sys_exit_ [syscall]

Karena itu, menggunakan ls, grepdan cut...

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

Statistik

Di sistem saya:

  • Menggunakan halaman manual mengungkapkan 440 panggilan sistem.
  • grepuntuk __SYSCALLdalam file header mengungkapkan 212 panggilan sistem.
  • Membaca tabel syscalls dari sumber kernel mengungkapkan 346 panggilan sistem.
  • Menggunakan /sys290 panggilan sistem yang terungkap.

Sekarang, jika saya menyatukan semuanya ...

$ 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

Kita mulai, 707 panggilan sistem! Tentu saja, angka ini mencerminkan definisi yang sangat fleksibel dari "pemanggilan sistem", karena 3,13 seharusnya hanya menyediakan 274 pemanggilan sistem (pembacaan /syssepertinya merupakan solusi terdekat).

John WH Smith
sumber
Saya mencari cara yang lebih banyak dalam hal 'membaca' tabel sistem panggilan dalam beberapa cara daripada mencari tahu mana dari sistem panggilan yang didokumentasikan dalam halaman manual
Swair
Saya tidak berpikir kernel menyimpan daftar syscalls-nya, setidaknya bukan sebagai daftar string. Saya mengedit jawaban saya. Jika ada cara aktual untuk melakukan ini, saya akan membiarkan seseorang dengan lebih banyak pengalaman daripada saya menjawab Anda;)
John WH Smith
jadi saya bertanya-tanya tentang ini setelah saya menambahkan system call ke kernel dan mencoba menggunakannya memberikan "fungsi tidak diimplementasikan", dan saya bertanya-tanya apakah ada beberapa cara untuk mendapatkan tabel syscall untuk kernel saat ini. ketika saya melakukan 'instal install', perbarui grub dan mulai kernel baru, pada langkah apa kernel baru tersebut relevan termasuk file yang berisi system call baru?
Swair
1
Jika panggilan sistem Anda tidak ditemukan, maka Anda tidak menerapkannya dengan benar. Jawaban saya memberi tahu Anda cara menemukan panggilan sistem Linux, tetapi tidak cara men-debug sendiri (karena bukan itu yang Anda minta). Jika Anda kesulitan mengembangkannya, Anda harus mengajukan pertanyaan khusus tentangnya, dan menghindari masalah XY .
John WH Smith
@swair Sangat tidak biasa untuk menambahkan fungsionalitas dengan menambahkan system call. Kami tidak dapat memastikan dengan pasti apa yang salah karena Anda tidak memberikan kode apa pun (dan jika pertanyaan Anda memerlukan kode C, ini di luar topik, tetapi di rumah di Stack Overflow ). Saya menduga bahwa Anda menerapkan panggilan sistem (dengan benar atau tidak) dan Anda mencoba menggunakannya dari program C, dan bahwa Anda kehilangan langkah menulis fungsi C yang membuat panggilan sistem. Panggilan sistem bukan panggilan fungsi biasa.
Gilles 'SO- stop being evil'
1

Semua jawaban baik-baik saja.

Jika Anda mencari nama Panggilan Sistem tertentu:

$ cat /proc/kallsyms | grep <sys_call_name>

Jika Anda mencari daftar semua Panggilan Sistem:

$ cat /proc/kallsyms
Hamed Kamrava
sumber