Переповнення буфера: причини, ефективні методи вирішення проблеми і необхідний захист

Альтернативна захист

Однією з часто пропонованих альтернатив пов’язані версії, які записують у максимальний розмір цільового буфера. На перший погляд це виглядає як ідеальне рішення. На жаль, у цих функцій є невеликий нюанс, який викликає проблеми. При досягненні межі, якщо завершальний символ не поміщається в останній байт, виникають серйозні збої при читанні буфера.

У цьому спрощеному прикладі видно небезпеку рядків, не закінчуються нулем. Коли foo поміщається в normal buffer, він завершується нулем, оскільки має додаткове місце. Це найкращий варіант розвитку подій. Якщо байти в переповнення буфера на стеку будуть в іншому символьному buffer або іншої друкованої рядку, функція друку продовжити читання, поки не буде досягнутий завершальний символ цього рядка.

Недолік полягає в тому, що мова C не надає стандартну, безпечну альтернативу цим функціям. Тим не менше є і позитив – доступність декількох реалізацій для конкретної платформи. OpenBSD надає strlcpy і strlcat, які працюють аналогічно функціям strn, за винятком того, що вони усекают рядок на один символ раніше, щоб звільнити місце для нульового термінатора.

Аналогічно Microsoft надає свої власні безпечні реалізації часто використовуваних функцій обробки рядків: strcpy_s, strcat_s і sprintf_s.

Використання безпечних альтернатив, перерахованих вище, є кращим. Коли це неможливо, виконують ручну перевірку кордонів і нульове завершення при обробці строкових буферів.