Почему моя среда полна ␀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.

  • две сетевые карты в одной подсети и два фиктивных устройства на одном хосте - маршрутизация
  • Как на величину / proc / stat повлияет количество ядер процессора или процессора?
  • Как я могу прочитать жесткий диск Linux из Windows?
  • Управление сетевыми подключениями в Arch Linux
  • Как приоритет процесса в реальном времени установлен по умолчанию?
  • Переключиться на текстовую консоль в Fedora
  • Linux копирует диапазон папок
  • Создание виртуального устройства в файле .asoundrc
  • 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) могут быть проблематичными …).

    Interesting Posts

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

    Два разных IP-адреса для одного интерфейса NIC

    Почему вы не можете перечислить файл / каталог относительно .. из каталога символической ссылки (Нет такого файла или каталога)?

    Ошибка rsync: значение времени файла, усеченного на приемнике

    Linux bash: поиск и замена в файле без выхода из строя

    Проверьте, открыт ли файл другим процессом

    Как проверить, включена ли горячая замена или горячая вилка на моей машине Linux

    необходимо переместить файлы с именем в директории с соответствующими именами

    RPM: Установленные (но неупакованные) файлы, найденные на Centos 6 с CUPS 1.7.1

    Безопасно ли подключаться к серверу с неправильными (конфиденциальными) ключами ssh?

    Почему по умолчанию пользователь Debian не входит в список sudoer?

    Как использовать `ожидать` с` zipcloak`?

    Удаление сообщений из очереди qmail без остановки qmail

    Скопируйте определенные файлы из указанных подкаталогов в отдельный подкаталог

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

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