привет.
реализовал хук для system()/fork()/execve() в виде .so библиотеки. внутри хука для system(), я проверяю всякие условия/командную_строку, и если все гут - зову реальный system(). но, т.к. в .so реализованы хуки еще и для fork() и execve(), то когда реальный system() начинает выполняться, он зовет мой хуковый fork() и из него execve(). тут проблема в том, что для приведенного тут примера с system(), условия проверяются несколько раз подряд. от этого и хочу избавиться.
решил в .so библиотеке завести глобальную переменную, которую при входе в хук, устанавливаю в единицу, а при выходе в ноль. и каждый хук, перед проверкой условий проверяет, установлен ли этот флаг. и если установлен, то проверка не производится, и выполняется оригинальный вызов.
и тут я наткнулся на такую странную проблему... суть проблемы в том, что когда из хуковой system() зовется fork(), при входе в хуковый fork(), та самая глобальная переменная уже ровняется нулю, хотя из вызова выше(system()) возвращения не произошло. уточняю: глобальная переменная при входе в хуковый fork() ровняется нулю, и это еще до того, как вызываем реальный fork(). далее, из реального fork() (глобальную переменную мы снова устанавливаем в единицу(ибо при входе она почему-то ровняется нулю), чтоб исключить последующие проверки условий) происходит вызов хуковой execve(). в этом хуке все повторяется, глобальная переменная снова ровняется нулю!
в псевдокоде это выглядит так:
volatile int in_hook = 0;
...
int system(const char *cmd) {
if ( ! in_hook ) {
in_hook = 1; // "говорим" что мы в хуке
if ( ! { проверяем условия } ) {
errno = EPERM;
in_hook = 0;
return -1;
}
int rc = { вызываем реальный system() };
in_hook = 0;
return rc;
} else {
// сюда мы приходим только в том случае, если эта функция вызвана из хука.
return { вызываем реальный system() };
}
}
pid_t fork() {
// тут 'in_hook' уже равен нулю!
if ( ! in_hook ) {
in_hook = 1; // "говорим" что мы в хуке
if ( ! { проверяем условия } ) {
errno = EPERM;
in_hook = 0;
return -1;
}
int rc = { вызываем реальный fork() };
in_hook = 0;
return rc;
} else {
// сюда мы приходим только в том случае, если эта функция вызвана из хука.
return { вызываем реальный fork() };
}
}
благодарен.