Может ли нулевой символ передаваться в argv в середине строки? - PullRequest
0 голосов
/ 01 марта 2019
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    write(STDOUT_FILENO, argv[1], atoi(argv[2]));
    return 0;
}

Следующий вывод (запускается в bash в Ubuntu) показывает, что xyz не передается в argv.Я хочу убедиться, что это ограничение ОС, а не оболочки.Так что было бы невозможно передать нулевой символ в середине строки в argv.Кто-нибудь может подтвердить?Спасибо.

$ ./main.exe $'abc\000xyz' 7 | xxd
00000000: 6162 6300 3700 53                        abc.7.S

1 Ответ

0 голосов
/ 01 марта 2019

Запуск всех программ с помощью exec вызовов, несмотря на реализации ОС, позволяет увидеть, что стандарт POSIX говорит о exec функциях .

int execve (const char *path, char * const argv [], char * const envp []);

argv - аргументы, передаваемые программе, envp - переменные среды.

Массивы argv и environment заканчиваются нулевым указателем.Нулевой указатель, завершающий массив argv, не учитывается в argc.

Аргумент argv - это массив символьных указателей на строки с нулевым символом в конце.

Так что это очень легкозаключение:

  1. Пустая (нулевая длина) строка может быть передана в argv
  2. NULL строка не может быть передана в argv, она завершится argv, иотбросить все следующие аргументы.
  3. любая строка в 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

...