Menambahkan panggilan Sistem baru ke Linux 3.2.x dengan modul kernel yang dapat dimuat [ditutup]

11

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?

abhi
sumber
Pertanyaan ini di luar topik di sini: Unix & Linux adalah tentang penggunaan dan administrasi, bukan tentang pemrograman. Anda harus bertanya pada Stack Overflow . Jangan terlalu kabur: tautkan ke posting yang Anda temukan di Stack Overflow , dan jelaskan apa yang Anda temukan tidak meyakinkan atau kontradiktif.
Gilles 'SO- stop being evil'
2
Saya percaya bahwa pertanyaan ini jauh lebih terkait dengan Linux sebagai OS daripada pemrograman itu sendiri. Penting juga untuk mengetahui apa saja kemungkinan memperluas kemampuan sistem kami dan berapa batasannya. Ini, misalnya, membuat Anda mengerti mengapa beberapa fitur tidak mungkin untuk diimplementasikan sebagai modul yang dapat dimuat dan membutuhkan patching kernel. Mengetahui mengapa seperti ini juga dapat memberi Anda beberapa ide tentang keamanan vs kegunaan yang harus dibuat oleh pengembang kernel. Apakah pertanyaan itu lebih pada topik jika OP akan bertanya hanya jika itu mungkin dan mengapa tidak dan tidak bagaimana mengimplementasikannya?
Krzysztof Adamski
1
Ada banyak diskusi <stroke> api </stroke> di Linux Mailing List Kernel, misalnya reiserfs menggunakan syscallenya sendiri, yang tidak terlalu disukai oleh beberapa pengembang inti, termasuk Linus. Dalam kasus Anda, saya hanya akan menggunakan 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.
peterh

Jawaban:

14

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.cfile, di mana sys_call_tabledidefinisikan. Ukurannya persis __NR_syscall_max+1. __NR_syscall_maxdidefinisikan arch/x86/kernel/asm-offsets_64.csebagai sizeof(syscalls) - 1(ini adalah jumlah syscall terakhir), di mana syscalladalah 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_setaltrootmisalnya) 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_tableke modul pada versi 2.6 (versi kernel terakhir yang mengekspor simbol ini 2.5.41).

Salah satu cara untuk mengatasi ini adalah mengubah kernel Anda untuk mengekspor sys_call_tablesimbol ke modul. Untuk melakukan ini, Anda harus menambahkan dua baris berikut ke kernel/kallsyms.c( jangan lakukan ini pada mesin produksi ):

extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);

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.

Krzysztof Adamski
sumber
1

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.

PaulDaviesC
sumber