Распечатав «мусорные значения» в неинициализированном сегменте данных (bss), можем ли мы отобразить все значения из предыдущей программы.

avatar
Zeus Botko
8 августа 2021 в 23:43
112
2
2

У меня странный вопрос, и я не уверен, что смогу его объяснить, но поехали. Изучая C и используя его, вы обычно сталкиваетесь с термином «мусор» или «мусорное» значение, мой первый вопрос: это данные, оставшиеся поверх данных в этом адресе памяти из какой-то другой программы или чего-то еще, или это действительно что-то? случайное значение, если я считаю, что это правда, что это остаточное значение в этом адресе памяти, почему мы все еще можем читать из такого адреса памяти, я имею в виду, давайте предположим, что мы просто объявляем int x; и теперь он хранится в bss по некоторому адресу памяти #, и мы должны были вывести его значение, мы получили бы значение, которое находится по этому адресу, поэтому, если все, что я сказал, верно, разве это не позволяет нам объявить многие много-много переменных, но только объявляем, а не инициализируем, возможно, мы можем сопоставить все значения, ранее сохраненные в bss, из какой-то программы и т. д. Скорее всего, я уверен, что это будет большая угроза безопасности, и поэтому я знаю, что, вероятно, есть какие-то меры против этого, но я хочу знать, что предотвращает это?

Источник
U. Windl
9 августа 2021 в 08:33
0

Заголовок бессмыслен, поскольку сегмент BSS в не неинициализирован. Может быть, скажите нам, какую операционную систему вы используете.

Zeus Botko
10 августа 2021 в 00:15
0

@U.Windl Где я узнал об управлении памятью, BSS называется неинициализированным сегментом данных.

U. Windl
10 августа 2021 в 06:37
0

BSS является «неинициализированным» (в C), но люди, похоже, неправильно понимают, что это значит: сегмент BSS имеет только размер, без данных (таким образом, «неинициализированный»), но при запуске программы он будет заполнен нулями. В старых операционных системах, таких как MS-DOS, где новые процессы могут получить доступ к старому содержимому памяти, библиотека времени выполнения заполнила BSS нулями, в то время как в UNIX-подобных операционных системах ОС только выдает очищенную память (новым) процессам. Поскольку "неинициализированные" переменные C static помещаются в BCC, BCC необходимо обнулить, поскольку статические переменные C по умолчанию инициализируются нулем.

Ответы (2)

avatar
Nate Eldredge
8 августа 2021 в 23:48
6

Нет, содержимое секции .bss обнуляется перед запуском вашей программы. Это сделано для того, чтобы удовлетворить гарантии C, что глобальные и static переменные, если они не инициализированы явно, будут инициализированы нулем.

Действительно, в типичной многозадачной системе вся память, выделенная вашим процессом, будет обнулена операционной системой до того, как вы получите к ней доступ. Это делается для того, чтобы избежать именно упомянутой вами дыры в безопасности.

Значения локальных (auto) переменных в стеке обычно содержат "мусор", если они не инициализированы, но это будет мусор, оставшийся от выполнения вашей собственной программы до этого момента. Если ваша программа не записала ничего в это конкретное место в стеке, то она все равно будет содержать ноль (опять же в типичной ОС); он никогда не будет содержать содержимое памяти других программ.

То же самое касается памяти, выделенной malloc. Если он поступает прямо из ОС, он содержит нули. Если это блок, который был ранее выделен и освобожден, он может содержать мусор из вашего предыдущего использования этой памяти или из внутренних данных malloc, но, опять же, он никогда не будет содержать данные другой программы.

Zeus Botko
9 августа 2021 в 00:01
0

Спасибо за разъяснение, четко и лаконично, проголосовал!

Eric Postpischil
9 августа 2021 в 00:10
1

По поводу «вся память, выделенная вашим процессом, будет обнулена»: неинициализированная память будет очищена (или, по крайней мере, очищена от любых конфиденциальных данных). Память, сопоставленная с существующими данными, например память, загружаемая из сегмента кода исполняемого файла или из некоторого файла, запрошенного mmap, может быть просто прочитана из хранилища без предварительной очистки.

avatar
zwol
8 августа 2021 в 23:59
2

Ничто в самом языке C не мешает вам делать почти то, что вы говорите. Единственное, что вы сказали неправильно, учитывая только требования стандарта C, это то, что вы говорили о переменных «в bss». Объекты со статической продолжительностью хранения и без инициализатора (который является стандартным эквивалентом переменных в bss) гарантированно инициализируются нулем при запуске программы, поэтому таким образом вы не можете получить доступ к данным уже не работающих программ. Но в среде, подобной старым добрым MS-DOS или CP/M, ничто не могло помешать вам установить указатель на базу физической памяти, просмотреть до конца и найти данные из предыдущих программ.

Однако все современные операционные системы для полнофункциональных компьютеров обеспечивают защиту памяти, что означает, среди прочего, что они гарантируют, что ни один процесс не может прочитать память другого процесса, будь то или нет, другой процесс все еще работает, кроме как через четко определенные API-интерфейсы, обеспечивающие соблюдение политики безопасности. Семейство аппаратных ошибок "Spectre" имеет большое значение просто потому, что они нарушают эту гарантию.

Подробности о том, как работает защита памяти, слишком сложны, чтобы поместиться в это поле для ответа, но одна из вещей, которая почти всегда делается, заключается в том, что всякий раз, когда вы выделяете больше памяти из операционной системы, эта память инициализируется либо для всех- нулевые биты или к содержимому файла на диске. В любом случае вы не сможете добраться до "мусора".