Запуск всех программ с помощью exec
вызовов, несмотря на реализации ОС, позволяет увидеть, что стандарт POSIX говорит о exec
функциях .
int execve (const char *path, char * const argv [], char * const envp []);
argv
- аргументы, передаваемые программе, envp
- переменные среды.
Массивы argv и environment заканчиваются нулевым указателем.Нулевой указатель, завершающий массив argv, не учитывается в argc.
Аргумент argv - это массив символьных указателей на строки с нулевым символом в конце.
Так что это очень легкозаключение:
- Пустая (нулевая длина) строка может быть передана в
argv
NULL
строка не может быть передана в argv, она завершится argv
, иотбросить все следующие аргументы. - любая строка в
argv
не может содержать \x0
символа, \x0
завершит текущую строку параметров.
Объяснить, что произошло при запуске
python -c 'print "\x30\x00\x31"' | xargs --null prog
Попробуйте:
python -c 'print "\x30\x00\x31"' | strace -f xargs --null echo
Мы можем найти:
...
...
...
read(0, "0\0001\n", 4096) = 4
...
...
...
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f09f46d9850) = 21232
strace: Process 21232 attached
...
...
...
[pid 21232] execve("/bin/echo", ["echo", "0", "1\n"], 0x7ffe5ccd7638 /* 74 vars */ <unfinished ...>
Это показывает, что xargs
потенциально разделяет аргумент, содержащий \x0
, на два аргумента, когдазвонит prog
.Не выполняется оболочкой, не выполняется ОС, libc, но xargs