Невозможно использовать аргумент `== `команды `capsh `для повторного -выполнения?

Та же проблема. Используя информацию, представленную в этой теме, я смог пойти дальше.

Я использовал apt source python2.7и debuild -b -uc -us, чтобы подробно изучить, как был собран официальный пакет. Реализация imp.get_suffixes()находится по адресу Python/import.c :2940 imp_get_suffixes(...), который считывает суффиксы из списка с именем _PyImport_Filetab. Этот список, в свою очередь, в основном _PyImport_DynLoadFiletabи _PyImport_StandardFiletabконкатенирован.

Стало очевидно, что _PyImport_DynLoadFiletab— это то, что нам следует искать, и его определение различается для разных платформ -они есть в Python/dynload _*.c. В Python/dynload _shlib.c — это:

const struct filedescr _PyImport_DynLoadFiletab[] = {
#ifdef __CYGWIN__
    {".dll", "rb", C_EXTENSION},
    {"module.dll", "rb", C_EXTENSION},
#else
#if defined(PYOS_OS2) && defined(PYCC_GCC)
    {".pyd", "rb", C_EXTENSION},
    {".dll", "rb", C_EXTENSION},
#else
#ifdef __VMS
    {".exe", "rb", C_EXTENSION},
    {".EXE", "rb", C_EXTENSION},
    {"module.exe", "rb", C_EXTENSION},
    {"MODULE.EXE", "rb", C_EXTENSION},
#else
#ifdef Py_DEBUG
    {"_d.so", "rb", C_EXTENSION},
    {"module_d.so", "rb", C_EXTENSION},
# ifdef MULTIARCH
    {"." MULTIARCH "_d.so", "rb", C_EXTENSION},
# endif
#endif
#ifdef MULTIARCH
    {"." MULTIARCH ".so", "rb", C_EXTENSION},
#endif
    {".so", "rb", C_EXTENSION},
    {"module.so", "rb", C_EXTENSION},
#endif
#endif
#endif
    {0, 0}
};

Это прямо здесь :MULTIARCH, если вы посмотрите на журнал сборки, это"x86_64-linux-gnu"(с кавычками из-за -s ). Значение, по-видимому, взято из dpkg-architecture -qDEB_HOST_MULTIARCH, но я не проверял.

Что еще более важно, _PyImport_DynLoadFiletabне выглядит так изначально в dynload _shlib.c, он был исправлен. Таким образом, чтобы получить такое же поведение, необходимо также применить некоторый патч, по крайней мере, добавить часть {"." MULTIARCH ".so",...}. В моем случае достаточно пропатчить этот файл (dynload _shlib.c ).

0
07.01.2021, 20:42
3 ответа

Проблема в том, что он пытается повторно -выполнить себя какcapsh(или любое другое имя команды и путь, который вы запустили с ).

Это изstrace capsh == --print:

execve("capsh", ["capsh", "--print"], [/* 20 vars */]) = -1 ENOENT (No such file or directory)
write(2, "execve /bin/bash failed!\n", 25execve /bin/bash failed!
) = 25

Так что на самом деле не " execve /bin/bash" терпит неудачу, а execve capsh. Функция execve()не выполняет поиск в $PATH.

Использование capshс его полным путем заставит его работать.

$ command -v capsh
/sbin/capsh
$ /sbin/capsh == --print
Current: =
[... etc....]

См. также руководство execve(2)по вашей системе(man 2 execve).

1
18.03.2021, 22:38

Если исходный код , который я нашел , верен, он, похоже, использует одни и те же несколько строк как для ==, так и для --:

.
    } else if ((!strcmp("--", argv[i])) || (!strcmp("==", argv[i]))) {
        argv[i] = strdup(argv[i][0] == '-' ? "/bin/bash" : argv[0]);
        argv[argc] = NULL;
        execve(argv[i], argv+i, envp);
        fprintf(stderr, "execve /bin/bash failed!\n");
        exit(1);
    }

Как сказал Кусалананда, он не найдет capsh, так как execve()не ищет пути, а сообщение об ошибке жестко закодировано для случая /bin/bash.

1
18.03.2021, 22:38

Вероятно, это ошибка в libcap :capsh, которую мы исправили в прошлом году:

https://bugzilla.kernel.org/show_bug.cgi?id=209873

Если эта проблема сохраняется в версиях libcap после 2.45, дайте мне знать.

0
21.05.2021, 02:31

Теги

Похожие вопросы