Как я должен защитить от нападений жесткой ссылки?

  • Я хочу добавить данные в файл в/tmp.
  • Если файл не существует, я хочу создать его
  • Я не забочусь, владеет ли кто-то еще файлом. Данные не являются секретными.
  • Я не хочу, чтобы кто-то смог к состоянию состязания это в запись где-то в другом месте, или в другой файл.

Что лучший способ состоит в том, чтобы сделать это?

Вот моя мысль:

fd = open("/tmp/some-benchmark-data.txt", O_APPEND | O_CREAT | O_NOFOLLOW | O_WRONLY, 0644);
fstat(fd, &st);
if (st.st_nlink != 1) {
    HARD LINK ATTACK!
}

Проблема с этим: Кто-то может связать файл с некоторым недолгим моим файлом, так, чтобы /tmp/some-benchmark-data.txt совпал с/tmp/tmpfileXXXXXX, который другой мой сценарий использует (и открытый правильно использование O_EXCL и все это). Мои исходные данные затем добавляются в этот/tmp/tmpfileXXXXXX файл, в то время как он все еще используется.

Если мой другой сценарий, оказалось, открыл свой tempfile, затем удалил его, то используйте его; затем содержание того файла было бы повреждено моими исходными данными. Этот другой сценарий должен был бы затем удалить свой файл между открытым () и fstat () вышеупомянутого кода.

Так, другими словами:

This script          Dr.Evil        My other script or program
                                    open(fn2, O_EXCL | O_CREAT | O_RDWR)
                     link(fn1,fn2)
open(fn1, ...)
                                     unlink(fn2)
fstat(..)=>link is 1
write(...)
close(...)
                                    write(...)
                                    seek(0, ...)
                                    read(...) => (maybe) WRONG DATA!

И поэтому вышеупомянутое решение не работает. Существуют вполне возможно другие нападения.

Каков правильный путь? Помимо не использования мирового перезаписываемого каталога.

Править: Для защиты от результата, что злой пользователь создает файл с его владением и полномочиями или просто неправильными полномочиями (трудным соединением файла и затем удалением оригинала, или hardlinking недолгий ваш файл), я могу проверить владение и биты полномочий после проверки nlink.

Не было бы никакой проблемы безопасности, но также не предотвратит неожиданности. Худший случай - то, что я получаю некоторые свои собственные данные (из другого файла) в начале файла, скопированного из некоторого другого моего файла.

Редактирование 2: Я думаю, что почти невозможно защитить от кого-то твердое соединение имя к файлу, это открывается, удаляется и затем используется. Примерами этого являются упаковщики EXE, которые иногда даже выполняют удаленный файл через/proc/pid/fd-num. Гонки с этим заставили бы осуществление упакованной программы перестать работать. lsof мог, вероятно, найти, открыли ли кому-то еще inode, но это, кажется, больше проблемы, чем это стоит.

7
задан Thomas 5 April 2010 в 20:55
поделиться

2 ответа

Что бы вы ни делали, вы обычно получаете состояние гонки, когда кто-то другой создает ссылку, а затем удаляет ее к моменту выполнения вашего системного вызова fstat ().

Вы не сказали точно, что пытаетесь предотвратить. Конечно, существуют патчи ядра, которые предотвращают создание (жестких или символических) ссылок на файлы, которыми вы не владеете, в каталогах с доступом для записи (или прикрепленных каталогах).

Помещение его в каталог, не доступный для записи всем, кажется правильным.

SELinux, который кажется стандартным Linux с усиленной безопасностью, может иметь возможность настроить политику, запрещающую пользователям делать плохие вещи, которые нарушают работу вашего приложения.

В общем, если вы работаете как root, не создавайте файлы в / tmp. Другая возможность - использовать setfsuid (), чтобы установить uid вашей файловой системы для кого-то другого, тогда, если файл не доступен для записи этому пользователю, операция просто завершится ошибкой.

2
ответ дан 7 December 2019 в 16:41
поделиться

Если не считать того, что вы только что проиллюстрировали, единственное, что я пробовал, в итоге оказалось почти столь же гоночным и более дорогим, установив часы inotify на / tmp до создания файла, что позволяет в некоторых случаях перехватить событие жесткой ссылки.

Тем не менее, это все еще очень сложно и неэффективно, так как вам также потребуется выполнить поиск в ширину / tmp, по крайней мере, до уровня, на котором вы хотите создать файл.

Насколько мне известно, нет "надежного" способа избежать такой гонки, кроме как не использовать каталоги с возможностью записи слов. Каковы последствия того, что кто-то перехватит ваш ввод-вывод через жесткую ссылку ... получит ли он что-нибудь полезное или просто заставит ваше приложение проявлять неопределенное поведение?

1
ответ дан 7 December 2019 в 16:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: