LibKing » Книги » comp-programming » Ори Померанц - Энциклопедия разработчика модулей ядра Linux

Ори Померанц - Энциклопедия разработчика модулей ядра Linux

Тут можно читать онлайн Ори Померанц - Энциклопедия разработчика модулей ядра Linux - бесплатно полную версию книги (целиком). Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте LibKing.Ru (ЛибКинг) или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
libking
  • Название:
    Энциклопедия разработчика модулей ядра Linux
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    4/5. Голосов: 101
  • Избранное:
    Добавить в избранное
  • Ваша оценка:

Ори Померанц - Энциклопедия разработчика модулей ядра Linux краткое содержание

Энциклопедия разработчика модулей ядра Linux - описание и краткое содержание, автор Ори Померанц, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Linux Kernel Module Programming Guide свободная книга; Вы можете воспроизводить и/или изменять ее в соответствии с версией 2 (или, в вашем случае, любой более поздней версией) GNU General Public License, опубликованной Free Software Foundation. Версия 2 поставляется с этим документом в Приложении E.

Эта книга распространяется в надежде, что будет полезна, но без какой-либо гарантии; даже без подразумеваемой гарантии высокого спроса или пригодности какой-либо для специфической цели.

Автор поощряет широкое распространение этой книги для персонального или коммерческого использования, если вышеупомянутое примечание относительно авторского права остается неповрежденным, и распространитель твердо придерживается условий GNU General Public License (см. Приложение E). Вы можете копировать и распространять эту книгу бесплатно или для получения прибыли. Никакое явное разрешение не требуется от автора для воспроизводства этой книги в любой среде, физической или электронной.

Обратите внимание, производные работы и переводы этого документа должны быть помещены согласно GNU General Public License, и первоначальное примечание относительно авторского права должно остаться неповрежденным. Если Вы пожертвовали новый материал этой книге, Вы должны сделать исходный текст доступным для ваших изменений. Пожалуйста делайте изменения и модификации, доступные непосредственно поддерживающему данный проект Ori Pomerantz. Он объединит модификации и обеспечит непротиворечивость изменений для всего Linux сообщества.

Если Вы планируете издавать и распространять эту книгу коммерчески, пожертвования, лицензионные платежи, и/или напечатанные копии будут высоко оценены автором и Linux Documentation Project (LDP). Содействие таким образом показывает вашу поддержку свободного программного обеспечения и Linux Documentation Project. Если Вы имеете вопросы или комментарии, пожалуйста войдите в контакт с автором по адресу, приведенному выше.

Энциклопедия разработчика модулей ядра Linux - читать онлайн бесплатно полную версию (весь текст целиком)

Энциклопедия разработчика модулей ядра Linux - читать книгу онлайн бесплатно, автор Ори Померанц
Тёмная тема

Шрифт:

Сбросить

Интервал:

Закладка:

Сделать

Исходный текст, приводимый здесь, является примером такого модуля. Мы хотим «шпионить» за некоторым пользователем, и посылать через printk сообщение всякий раз, когда данный пользователь открывает файл. Мы заменяем системный вызов, открытия файла нашей собственной функцией, названной our_sys_open. Эта функция проверяет uid (user id) текущего процесса, и если он равен uid, за которым мы шпионим, вызывает printk, чтобы отобразить имя файла, который будет открыт. Затем вызывает оригинал функции open с теми же самыми параметрами, фактически открывает файл.

Функция init_module меняет соответствующее место в sys_call_table и сохраняет первоначальный указатель в переменной. Функция cleanup_module использует эту переменную, чтобы восстановить все назад к норме. Этот подход опасен, из-за возможности существования двух модулей, меняющих один и тот же системный вызов. Вообразите, что мы имеем два модуля, А и B. Системный вызов open модуля А назовем A_open и такой же вызов модуля B назовем B_open. Теперь, когда вставленный в ядро системный вызов заменен на A_open, который вызовет оригинал sys_open, когда сделает все, что ему нужно. Затем, B будет вставлен в ядро, и заменит системный вызов на B_open, который вызовет то, что как он думает, является первоначальным системным вызовом, а на самом деле является A_open.

Теперь, если B удален первым, все будет хорошо: это просто восстановит системный вызов на A_open, который вызывает оригинал. Однако, если удален А, и затем удален B, система разрушится. Удаление А восстановит системный вызов к оригиналу, sys_open, вырезая B из цикла. Затем, когда B удален, он восстановит системный вызов к тому, что он считает оригиналом, На самом деле вызов будет направлен на A_open, который больше не в памяти. На первый взгляд кажется, что мы могли бы решать эту специфическую проблему, проверяя, если системный вызов равен нашей функции open и если так, не менять значение этого вызова (так, чтобы B не изменил системный вызов, когда удаляется), но это вызовет еще худшую проблему. Когда А удаляется, он видит, что системный вызов был изменен на B_open так, чтобы он больше не указывал на A_open, так что он не будет восстанавливать указатель на sys_open прежде, чем будет удалено из памяти. К сожалению, B_open будет все еще пробовать вызывать A_open, который больше не в памяти, так что даже без удаления B система все равно рухнет.

Я вижу два способа предотвратить эту проблему. Первое: восстановить обращение к первоначальному значению sys_open. К сожалению, sys_open не является частью таблицы ядра системы в /proc/ksyms, так что мы не можем обращаться к нему. Другое решение состоит в том, чтобы использовать счетчик ссылки, чтобы предотвратить выгрузку модуля. Это хорошо для обычных модулей, но плохо для «образовательных» модулей.

syscall.c

/* syscall.c

*

* System call "stealing" sample

*/

/* Copyright (C) 1998-99 by Ori Pomerantz */

/* The necessary header files */

/* Standard in kernel modules */

#include /* We're doing kernel work */

#include /* Specifically, a module */

/* Deal with CONFIG_MODVERSIONS */

#if CONFIG_MODVERSIONS==1

#define MODVERSIONS

#include

#endif

#include /* The list of system calls */

/* For the current (process) structure, we need

* this to know who the current user is. */

#include

/* In 2.2.3 /usr/include/linux/version.h includes a

* macro for this, but 2.0.35 doesn't - so I add it

* here if necessary. */

#ifndef KERNEL_VERSION

#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))

#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

#include

#endif

/* The system call table (a table of functions). We

* just define this as external, and the kernel will

* fill it up for us when we are insmod'ed */

extern void *sys_call_table[];

/* UID we want to spy on - will be filled from the command line */

int uid;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

MODULE_PARM(uid, "i");

#endif

/* A pointer to the original system call. The reason

* we keep this, rather than call the original function

* (sys_open), is because somebody else might have

* replaced the system call before us. Note that this

* is not 100% safe, because if another module

* replaced sys_open before us, then when we're inserted

* we'll call the function in that module - and it

* might be removed before we are.

*

* Another reason for this is that we can't get sys_open.

* It's a static variable, so it is not exported. */

asmlinkage int (*original_call)(const char *, int, int);

/* For some reason, in 2.2.3 current->uid gave me

* zero, not the real user ID. I tried to find what went

* wrong, but I couldn't do it in a short time, and

* I'm lazy - so I'll just use the system call to get the

* uid, the way a process would.

*

* For some reason, after I recompiled the kernel this

* problem went away.

*/

asmlinkage int (*getuid_call)();

/* The function we'll replace sys_open (the function

* called when you call the open system call) with. To

* find the exact prototype, with the number and type

* of arguments, we find the original function first

* (it's at fs/open.c).

*

* In theory, this means that we're tied to the

* current version of the kernel. In practice, the

* system calls almost never change (it would wreck havoc

* and require programs to be recompiled, since the system

* calls are the interface between the kernel and the processes). */

asmlinkage int our_sys_open(const char *filename, int flags, int mode) {

int i = 0;

char ch;

/* Check if this is the user we're spying on */

if (uid == getuid_call()) {

/* getuid_call is the getuid system call,

* which gives the uid of the user who

* ran the process which called the system

* call we got */

/* Report the file, if relevant */

printk("Opened file by %d: ", uid);

do {

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

get_user(ch, filename+i);

#else

ch = get_user(filename+i);

#endif

i++;

printk("%c", ch);

} while (ch != 0);

printk("\n");

}

/* Call the original sys_open - otherwise, we lose

* the ability to open files */

return original_call(filename, flags, mode);

}

/* Initialize the module - replace the system call */

int init_module() {

/* Warning - too late for it now, but maybe for next time... */

printk("I'm dangerous. I hope you did a ");

printk("sync before you insmod'ed me.\n");

printk("My counterpart, cleanup_module(), is even");

printk("more dangerous. If\n");

printk("you value your file system, it will ");

printk("be \"sync; rmmod\" \n");

printk("when you remove this module.\n");

/* Keep a pointer to the original function in

* original_call, and then replace the system call

* in the system call table with our_sys_open */

original_call = sys_call_table[__NR_open];

sys_call_table[__NR_open] = our_sys_open;

/* To get the address of the function for system

* call foo, go to sys_call_table[__NR_foo]. */

printk("Spying on UID:%d\n", uid);

/* Get the system call for getuid */

getuid_call = sys_call_table[__NR_getuid];

return 0;

}

/* Cleanup - unregister the appropriate file from /proc */

void cleanup_module() {

/* Return the system call back to normal */

if (sys_call_table[__NR_open] != our_sys_open) {

printk("Somebody else also played with the ");

printk("open system call\n");

printk("The system may be left in ");

printk("an unstable state.\n");

}

sys_call_table[__NR_open] = original_call;

}

Отложенные процессы

Что Вы делаете, когда кто-то просит Вас о чем-то, что Вы не можете сделать сразу же? Если вы человек, и вы обеспокоены, единственное, что Вы можете сказать: «Не сейчас, я занят.». Но если вы модуль, Вы имеете другую возможность. Вы можете поместить процесс в спячку, чтобы он бездействовал, пока Вы не сможете обслужить его. В конце концов, процессы помещаются в спячку и пробуждаются ядром постоянно.

Читать дальше
Тёмная тема

Шрифт:

Сбросить

Интервал:

Закладка:

Сделать


Ори Померанц читать все книги автора по порядку

Ори Померанц - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Энциклопедия разработчика модулей ядра Linux отзывы


Отзывы читателей о книге Энциклопедия разработчика модулей ядра Linux, автор: Ори Померанц. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
Большинство книг на сайте опубликовано легально на правах партнёрской программы ЛитРес. Если Ваша книга была опубликована с нарушениями авторских прав, пожалуйста, направьте Вашу жалобу на PGEgaHJlZj0ibWFpbHRvOmFidXNlQGxpYmtpbmcucnUiIHJlbD0ibm9mb2xsb3ciPmFidXNlQGxpYmtpbmcucnU8L2E+ или заполните форму обратной связи.
img img img img img