Почему моя среда полна ␀s?

У меня есть процесс, среда которого следующая:

root@a-vm:/proc/1363# hexdump -C environ 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 0000016c 

Я никогда не видел ничего подобного; Я ожидаю, что environ содержит nul terminated key=value пары, поэтому этот результат нарушает всевозможные утверждения. Я смотрю на известную ошибку ядра, или есть какой-то законный способ в Unix / Linux для этого? (… и если да, почему? Почему ядро ​​даже допускает эту бессмыслицу?)

(на Linux, 3.13.0 / Ubuntu Trusty)

(Я столкнулся с этим, пытаясь понять, почему этот процесс не пишет какой-то временный вывод в правильное место, предполагается, что он использует определенный каталог для хранилища temp, и он информирован об этом каталоге, установив переменную env TMP , но я Установка TMP на то, что выглядит как обычный путь, а не пучок nuls, и я никогда не видел полностью пустой env.

2 Solutions collect form web for “Почему моя среда полна ␀s?”

Это не вздор, для Linux это законный способ, и ваши ожидания ошибочны.

Аргументы аргумента и среды, переданные в код запуска программы ядром, хранятся в обычной виртуальной памяти прикладного пространства, как и любые другие данные программы; и, как и любые другие переменные данных программы, они могут быть изменены. Для программ вполне законно изменять их.

(Обратите внимание, что это с точки зрения того, что ядро ​​поставляет и применяет. Что могут сказать стандарты для определенных языков программирования, не обязательно одно и то же. Но что касается ядра, это просто область приложения-пространства виртуальная память для программных данных, которые можно читать и записывать. Ядру все равно, какой язык программирования вы скомпилировали с вашего машинного кода.)

Файл /proc/${PID}/environ – это просто окно в эту виртуальную память прикладного пространства. Вместо того, чтобы помнить фактические данные среды процесса, Linux просто запоминает начальный и конечный адреса области окружения, с которой он начал процесс, а файл /proc/${PID}/environ просто считывает все, что находится в этой памяти прямо сейчас. Вы не должны ожидать, что этот файл содержит список строк с концевыми символами. Это ошибочное ожидание.

Для изменения памяти, содержащей эти строки, нет библиотеки GNU C. Но разные программы имеют свои собственные функции.

Например, рассмотрим OpenSSH. Сервер OpenSSH изменяет то, что ps показывает для своего вектора аргументов, чтобы читать такие вещи, как sshd: JdeBP [priv] .

Сервер OpenSSH содержит код, который пытается подражать Linux, что он может делать с библиотекой BSD C на OpenBSD. В OpenBSD есть функция библиотеки BSD C с именем setproctitle() которая переписывает вектор аргумента процесса, как сообщает команда ps . Он вызывает sysctl() для передачи нового аргумента в ядро, которое ps может считывать с помощью sysctl() . У FreeBSD есть аналогичная функция.

В Linux, как объясняется, ядро ​​не запоминает фактические аргументы и среду, а только начальный и конечный адреса областей памяти, в которых он первоначально размещал их при запуске процесса. Таким образом, порт Linux OpenSSH имеет функцию совместимости setproctitle() которая вместо этого перезаписывает вышеупомянутую область памяти.

Эта функция совместимости вычисляет общий размер области окружения и области аргументов и перезаписывает все это с помощью новой строки аргумента. Он делает это, потому что в обычном случае программы, которые вызывают setproctitle() хотят записать более длинный набор данных аргументов, чем тот, который первоначально был изначально выполнен. sshd часто делает. Таким образом, он позволяет новым аргументам перезаписывать область окружения, которая следует за зоной аргумента, предоставляя программам больше места для более длинных наборов строк аргументов.

Важно отметить, что он также заполняет неиспользуемую часть области, которую не нужно было перезаписывать, до исходной длины общих аргументов и данных окружающей среды с помощью ␀s.

И то, что вы видите, является точным результатом этого. Если вы обнаружите серверный процесс OpenSSH в своей системе, вы обнаружите, что в его /proc/${PID}/environ есть много ␀s.

дальнейшее чтение

  • setproctitle . Руководство FreeBSD 11.0.
  • setproctitle . Руководство OpenBSD.
  • setproctitle() . OpenSSH Portable Release.
  • environ_read() . фс / Proc / основание. Ядро Linux. Свободные электроны.

Это полностью выполнимо, написав NUL s в ячейке памяти, в которой находятся переменные среды:

 #include <stdio.h> #include <unistd.h> extern char **environ; int main(void) { int i; char *p = *environ; /* hopefully your ENV is longer than this */ for (i = 0; i < 10; i++) *(p + i) = 0; printf("hexdump -C /proc/%d/environ\n", getpid()); sleep(99999); } 

Если вместо этого вы запускаете программу с пустой средой, то файл окружения будет полностью пустым:

 execle("/bin/sleep", "sleep", "999", (char *)NULL, (char *const) NULL) 

Таким образом, этот случай – это что-то, выполняемое процессом или процессом после его запуска (и мало что может помешать этому, если вы каким-то образом не заблокировали эту память, а затем вызовы setenv(3) могут быть проблематичными …).

  • Оболочки Bash с различными переменными среды
  • Есть ли способ определить предпочтительный инструмент слияния или diff в Unix?
  • Назначьте несколько переменных окружения одной переменной и расширьте их по команде
  • Почему `` IFS = read` используется так часто, а не `IFS =; в то время как читать..`?
  • Как читать значение переменной, где имя переменной - значение другой переменной
  • Как установить SHELL = / bin / bash глобально для cron
  • Могу ли я установить несколько каталогов для $ HOME?
  • Почему bash очищает OLDPWD при запуске дочернего скрипта?
  • Как установить переменную среды `screen` из bash?
  • Хранение списка в переменной
  • Набор переменных среды, но не соблюдается
  • Как исправить правильные сценарии запуска в интерактивной оболочке без входа
  • Interesting Posts

    Можно ли сделать символическую ссылку файла на другой машине?

    Должен ли владелец зашифрованного каталога регистрироваться для его доступа к системе?

    Почему команда cd обрабатывает STDIN иначе, чем другие команды?

    Как разрешить доступ к файлам в домашней папке пользователя без загрузки?

    VIM: показать все строки, отредактированные в сеансе

    Удал файл authorized_keys и попал в проблему

    Приоритет && vs & in bash и zsh

    Запустите команду, а затем замените параметр в одной строке

    KVM – список снимков в порядке их создания

    Выделите три последних обновленных файла в выводе ls

    Установка Brother DCP-195C на чашки

    grep искать error_log и отправлять сообщения только по электронной почте, когда результаты будут найдены?

    Отменить перемещение букв с помощью sed

    Var1 устанавливается в содержимое выполняемой команды, как установить Var2 в качестве команды из Var1

    Удалите горячую клавишу Alt + F1 из Gnome Shell

    Linux и Unix - лучшая ОС в мире.