Додавання нового системного виклику до Linux 3.2.x за допомогою завантажуваного модуля ядра [закрито]


11

Я хочу додати певний новий системний виклик в Linux ядро ​​3.2.x, але як модуль ядра для завантаження (оскільки я не хочу перекомпілювати ядро ​​знову і знову)

Я читаю багато публікацій в Інтернеті, а також у програмі SO, а деякі місця стверджують, що реалізація системних викликів як завантажуваних модулів неможлива, а інші кажуть, що це можливо.

Що це таке? Як це робиться, якщо це можливо?


Це питання поза темою тут: Unix & Linux - це використання та адміністрування, а не програмування. Вам слід запитати про переповнення стека . Не будьте такі розпливчасті: посилання на публікації, які ви знайшли на стеку Overflow , та поясніть, що ви вважаєте непереконливим чи суперечливим.
Жил "ТАК - перестань бути злим"

2
Я вважаю, що це питання набагато більше стосується Linux як ОС, ніж самого програмування. Також досить важливо знати, які можливості розширення можливостей нашої системи та які її межі. Наприклад, це дозволяє зрозуміти, чому деякі функції неможливо реалізувати як завантажуваний модуль та потребує виправлення ядра. Знаючи, чому це так, може також дати вам кілька ідей щодо безпеки та зручності використання розробників ядра. Чи буде це питання більше на тему, якщо ОП запитає лише, чи можливо, а чому ні, а не як це реалізувати?
Кшиштоф Адамський

1
У списку розсилки ядра Linux було чимало дискусій <stroke> flames </stroke>, наприклад, reiserfs використовував власні системні дзвінки, які не дуже любили деякі основні розробники, включаючи Linus. У вашому випадку я просто використовую ioctl()s для виконання завдання, вони легко модулюються. Афаїк - головна причина, що робить це настільки важким, як не виключено, що кількість системних дзвінків є дуже жорсткою кодовою річчю, і ніхто не хоче хаосу, що він би потрапив до картини. Але є численні інтерфейси ядра, щоб досягти однакової функціональності, наприклад, sysfs, ioctls або подібні.
peterh

Відповіді:


14

Це неможливо, оскільки таблиця системних викликів (call sys_call_table) - це масив статичного розміру. А його розмір визначається в момент компіляції за кількістю зареєстрованих системних дзвінків. Це означає, що немає місця для іншого.

Ви можете перевірити реалізацію, наприклад, архітектури x86 у arch/x86/kernel/syscall_64.cфайлі, де sys_call_tableвизначено. Її розмір рівно __NR_syscall_max+1. __NR_syscall_maxвизначається arch/x86/kernel/asm-offsets_64.cяк sizeof(syscalls) - 1(це номер останнього систематичного виклику), де syscallзнаходиться таблиця з усіма системними дзвінками.

Одне можливе рішення - повторно використовувати деякий існуючий (або застарілий), якщо у вашій архітектурі є такий, див., sys_setaltrootНаприклад, номер системного виклику з вашим, оскільки це не потребує більше місця в пам'яті. Деякі архітектури також можуть мати отвори в таблиці syscall (наприклад, 64-бітна версія x86), тому ви можете також використовувати це.

Ви можете використовувати цю техніку, якщо ви розробляєте нові syscall і просто хочете уникнути перезавантаження під час експериментів. Вам потрібно буде визначити ваш новий системний виклик, знайти існуючий запис у таблиці syscall та замінити його у своєму модулі.

Зробити це з модуля ядра не тривіально, оскільки ядро ​​не експортує sys_call_tableдо модулів, починаючи з версії 2.6 (остання версія ядра, яка експортувала цей символ 2.5.41).

Один із способів подолати це - змінити ваше ядро ​​на експорт sys_call_tableсимволу в модулі. Для цього вам потрібно додати наступні два рядки до kernel/kallsyms.c( не робити цього на виробничих машинах ):

extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);

Ще одна методика - динамічно знаходити таблицю syscall. Ви перебираєте пам'ять ядра, порівнюючи кожне слово із вказівником із відомою функцією системного виклику. Оскільки ви знаєте зміщення цього системного виклику знань у таблиці, ви можете обчислити початкову адресу таблиці.


1

На жаль, ви не можете додати системні дзвінки до ядра як модулі, що завантажуються. Вам потрібно відчувати компіляцію ядра щоразу, коли ви додаєте новий системний виклик.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.