TGViewer
Bash Days | Linux | DevOps Bash Days | Linux | DevOps @bashdays · 23.6K subscribers
Post #131 8.2K
Большинство утилит/программ/скриптов и т.п. работают с временными файлами. Сначала они создают этот временный файл, пишут в него какие-то данные, а на выходе отдают готовый результат, будь то файл с выгрузкой либо что-то другое. А временный файл с которым производилась работа, естественно зачищается.

Наша задача на сегодня, перехватить этот временный файл, до того как он удалится. А для чего? Ситуации разные бывают.

Недавно я дебажил проблему с выгрузкой, которая годами работала, а потом сломалась, на выходе я получал пустой файл. Эту выгрузку делал как раз бинарник неизвестного происхождения. Отследить логику работы само собой не представлялось возможным.

Этот случай я успешно отдебажил. Временный файл удалялся ДО того как стать файлом выгрузки. Почему? Потому что процесс удаления временного файла работал в отдельном потоке (thread) и удалял временный файл спустя 30 секунд.

А так как выгрузка с каждым годом становилась все больше, 30ти секунд стало мало. По итогу временный файл удалялся, а на выходе создавался пустой файл без каких либо данных. Естественно никакой обработки эксепшенов в бинарнике не было, вечный статус - завершено успешно! Файл же есть на выходе, значит успешно. Не поспоришь.

На такие ёбнутые случаи и нужен strace, чтобы хоть немного понять, что происходит.

Короче расчехляем нашу лабораторию и создаем скрипт. Бинарники мучить не будем, bash скрипта будет достаточно для понимания.

#!/bin/bash

echo $UID > /tmp/test.txt
unlink /tmp/test.txt

UID обозначает идентификатор пользователя, то есть номер, назначенный каждому пользователю Linux.

1. Записываем во временный файл /tmp/test.txt этот самый UID.
2. Удаляем временный файл.

Почему не rm а unlink? Потому что в моём случае это был именно unlink, который я нашел просматривая лог strace. Чем отличается unlink от rm, расскажу в следующих постах.

Так, подопытный скрипт есть. Запускаем так:

strace -yfe inject=unlink:error=EACCES ./script.sh

В этой конструкции мы говорим strace, чтобы проинжектил наш системный вызов unlink и передал ему насильно ошибку EACCES (Permission denied).

В тот момент когда скрипт попытается удалить временный файл, наша инъекция не даст ему это сделать и завершит скрипт с ошибкой:

[pid 677954] unlink("/tmp/test.txt") = -1 EACCES (Permission denied) (INJECTED)

А сам временный файл останется на диске. Открываем его и смотрим, что же там внутри происходит.

По умолчанию инъекция будет сделана всем системным вызовам unlink, но есть возможность указать диапазон или конкретный индекс срабатывания. В этом посте можешь глянуть как узнать конкретный индекс (смотри строчку с when=4+).

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

Отдал результаты дебага разработчикам, фиксить это конечно никто не стал, такой гемор никому не нужен. По итогу ребята с нуля переписали на golang и сразу чудным образом нашлась документация. Жиза.

Вот такие приключения порой случаются. Изучай. Хорошего дня!

tags: #linux #debug #bash
—
💩 @bashdays
  • 👍 115
More from @bashdays
  1. Sep 29, 2026Самый жаркий холивар в команде — это не systemd, а какие заказать роллы на всю команду. Од…
  2. Sep 24, 2026Post #1565
  3. Sep 23, 2026Здрасти приехали, решил я в кой-то веке воспользоваться услугами Codex, создал аккаунт, по…
  4. Sep 22, 2026Всем привет, с вами TagdTagd. Сегодня опять поднимем тему архивов, но немного с другой сто…
  5. Sep 15, 2026Всем привет, с вами TagdTagd. И это вторая часть. Практическая. С первой частью можешь озн…
  6. Sep 9, 2026Всем привет, с вами TagdTagd! Я тут вынужденно перешёл на MAX. Просто Telegram перестал ра…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →