The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



"Локальная root-уязвимость в подсистеме inotify ядра Linux"
Версия для распечатки Пред. тема | След. тема
Форум Разговоры, обсуждение новостей
Исходное сообщение [ Отслеживать ]
Присылайте удачные настройки в раздел примеров файлов конфигурации на WIKI.opennet.ru.
. "Локальная root-уязвимость в подсистеме inotify ядра Linux" +2 +/
Сообщение от Orduemail (ok), 05-Авг-17, 17:06 
> [i]чисто механически, следуя определённым правилам программирования, типа "не использовать
> unsafe"[/i] - не могу осознать, каким образом unsafe связан c состоянием
> гонки в данном случае?
> я не знаю rust и интересно, каким образом он помогает избегать состояний
> гонки.

Я сейчас потратил полчаса пытаясь изобрести краткое объяснение. Мне не удалось это. Там вся магия сокрыта в системе типов с лайфтаймами и borrowing'е, и мне кажется, что единственный способ понять как это работает -- это взять и попытаться создать race condition в rust'е. Если потратить несколько дней на борьбу с borrow checker'ом, пробуя объехать его на кривой козе и так, и эдак, то в голове начинает зарождаться понимание, почему race condition невозможен. Если потратить ещё месяц на то, чтобы читать статьи и чужой код, то можно понять как, несмотря на всё это, возможно писать какой-нибудь рабочий и полезный код. Но так или иначе, чтобы понять как это работает, надо рассмотреть десяток примеров с потенциальным race condition, разбирая каждый на предмет "а если попытаться так, то ничего не получиться потому-то и потому-то", и завершая это сентенцией типа "таким образом у нас есть такие-то пути справится с проблемой, этот лучше в таких-то ситуациях, а этот в таких-то".

Но чтобы не звучать совсем абстрактно, я приведу один пример. Если у меня есть

struct Dummy {
    a: u32,
    b: u32,
}

Допустим я хочу чтобы для этой структуры всегда выполнялся бы какой-нибудь инвариант, например, a = 2*b.

Допустим, я напишу функцию:

fn double_this_dummy(dummy: &mut Dummy) {
    dummy.a *= 2;
    dummy.b *= 2;
}

Инвариант сохраняется. Можно предположить, что параллельный поток в это время изменит именно этот объект, вот ровно между удвоением a и b он возьмёт и уменьшит a на 3 и b на 6. Тогда инвариант будет нарушен. Но rust не позволит мне создать две mutable ссылки на этот объект, поэтому если внутри этой функции у меня есть ссылка на dummy, то у параллельного потока её не будет. А значит никакого race condition'а не случится.

Если мы попытаемся таки создать две mutable ссылки на один и тот же объект, так чтобы одна была в одном потоке, а другая в другом, то это выльется в долгий сеанс переругивания с borrow-checker'ом, и кончится либо использованием unsafe кода, либо осознанием своей глупости и нахождением safe пути достичь наших целей. Сложно объяснить как это происходит -- это надо испытать на себе.

Ответить | Правка | Наверх | Cообщить модератору

Оглавление
Локальная root-уязвимость в подсистеме inotify ядра Linux, opennews, 04-Авг-17, 23:02  [смотреть все]
Форумы | Темы | Пред. тема | След. тема



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру