LINUX.ORG.RU

Использование системных вызовов в режиме ядра

 


0

2

Можно ли находясь в режиме ядра использовать системный вызов? Есть например в файле /usr/src/linux-headers<версия>/include/linux/syscalls.h

asmlinkage long sys_open(const char __user *filename,
                                int flags, int mode);
Только вот это просто объявление функции, самой функции нет. Что делать, как мне использовать какой-нибудь open?

★★★

технически мойшно, практически за такое надо сразу бить лицо

anonymous
()

Что делать, как мне использовать какой-нибудь open?

Это считается плохим стилем. Если ты к тому же задаешь вопрос «как это сделать» - для тебя это еще и опасно. Какую задачу ты пытаешься решить?

tailgunner ★★★★★
()
Ответ на: комментарий от LIKAN

надо быть конченным идиотом, чтобы открывать файл из ядра

anonymous
()
Ответ на: комментарий от LIKAN

«Открыть файл» это не задача.

anonymous
()
Ответ на: комментарий от tailgunner

Окай, реальная задача - определить рабочий каталог процесса, который в данный момент в режиме ядра. Ничего лучше сисколла getcwd я не придумал.

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

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

Это уже ближе к настоящей задаче (хотя тоже не она). Боюсь, я недостаточно квалифицирован, чтобы дать тебе совет - когда я думаю о вызовах chdir из параллельных нитей и namespace-ах, я просто не перестаю понимать, что такое «рабочий каталог процесса».

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Каталоги разделены на «правильные» и «неправильные» (по настроению администратора), нужно чтоб для любого процесса в определённых каталогах определенные действия(которые предоставляет ядро - системные вызовы) не выполнялись, соответственно нужно четко знать, в каком каталоге сейчас каждый процесс находится, так что определения каталога - скажем так конечная задача. В информационных структурах процесса информацию о каталоге мне найти не удалось, так что пока, только системный вызов рассматривается как вариант решения задачи.

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

Каталоги разделены на «правильные» и «неправильные» (по настроению администратора), нужно чтоб для любого процесса в определённых каталогах определенные действия(которые предоставляет ядро - системные вызовы) не выполнялись

Примерно этого я и боялся - какой-то доморощенный механизм безопасности с гарантированно кривой реализацией. А правда надо, чтобы системные вызовы не выполнялись в «неправильных» каталогах, но те же самы вызовы выполнялись в «правильных»?

пока, только системный вызов рассматривается как вариант решения задачи.

Ну, если уж ты решил пойти по черезжопному пути, то иди до конца - перехватывай системный вызов chdir и подменяй в нем таблицу системных вызовов. Почувствуй себя хакиром.

tailgunner ★★★★★
()
Ответ на: комментарий от LIKAN

Лучше если ты расскажешь изначальную задачу. Пока всё что ты хочешь сделать это типичные антипаттерны.

Я вот не понимаю почему то что ты хочешь нельзя сделать через, например, selinux/acl....

true_admin ★★★★★
()
Ответ на: комментарий от LIKAN

А посаны, «текущий каталог» разве не имеет смысл только в вызовах связанных с фс, следовательно достаточно unix permissions/acl этих самых фс?

anonymous
()
Ответ на: комментарий от tailgunner

Ну вы, мягко говоря, переоценили сложность задачи, правда угадали её направление. Задача действительно связана с безопасностью, только вот надо не защитить, а скомпрометировать уже существующий чужой механизм, так что качество кода не так уж и важно, но все же интересно, как сделать правильно. До черезжопного пути я догадался и сам, планировалось просто выковырять адрес таблицы сисколов, по индексу найти getcwd (при чем тут chdir?), и собственно по его адресу вызвать сам код (такое уже делалось, правда в том случае сделать как-то по-другому физически нельзя). А сюда полез узнать, есть ли более элегантный путь, где-то же храниться адрес текущего каталога процесса.

LIKAN ★★★
() автор топика
Последнее исправление: LIKAN (всего исправлений: 2)
Ответ на: комментарий от LIKAN

надо не защитит, а скомпрометировать уже существующий чужой механизм, так что качество кода не так уж и важно

Тогда перехват системных вызовов.

но все же интересно, как сделать правильно

Не знаю. С точки зрения способствования во взломе систему не изучал, нормальной формулировки задачи не знаю. Если бы это было нужно мне, я бы первым делом пустил программу под отладчиком.

getcwd (при чем тут chdir?)

Ы? Вообще-то меняет текущий каталог (и, соответственно, отключает ненужные системные вызовы) именно chdir. Причем тут getcwd вообще?

где-то же храниться адрес текущего каталога процесса.

«Текущий каталог процесса» после реализации namespace-ов вещь эфемерная (и, полагаю, довольно сложная для извлечения). Впрочем, sys_getcwd ждет тебя %)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Ну собственно перехватом я и занимаюсь, и в зависимости от того, какая сейчас текущая директория, я подсовываю либо изначальный вызов без изменений, либо специально подправленный. Мне не менять каталог надо(хотя и с этой стороны тоже подойти можно, только длиннее в разы), а только определить текущий. Ну так sys_getcwd, все с этого и началось. Как его использовать, какой заголовочник подключить?

LIKAN ★★★
() автор топика
Последнее исправление: LIKAN (всего исправлений: 1)
Ответ на: комментарий от LIKAN

Открыть файл например.

Для этого есть функции типа filp_open

annulen ★★★★★
()
Ответ на: комментарий от LIKAN

Мне не менять каталог надо(хотя и с этой стороны тоже подойти можно, только длиннее в разы), а только определить текущий.

Тебе нужно подменить таблицу вызовов при входе в «неправильный» каталог и подменить ее обратно при выходе (ну или поставить флаг «игнорировать вызовы»).

Ну так sys_getcwd, все с этого и началось.

Насколько я помню, всё начиналось с sys_open.

Как его использовать

Я не предлагал его использовать. Ты можешь посмотреть там, как именно вычисляется текущий каталог, если тебе это интересно. Для подхода «перехватываем chdir и устанавливаем в нем флаг фильтрации» понимание работы sys_getcwd не нужно.

tailgunner ★★★★★
()
Ответ на: комментарий от LIKAN

ЛОР такой ЛОР

anonymous> current->fs->pwd

LIKAN> Это ссылка на inode. Путь я из него хрен получу.

anonymous> path_get(current->fs->pwd)

LIKAN> ЛОР такой ЛОР.Я разве сказал, что хочу их тупо блокировать.

Тебе сказали, как получить имя каталога. Чем ты недоволен?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Может я в этой жизни чего-то не понял, но path_get принимает на вход struct path *, а current->fs->pwd имеет тип struct inode *.

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

current->fs->pwd имеет тип struct inode *

В исходниках, которые у меня под рукой:

// sched.h

struct task_struct {
  ...
  struct fs_struct *fs;
  ...
};
// fs_struct.h

struct fs_struct {
  ...
  struct path pwd;
  ...
};

...к моему огромному сожалению.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Я глянуть в исходники procfs ?

Там же cwd в виде symlink показывается.

vel ★★★★★
()
Ответ на: комментарий от tailgunner

Меня обманули вот тут. Ну да ладно, спасибо. Но вот есть одна проблемка.

struct path pwd
pwd=current->fs->pwd
Вылазит ошибка dereferencing pointer to incomplete type. Вот так
struct fs_struct *fs = current-> fs;
struct path pwd;
pwd=(struct path)fs->pwd;
даёт то же самое.

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

Меня обманули вот тут

А... ы... епт... я было подумал, что у тебя учебник времен 2.4, но у тебя учебник времен 2.0 o_O

Но вот есть одна проблемка.

Я отказываюсь отвечать на этот вопрос, так как мой ответ может быть использован для увеличения количества кривого кода на этой планете %)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Это считается плохим стилем. Если ты к тому же задаешь вопрос «как это сделать» - для тебя это еще и опасно. Какую задачу ты пытаешься решить?

это похоже на вопрос с собеседования.

dimon555 ★★★★★
()
Ответ на: комментарий от tailgunner

Ну, если уж ты решил пойти по черезжопному пути, то иди до конца - перехватывай системный вызов chdir и подменяй в нем таблицу системных вызовов. Почувствуй себя хакиром.

Человек всего лишь хочет прострелить себе ногу, а ты сразу предлагаешь ему заодно отрезать себе яйца.

anonymous
()
Ответ на: комментарий от tailgunner

Товарищи, мне сказали, что системные вызовы - это не есть хорошо, я от них отказался. Мне сказали куда двигаться - я туда и двигаюсь. Почему стрелять в ногу то? А во-вторых, что-то сложнее hello word под ядро я пытаюсь написать впервые, так что будьте снисходительны, или вы хотите чтобы новичек прям сразу писал код, который можно будет поставить в рамочку и повесить на стену, я для этого и иду сюда, чтоб научили как надо. Вот это

pwd=current->fs->pwd
растет именно от вашей цитаты. Так что вопрос не снимается, мануалов по полученной ошибке нет и метод зоркого взгляда мне не помог.

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

я для этого и иду сюда, чтоб научили как надо

Я надеюсь ты уже осознал свою главную ошибку?

anonymous
()
Ответ на: комментарий от anonymous

дада, спасибо, разобрался

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

Товарищи, мне сказали, что системные вызовы - это не есть хорошо, я от них отказался. Мне сказали куда двигаться - я туда и двигаюсь.

Ты пытаешься корежить ядро, не имея опыта в этой области; это и способ научиться, и способ отстрелить себе ноги. Почему не LD_PRELOAD, gdb, или seccomp, если уж нужно именно фильтровать вызовы? Или это учебная задача, которая _должна_ быть решена именно в ядре?

tailgunner ★★★★★
()

ivan@panda:~$ sudo insmod ./work/pwd/test.ko ivan@panda:~$ dmesg | tail -n1 [2101785.416656] /home/ivan

Всё работает, ептыть.

anonymous
()
Ответ на: комментарий от anonymous

Ну а повыступать? А показать всем, что у меня дескать опыт, а ты говно? Линупсоиды по-другому не умеют.

anonymous
()
Ответ на: комментарий от anonymous

Как и сказано выше - неувеличение количества кривого кода на планете.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

а)Да, это учебная задача, поставленная вполне жестко.(С другой стороны, лично для себя я с большим удовольствием выслушаю все возможные варианты её решения)
б)Я так и не нашел способа получить из struct path данные в виде char *. Есть вроде функции для получения char * из dentry, но как я понял, они не для общего пользования. (Объявлены в .h, но сам код в .с, попользоваться так просто не получиться?)

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

Да, это учебная задача

Тогда первой ее частью является «найди в ядре реализацию sys_getcwd» (подсказка - это в fs/*.c).

tailgunner ★★★★★
()
Ответ на: комментарий от LIKAN

Возможно программирование просто не твоё, кому-то же надо лепить пельмени.

static int __init test_init(void)
{
        char _tmpbuf[256];
        char *d_name;

        printk("%s\n", current->comm);

        d_name = d_path(&current->fs->pwd, _tmpbuf, sizeof(_tmpbuf));
        printk( "%s\n", d_name);

        return 0;
}
anonymous
()
Ответ на: комментарий от LIKAN

Объявлены в .h, но сам код в .с

Это вообще пушка.

man EXPORT

anonymous
()
Ответ на: комментарий от anonymous

Ну вы просто кажется озвучили в коде один из моих комментариев, откуда взять функцию d_path все равно не ясно.

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

ЧТЯНД?

Смекалку не проявляешь:

$ grep getcwd *
dcache.c: *     char *getcwd(char * buf, size_t size)
dcache.c: *             retval = sys_getcwd(buf, size);
dcache.c:SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
dcache.c: * to keep getcwd() working.
tailgunner ★★★★★
()

Расковыряй getcwd

ttnl ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.