Почему моя среда полна ␀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 для этого? (… и если да, почему? Почему ядро ​​даже допускает эту бессмыслицу?)

  • Могу ли я написать C-программы для Linux на OS X?
  • Python 2.7 устанавливается на Scientific Linux 6 через SCL devtoolset
  • Только разрешение на файл
  • Как избежать вызова «startx» при входе в ssh
  • Ubuntu 12.10 Отклонение вентилятора
  • Временное включение модуля с черным списком из cli
  • (на Linux, 3.13.0 / Ubuntu Trusty)

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

  • Являются ли Iptables глобальными или пользовательскими?
  • tty (консоль): отключить монитор
  • Могу ли я сделать низкоуровневые изменения на корневом fs, установленном RO?
  • Каков наиболее эффективный способ перемещения большого количества файлов, которые находятся в одном каталоге?
  • Как установить IronKey в OpenBSD?
  • Как сохранить boot.log между перезагрузками?
  • 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) могут быть проблематичными …).

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