Saya ingin menambahkan panggilan sistem baru tertentu di kernel linux 3.2.x tetapi sebagai modul kernel yang dapat dimuat (karena saya tidak ingin mengkompilasi ulang kernel lagi dan lagi)
Saya membaca banyak posting di internet dan juga di SO, dan beberapa tempat mengklaim bahwa menerapkan panggilan sistem sebagai modul yang dapat dimuat tidak mungkin, sementara yang lain mengatakan itu mungkin.
Yang mana itu? Bagaimana ini dilakukan jika itu mungkin?
ioctl()
s untuk tugas, mereka mudah modularizable. Afaik alasan utama di balik membuat ini sekeras mungkin bahwa jumlah syscalls adalah hal yang sangat sulit dikodekan dan tidak ada yang ingin kekacauan apa yang akan masuk ke dalam gambar. Tetapi ada banyak antarmuka kernel untuk mencapai fungsi yang sama, misalnya sysfs, ioctls atau semacamnya.Jawaban:
Itu tidak mungkin karena tabel panggilan sistem (dipanggil
sys_call_table
) adalah array ukuran statis. Dan ukurannya ditentukan pada waktu kompilasi dengan jumlah syscalls terdaftar. Ini berarti tidak ada ruang untuk yang lain.Anda dapat memeriksa implementasi misalnya untuk arsitektur x86 dalam
arch/x86/kernel/syscall_64.c
file, di manasys_call_table
didefinisikan. Ukurannya persis__NR_syscall_max+1
.__NR_syscall_max
didefinisikanarch/x86/kernel/asm-offsets_64.c
sebagaisizeof(syscalls) - 1
(ini adalah jumlah syscall terakhir), di manasyscall
adalah tabel dengan semua syscalls.Salah satu solusi yang mungkin adalah dengan menggunakan kembali beberapa yang sudah ada (atau sudah usang jika arsitektur Anda memiliki satu, lihat
sys_setaltroot
misalnya) nomor panggilan dengan Anda karena ini tidak akan memerlukan lebih banyak ruang dalam memori. Beberapa arsitektur mungkin juga memiliki lubang di tabel syscall (seperti versi 64 bit x86) sehingga Anda dapat menggunakannya juga.Anda dapat menggunakan teknik ini jika Anda mengembangkan syscall baru dan hanya ingin menghindari reboot saat bereksperimen. Anda harus menentukan panggilan sistem baru Anda, menemukan entri yang ada di tabel syscall dan kemudian menggantinya dari modul Anda.
Melakukan hal ini dari modul kernel tidak sepele karena kernel tidak mengekspor
sys_call_table
ke modul pada versi 2.6 (versi kernel terakhir yang mengekspor simbol ini2.5.41
).Salah satu cara untuk mengatasi ini adalah mengubah kernel Anda untuk mengekspor
sys_call_table
simbol ke modul. Untuk melakukan ini, Anda harus menambahkan dua baris berikut kekernel/kallsyms.c
( jangan lakukan ini pada mesin produksi ):Teknik lain adalah menemukan tabel syscall secara dinamis. Anda mengulangi lebih dari memori kernel, membandingkan setiap kata dengan pointer ke fungsi panggilan sistem yang dikenal. Karena Anda tahu offset syscall pengetahuan ini dalam tabel, Anda bisa menghitung alamat awal tabel.
sumber
Sayangnya Anda tidak dapat menambahkan panggilan sistem ke kernel sebagai modul yang dapat dimuat. Anda harus bersusah payah menyusun kernel setiap kali Anda menambahkan panggilan sistem baru.
sumber