Целью этого кода является создание трассировки стека всякий раз, когда перехватывается sigterm / sigint / sigsegv / etc. Чтобы не полагаться на управление памятью внутри кода C ++ в случае sigsegv, я решил написать bash-скрипт, который будет получать PID и адреса памяти в массиве трассировки.
События Sig ловятся.
Ниже я сгенерирую вызов скрипта bash
trace_size = backtrace(trace, 16);
trace[1] = (void *)ctx->rsi;
messages = backtrace_symbols(trace, trace_size);
char syscom[356] = {0};
sprintf(syscom,"bash_crash_supp.sh %d", getpid());
for (i=1; i<(trace_size-1) && i < 10; ++i)
{
sprintf(syscom,"%s %p",syscom,trace[i]);
}
Ниже, где моя проблема возникает. Команда в syscom генерируется правильно. Я могу остановить код до следующего всплывающего окна, запустить команду в терминале, и она работает правильно.
Однако запуск сценария непосредственно из кода C ++, похоже, не работает.
setuid(0);
FILE *bashCommand = popen(syscom,"r");
char buf[256] = {0};
while(fgets(buf,sizeof(buf),bashCommand) != 0) {
LogMessage(LOG_WARNING, "%s\n", buf);
}
pclose(bashCommand);
exit(sig);
Цель сценария bash — получить смещение из / proc /ПИД-регулятор/ maps, а затем используйте его для запуска addr2line, чтобы получить имя файла / номер строки.
strResult=$(sudo cat /proc/"$1"/maps | grep "target_file" | grep -m 1 '[0-9a-fA-F]')
offset=$( cut -d '-' -f 1 <<< "$strResult");
Однако смещение получает 0, когда я запускаю из кода c ++, но когда я запускаю точно такую же команду (которая хранится в syscom в коде c ++) в терминале, я получаю ожидаемый результат.
Я пытался это исправить некоторое время. Скорее всего, проблема с разрешениями, но я пытался обойти их всеми способами, которые я знаю / видел через Google. Пользователь, пытающийся запустить скрипт (в настоящее время работает с кодом C ++), — apache.
Исправление не нужно беспокоиться о безопасности коробки. Если бы работало что-то простое, например, «chmod 777 / proc -r», это было бы решением (к сожалению, ОС не позволяет мне делать такие команды с / proc).
Вещи, которые я уже пробовал:
Команда сгенерирована в C ++
bash_crash_supp.sh 25817 0x7f4bfe600ec8 0x7f4bf28f7400 0x7f4bf28f83c6 0x7f4bf2904f02 0x7f4bfdf0fbb0 0x7f4bfdf1346e 0x7f4bfff4f4f4f4b8f4f4f4b8f4f4f4f4f4b6
Параметры в bash:
25817 0x7f4bfe600ec8 0x7f4bf28f7400 0x7f4bf28f83c6 0x7f4bf2904f02 0x7f4bfdf0fbb0 0x7f4bfdf1346e 0x7f4bfdf1eb30 0x7f4bfdf1b9b8b8b8
Кто-нибудь может придумать какие-либо другие способы решить эту проблему?
Короче говоря, почти все системы на основе Unix игнорируют setuid
на любой интерпретируемый сценарий (что-нибудь с Шебанг #!
) в качестве меры безопасности.
Вы можете использовать setuid
на реальных исполняемых файлах, но не на самих скриптах оболочки. Если вы готовы взять массивный риск безопасности, вы можете сделать обертку исполнимый запустить скрипт оболочки и дать исполняемый файл setuid
,
Для получения дополнительной информации см. Этот вопрос на Unix StackExchange: https://unix.stackexchange.com/a/2910