⚡️Буква-убийца
Почти детективная история про то, как мы нажатием на одну кнопку убили систему на сервере.
(дважды)
Пару лет назад, после перехода на новую версию компилятора gcc, мы заметили, что при сборке проекта стало появляться предупреждение:
warning: the use of 'mktemp' is dangerous, better use 'mkstemp'
Всё при этом работало нормально, проект билдился успешно, но каждый раз при сборке это предупреждение "мозолило глаз".
Ну, работы на 5 секунд, берём, нажимаем кнопку 'S' и превращаем mktemp в mkstemp. Собираем проект, ворнинга нет, красота!
Запускаем тесты для порядка, всё поначалу идёт, а потом подвисает... Висит 10 секунд, 20, 30...
Интересно, думаем. Идём в другую консольку, чтобы посмотреть gstack'ом, где всё повисло.
Запускаеm ps -ax | grep test, чтобы узнать PID процесса, и получаем:
bash: /usr/bin/ps: /lib64/ld-linux-x86-64.so.2: bad ELF interpreter: No such file or directory
📍WTF???
❗️Срочно стопаем тест, переходим в mc (который был уже запущен и пока работает), и наблюдаем ужасное:
/lib, /lib64 отсутствуют, /var пустой, от /bin, /home и /opt какие-то ошмётки остались...
Очевидно, тест в процессе работы попытался удалить корневую директорию, и весьма в этом преуспел.
Надо заметить, что ввиду специфики разработки, вся работа у нас ведется под суперпользователем root. Да, это ужасно и небезопасно,
но значительно упрощает жизнь разработчику, поэтому мы привыкли. Ну и получили в итоге.
📌Что же случилось с тестом? Очевидно, его работу изменило то самое нажание одной единственной кнопки 'S'.
Тест использует функцию mktemp для генерации имени временной папки, в которой хранит тестовые данные. В конце теста папка рекурсивно удаляется.
Папка. Рекурсивно. Удаляется.
Функция mktemp возвращает си-строку. А функция mkstemp, как оказалось, возвращает int - дескриптор временного файла.
То есть 'S' не просто добавляет "безопасности" к функции, но и меняет её прототип. Совсем другая функция, в общем, оказалась.
Значение, которое нам вернула mktemp/mkstemp мы присваиваем std::string переменной и далее используем, как имя временного каталога, который в конце удаляем.
path = path + ".XXXXXX";
path = mkstemp(&path[0]);
Почти детективная история про то, как мы нажатием на одну кнопку убили систему на сервере.
(дважды)
Пару лет назад, после перехода на новую версию компилятора gcc, мы заметили, что при сборке проекта стало появляться предупреждение:
warning: the use of 'mktemp' is dangerous, better use 'mkstemp'
Всё при этом работало нормально, проект билдился успешно, но каждый раз при сборке это предупреждение "мозолило глаз".
Ну, работы на 5 секунд, берём, нажимаем кнопку 'S' и превращаем mktemp в mkstemp. Собираем проект, ворнинга нет, красота!
Запускаем тесты для порядка, всё поначалу идёт, а потом подвисает... Висит 10 секунд, 20, 30...
Интересно, думаем. Идём в другую консольку, чтобы посмотреть gstack'ом, где всё повисло.
Запускаеm ps -ax | grep test, чтобы узнать PID процесса, и получаем:
bash: /usr/bin/ps: /lib64/ld-linux-x86-64.so.2: bad ELF interpreter: No such file or directory
📍WTF???
❗️Срочно стопаем тест, переходим в mc (который был уже запущен и пока работает), и наблюдаем ужасное:
/lib, /lib64 отсутствуют, /var пустой, от /bin, /home и /opt какие-то ошмётки остались...
Очевидно, тест в процессе работы попытался удалить корневую директорию, и весьма в этом преуспел.
Надо заметить, что ввиду специфики разработки, вся работа у нас ведется под суперпользователем root. Да, это ужасно и небезопасно,
но значительно упрощает жизнь разработчику, поэтому мы привыкли. Ну и получили в итоге.
📌Что же случилось с тестом? Очевидно, его работу изменило то самое нажание одной единственной кнопки 'S'.
Тест использует функцию mktemp для генерации имени временной папки, в которой хранит тестовые данные. В конце теста папка рекурсивно удаляется.
Папка. Рекурсивно. Удаляется.
Функция mktemp возвращает си-строку. А функция mkstemp, как оказалось, возвращает int - дескриптор временного файла.
То есть 'S' не просто добавляет "безопасности" к функции, но и меняет её прототип. Совсем другая функция, в общем, оказалась.
Значение, которое нам вернула mktemp/mkstemp мы присваиваем std::string переменной и далее используем, как имя временного каталога, который в конце удаляем.
path = path + ".XXXXXX";
path = mkstemp(&path[0]);