Висячие и неинициализированные указатели в программировании
Dangling pointer
Висячие и "дикие" указатели в программировании: что это, причины возникновения и опасные последствия. Нарушения безопасности памяти и непредсказуемое поведение.
Сравнивайте с английским: нажмите на абзац — оригинал откроется в окне. Кнопка EN под абзацем показывает его прямо в тексте.
Содержание
Введение
Указатель, который не указывает на допустимый объект.
Pointer that does not point to a valid object
В компьютерном программировании висячие и дикие указатели — это указатели, которые не указывают на допустимый объект соответствующего типа. Это особые случаи нарушений безопасности памяти. В более общем смысле, висячие и дикие ссылки — это ссылки, которые не разрешаются в допустимое местоположение. Висячие указатели возникают при уничтожении объекта, когда объект, на который есть входящая ссылка, удаляется или освобождается, не изменяя при этом значение указателя, так что указатель продолжает указывать на область памяти освобожденной памяти. Система может повторно выделить ранее освобожденную память, и если программа затем разыменует (теперь) висячий указатель, может возникнуть непредсказуемое поведение, поскольку память может содержать совершенно другие данные. Если программа записывает в память, на которую указывает висячий указатель, может произойти скрытая порча несвязанных данных, приводящая к трудноуловимым ошибкам, которые очень сложно обнаружить. Если память была перераспределена другому процессу, попытка разыменовать висячий указатель может вызвать ошибки сегментации (UNIX, Linux) или общие ошибки защиты (Windows). Если программа имеет достаточные привилегии для перезаписи служебных данных, используемых менеджером памяти ядра, повреждение может привести к нестабильности системы. В объектно-ориентированных языках со сборкой мусора висячие ссылки предотвращаются путем уничтожения только тех объектов, которые недоступны, то есть не имеют входящих указателей. Это обеспечивается либо трассировкой, либо подсчетом ссылок. Однако финализатор может создавать новые ссылки на объект, требуя его восстановления, чтобы предотвратить появление висячей ссылки. Дикие указатели, также называемые неинициализированными указателями, возникают, когда указатель используется до инициализации в какое-либо известное состояние, что возможно в некоторых языках программирования. Они демонстрируют такое же непредсказуемое поведение, как и висячие указатели, хотя их реже удается не заметить, поскольку многие компиляторы выдают предупреждение во время компиляции, если к объявленным переменным обращаются до их инициализации.
Dangling pointers and wild pointers in computer programming are pointers that do not point to a valid object of the appropriate type. These are special cases of memory safety violations. More generally, dangling references and wild references are references that do not resolve to a valid destination. Dangling pointers arise during object destruction, when an object that has an incoming reference is deleted or deallocated, without modifying the value of the pointer, so that the pointer still points to the memory location of the deallocated memory. The system may reallocate the previously freed memory, and if the program then dereferences the (now) dangling pointer, unpredictable behavior may result, as the memory may now contain completely different data. If the program writes to memory referenced by a dangling pointer, a silent corruption of unrelated data may result, leading to subtle bugs that can be extremely difficult to find. If the memory has been reallocated to another process, then attempting to dereference the dangling pointer can cause segmentation faults (UNIX, Linux) or general protection faults (Windows). If the program has sufficient privileges to allow it to overwrite the bookkeeping data used by the kernel's memory allocator, the corruption can cause system instabilities. In object oriented languages with garbage collection, dangling references are prevented by only destroying objects that are unreachable, meaning they do not have any incoming pointers; this is ensured either by tracing or reference counting. However, a finalizer may create new references to an object, requiring object resurrection to prevent a dangling reference. Wild pointers, also called uninitialized pointers, arise when a pointer is used prior to initialization to some known state, which is possible in some programming languages. They show the same erratic behavior as dangling pointers, though they are less likely to stay undetected because many compilers will raise a warning at compile time if declared variables are accessed before being initialized.
Ручное деаллокация без висящей ссылки
Антони Кречмар [pl] (1945–1996) создал полную систему управления объектами, свободную от проблемы висячих ссылок. Аналогичный подход был предложен Фишером и ЛеБланком под названием "Замки и ключи".
Antoni Kreczmar [pl] (1945–1996) has created a complete object management system which is free of dangling reference phenomenon. A similar approach was proposed by Fisher and LeBlanc under the name Locks and keys.
Защитные отверстия с висящими указателями
Как и ошибки переполнения буфера, ошибки с висячими/недействительными указателями часто приводят к уязвимостям в системе безопасности. Например, если указатель используется для вызова виртуальной функции, из-за перезаписи указателя vtable может быть вызван другой адрес (возможно, указывающий на код эксплойта). В противном случае, если указатель используется для записи в память, может быть повреждена другая структура данных. Даже если память считывается только после того, как указатель стал висячим, это может привести к утечке информации (если в следующую выделенную там структуру помещены важные данные) или к повышению привилегий (если теперь недействительная память используется в проверках безопасности). Когда висячий указатель используется после освобождения памяти, без последующего выделения ему нового блока памяти, это называется уязвимостью типа "использование после освобождения". Например, уязвимость "использование после освобождения" в Microsoft Internet Explorer 6–11 используется в атаках нулевого дня продвинутой устойчивой угрозой.
Like buffer overflow bugs, dangling/wild pointer bugs frequently become security holes. For example, if the pointer is used to make a virtual function call, a different address (possibly pointing at exploit code) may be called due to the vtable pointer being overwritten. Alternatively, if the pointer is used for writing to memory, some other data structure may be corrupted. Even if the memory is only read once the pointer becomes dangling, it can lead to information leaks (if interesting data is put in the next structure allocated there) or to privilege escalation (if the now invalid memory is used in security checks). When a dangling pointer is used after it has been freed without allocating a new chunk of memory to it, this becomes known as a "use after free" vulnerability. For example, is a use after free vulnerability in Microsoft Internet Explorer 6 through 11 being used by zero day attacks by an advanced persistent threat.