модификация системных вызовов

Вопросы программного кода и архитектуры Linux

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: модификация системных вызовов

Непрочитанное сообщение Olej » 26 сен 2015, 14:11

Olej писал(а): Одним из сложных элементов при модификации системного вызова является запись в readonly страницу RAM (которая контролируется аппаратно MMU).
В комментарии показан ещё интересный способ сделать страницу RAM записываемой:

Код: Выделить всё

static void mem_setrw(void **table) {
    unsigned int l;
    pte_t *pte;
    pte = lookup_address((long unsigned int)table, &l);
    pte->pte |= _PAGE_RW;
}

static void mem_setro(void **table) {
    unsigned int l;
    pte_t *pte;
    pte = lookup_address((long unsigned int)table, &l);
    pte->pte &= ~_PAGE_RW;
}
table — это адрес памяти, в котором нужно что-то сделать.
http://lxr.free-electrons.com/source/ar ... le_types.h

Код: Выделить всё

410  * Helper function that returns the kernel pagetable entry controlling
411  * the virtual address 'address'. NULL means no pagetable entry present.
412  * NOTE: the return type is pte_t but if the pmd is PSE then we return it
413  * as a pte too.
414  */
415 extern pte_t *lookup_address(unsigned long address, unsigned int *level);

Код: Выделить всё

395 enum pg_level {
396         PG_LEVEL_NONE,
397         PG_LEVEL_4K,
398         PG_LEVEL_2M,
399         PG_LEVEL_1G,
400         PG_LEVEL_NUM
401 };
http://lxr.free-electrons.com/source/ar ... el_types.h

Код: Выделить всё

 7 typedef unsigned long   pteval_t;
...
13 typedef union {
 14         pteval_t pte;
 15         pteval_t pte_low;
 16 } pte_t;

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: модификация системных вызовов

Непрочитанное сообщение Olej » 27 сен 2015, 09:56

Выдающейся детальности разбор всех возможностей и вариантов системных вызовов в Linux:

Anatomy of a system call, part 1
July 9, 2014
This article was contributed by David Drysdale
Anatomy of a system call, part 2
July 16, 2014
This article was contributed by David Drysdale
Настолько, что его схему полезно скопировать сюда:
Изображение

Anatomy of a system call, additional content
[Posted July 9, 2014 by jake]

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: модификация системных вызовов

Непрочитанное сообщение Olej » 01 окт 2015, 00:15

Olej писал(а):2-я часть в таком же чёрном виде.
3-я часть марлезонского балета ;-)
Сетевые системные вызовы
Вложения
Netm_05.odt
(61.85 КБ) 238 скачиваний
netm.tgz
(23.35 КБ) 252 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: модификация системных вызовов

Непрочитанное сообщение Olej » 02 окт 2015, 23:22

Olej писал(а): 3-я часть марлезонского балета ;-)
Она же (в немного изменённом виде) на Хабрахабре:
Сетевые системные вызовы. Часть 3

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: модификация системных вызовов

Непрочитанное сообщение Olej » 07 окт 2015, 18:22

Olej писал(а): 3-я часть марлезонского балета ;-)
4-я, и как я предполагаю, последняя, завершающая часть по этой теме.
Добавить системный вызов
Вложения
Adds_04.odt
(65.38 КБ) 246 скачиваний
adds.tgz
(4.11 КБ) 259 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: модификация системных вызовов

Непрочитанное сообщение Olej » 07 окт 2015, 19:30

Olej писал(а): 4-я, и как я предполагаю, последняя, завершающая часть по этой теме.
Та же часть ... может чуть подчищенная и улучшенная, на Хабрахабр: Добавить системный вызов. Часть 4 и последняя.

jcmvbkbc
Интересующийся
Сообщения: 6
Зарегистрирован: 08 окт 2015, 21:05
Контактная информация:

Re: модификация системных вызовов

Непрочитанное сообщение jcmvbkbc » 08 окт 2015, 21:11

Olej писал(а): В комментарии показан ещё интересный способ сделать страницу RAM записываемой:

Код: Выделить всё

static void mem_setrw(void **table) {
    unsigned int l;
    pte_t *pte;
    pte = lookup_address((long unsigned int)table, &l);
    pte->pte |= _PAGE_RW;
}

static void mem_setro(void **table) {
    unsigned int l;
    pte_t *pte;
    pte = lookup_address((long unsigned int)table, &l);
    pte->pte &= ~_PAGE_RW;
}
Этому коду не хватает сброса TLB после модификации страничной таблицы, например вызовом __flush_tlb_one((unsigned long)table);

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: модификация системных вызовов

Непрочитанное сообщение Olej » 08 окт 2015, 21:27

jcmvbkbc писал(а):
Olej писал(а): В комментарии показан ещё интересный способ сделать страницу RAM записываемой:

Код: Выделить всё

static void mem_setrw(void **table) {
    unsigned int l;
    pte_t *pte;
    pte = lookup_address((long unsigned int)table, &l);
    pte->pte |= _PAGE_RW;
}

static void mem_setro(void **table) {
    unsigned int l;
    pte_t *pte;
    pte = lookup_address((long unsigned int)table, &l);
    pte->pte &= ~_PAGE_RW;
}
Этому коду не хватает сброса TLB после модификации страничной таблицы, например вызовом __flush_tlb_one((unsigned long)table);
Покажите кодом полностью, если не сложно ... в том виде, как это будет компилироваться и можно проверить.
Вопрос вот в чём:
- __flush_tlb_one - определена в arch/x86/include/asm/tlbflush.h как inline
- для связывания (с модулем) она недоступна ... как экспортируемое имя, или как не экспортируемое ...
- единственное имя ядра периода выполнения (из этого файла):

Код: Выделить всё

olej@nvidia ~ $ sudo cat /proc/kallsyms | grep __flush_tlb
c164df22 t __flush_tlb_all

jcmvbkbc
Интересующийся
Сообщения: 6
Зарегистрирован: 08 окт 2015, 21:05
Контактная информация:

Re: модификация системных вызовов

Непрочитанное сообщение jcmvbkbc » 08 окт 2015, 21:34

Например так, если эти функции вызываются в атомарном контексте:

Код: Выделить всё

static void mem_setrw(void **table) {
    unsigned int l;
    pte_t *pte;
    pte = lookup_address((long unsigned int)table, &l);
    pte->pte |= _PAGE_RW;
    __flush_tlb_one((unsigned long)table);
}

static void mem_setro(void **table) {
    unsigned int l;
    pte_t *pte;
    pte = lookup_address((long unsigned int)table, &l);
    pte->pte &= ~_PAGE_RW;
    __flush_tlb_one((unsigned long)table);
}
- для связывания (с модулем) она недоступна ... как экспортируемое имя, или как не экспортируемое ...
С чего бы? Конечно она доступна. Она будет встроена компилятором в место вызова, вне зависимости от того, модуль это или не модуль.
Последний раз редактировалось jcmvbkbc 08 окт 2015, 21:39, всего редактировалось 1 раз.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: модификация системных вызовов

Непрочитанное сообщение Olej » 08 окт 2015, 21:39

jcmvbkbc писал(а):Например так, если эти функции вызываются в атомарном контексте:
Это возможно в виде патча, комита ... при сборке ядра.
В коде динамического модуля это не сделаешь - я там выше дополнил почему ... но не успел ;-)

Ответить

Вернуться в «Linux изнутри»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 12 гостей