LINUX.ORG.RU

В Rust borrow checker обнаружены ошибки, существовавшие 11 лет и позволяющие обращаться к освобождённой памяти

 , ,


1

7

Проблема заключается в том, что требования borrow checker к времени жизни структуры можно обойти с помощью присвоения ковариантных полей.

В качестве примера кода, демонстрирующего ошибку, приведён (ссылка на Rust playground; для запуска нужно нажать кнопку “Run”):

struct Q<T, F: FnMut(&T)>(Option<T>, F);

impl<T, F: FnMut(&T)> Drop for Q<T, F> {
    fn drop(&mut self) {
        self.1(self.0.as_ref().unwrap())
    }
}

fn main() {
    let mut out: Option<&'static _> = None;
    {
        let l = vec![vec![1]];
        let mut q = Q(None, |s| {
            out = Some(*s);
        });
        q.0 = Some(&l);
    }
    println!("{:?}", out);
}

Обнаружение unsoundness (ошибок, приводящих к нарушению гарантий компилятора) в borrow checker’е Rust — не самое необычное явление. Но эта ошибка примечательна тем, насколько простым может быть код, вызывающий её. Для других ошибок приходилось сильно изворачиваться, чтобы избежать проверок компилятора.

Ссылка на issue: https://github.com/rust-lang/rust/issues/164250

★★

Последнее исправление: shdown (всего исправлений: 2)
Ответ на: комментарий от CrX

Любые слова нужно читать в контексте. Я писал ответ на «Разрекламировали язык, а память всё равно течёт...».

А не так, что «Во, смотрите все, как круто это всё работает!».

Я не фанат Rust'а, а просто сторонник. И всяких «вау, круто» я никогда не писал и не напишу.

Я пишу лишь о том, что заявленные фичи на практике всё-таки работают. Даже несмотря на баги.

saahriktu ★★★★★
()
Ответ на: комментарий от firkax

Создатели Rust’а просто очень старались, чтобы не получилось похоже на Си. Вот и выбрали из двух вриантов - быть как Си и быть обфусцированным по умолчанию - второй.

Дилемма Нетакусика!

Bfgeshka ★★★★★
()
Ответ на: комментарий от saahriktu

Любые слова нужно читать в контексте.

Именно. И в другом контексте твои слова не звучали бы настолько нелепо.

Я не фанат Rust’а, а просто сторонник. И всяких «вау, круто» я никогда не писал и не напишу.

Со стороны выглядит иначе.

Я пишу лишь о том, что заявленные фичи на практике всё-таки работают. Даже несмотря на баги.

Надо же! Бывает такое, когда какие-то заявленные фичи работают?

Нет, ну серьёзно?..

CrX ★★★★★
()
Ответ на: комментарий от shdown

gcc 10, и -O3 включил (ты про него не писал), не сегфолтится.

Впрочем, это не так важно, переменная и правда же освобождается и ей наверно деструктор вызывается, так что если что и печатается то рандомные данные.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от CrX

Я просто очень не люблю хейт. В т.ч. и как явление.

Кто-то может сказать, что я сам в своё время хейтил иксы и юникод, но на самом деле я их никогда не хейтил. Именно поэтому я довольно легко вернулся в иксы с юникодом.

Я в те прошлые годы лишь обосновывал свою позицию. Мне тогда казалось, что удобнее и проще сидеть в ядерной консоли с локалью KOI8-R. А кто-то просто не понимал, что не все юзкейсы в обязательном порядке требуют локали UTF-8.

saahriktu ★★★★★
()
Ответ на: комментарий от slackwarrior

Математически доказанные это были бы не костыли тогда и дыры бы не находились. А тут именно на авось действуют.

firkax ★★★★★
()
Ответ на: комментарий от saahriktu

Если от него есть практическая польза, то он всё-таки что-то предотвращает.

«Его пример другим наука» (с)

slackwarrior ★★★★★
()
Ответ на: комментарий от saahriktu

Я просто очень не люблю хейт. В т.ч. и как явление.

Понимаю, принимаю. Я к хейту отношусь тоже скорее негативно, но терпимо. А вот тупизну и фанатичные выкрики очень не люблю…

Кто-то может сказать, что я сам в своё время хейтил иксы и юникод, но на самом деле я их никогда не хейтил. Именно поэтому я довольно легко вернулся в иксы с юникодом.

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

CrX ★★★★★
()

Комментарии настоялись. Поставил добрых смайликов всем отметившимся с чувством юмора, насколько хватило лимитов ЛОРа по реакциям)

wandrien ★★★★
()
Ответ на: комментарий от saahriktu

Создатели Rust’а осознанно выбрали выразительность вместо псевдокодовости.

Ну понятно, что не случайно, имеем же мы право любить читаемость вместо выразительности? Можно вообще в регулярку каждую строчку засунуть, она знаешь какая выразительная? Правда без коммента и сам не вдруг прочитаешь что написал в прошлый раз

pihter ★★★★★
()
Ответ на: комментарий от yatazet

я чувствую запах очередного растосрача

Конечно чувствуешь: ты же уже в него вступил!

pihter ★★★★★
()
Ответ на: комментарий от saahriktu

у тя чё rust first love one’s love?

чисто для лучшей коммуникации - вспомни любой инструмент который буквально меняет распределение ситуаций - перестаёт ли быть нужной тб - нет - становятся ли часто случаи нештатные более замудрёнными - очевидно да - и пример из ТС и показывает - что не вполне отдавая отчёт достатоточно легко неофиту натолкнутся на поведение прямо нарушающее контракт инструмента - а вот за последнее специально существуют в обществе механизм рекламации

qulinxao3 ★☆
()
Ответ на: комментарий от saahriktu

Вы не понимаете в чём суть borrow checker’а.

А суть в том, что он реально предотвращает возникновение ряда ошибок. И даже если этот ряд не совсем полный, то он всё равно довольно большой

Воу Воу, погодите, а разве не было заявлено что компилятор ГАРАНТИРУЕТ отсутствие подобного при не использовании ансейва? Уже же 10 лет из каждого утюга льётся мантра что си - говно, она течёт, давайте перепишет на раст, у нас ГАРАНТИЯ не текучести! В си, знаешь ли, компилятор тоже много ошибок предотвращает, но да не все. Получается и в си не все и расте, получается, что он такое же говно как и все, а вот только корчил из себя святого?

Типа, знаешь, если какой-то мужик ходит к проституткам по вечерам, то всем, в принципе и плевать, ну ходит и ходит, а вот если это делает священник, который днем всем за праведную жизнь затирает, то всем уже не плевать, потому что что-то тут уже не сходится

pihter ★★★★★
()
Последнее исправление: pihter (всего исправлений: 1)
Ответ на: комментарий от pihter

Короче, мне тут уже, так сказать, намекнули, что спор тут у вас не технического характера.

А я тут участвую в технических спорах. По этой сути я уже всё изложил выше.

А что шум вокруг Rust'а, включая «Rust ради Rust'а» является злом - это я согласен.

Но я за то, чтобы на нём писали те, кому он нравится технически. Как те же питонисты пишут на Python, джависты на Java, сишники на Си,... и т.д.

Не больше, но и не меньше.

saahriktu ★★★★★
()
Ответ на: комментарий от saahriktu

какой качественый мануал по расту для свитчера с вирт(Никалауса)-языков(сяшко тож такой)?

qulinxao3 ★☆
()
Последнее исправление: qulinxao3 (всего исправлений: 1)
Ответ на: комментарий от saahriktu

кто-то просто не понимал, что не все юзкейсы в обязательном порядке требуют локали UTF-8.

Не все юзкейсы в обязательном порядке требуют строчных и русских букв. Шести битов XBATIT BCEM!

algo
()
Ответ на: комментарий от pihter

Воу Воу, погодите, а разве не было заявлено что компилятор ГАРАНТИРУЕТ отсутствие подобного при не использовании ансейва?

Было конечно. Только компилятор люди делают. Можно подумать ты всегда программы без ошибок пишешь.

bbc69
()
Ответ на: комментарий от bbc69

Воу Воу, погодите, а разве не было заявлено что компилятор ГАРАНТИРУЕТ отсутствие подобного при не использовании ансейва?

Было конечно. Только компилятор люди делают. Можно подумать ты всегда программы без ошибок пишешь

Мы, похоже, как-то по-разному понимаем слово «гарантировано». Этак я могу написать программу на си, самую любую, и продавать ее для управления самолетами, атомными станциями, хим производством и прочим подобным, заявляя что в ней, программе, гарантированно нет ошибок. Но это только пока не найдут ошибки, когда найдут – скажу: но я же человек, человеку свойственно ошибаться, чего вы хотели

pihter ★★★★★
()
Ответ на: комментарий от dynamic_cast

долго всматривался в этот говнокод и еще раз убедился, что C++ это простой и понятный язык

Ну да, простой, пока пишешь на уровне hello world.

WatchCat ★★★★★
()
Ответ на: комментарий от qulinxao3

Универсальных мануалов ни по какому языку программирования нет и не будет.

Только практика, только хардкор. С перелопачиванием самых разных источников.

saahriktu ★★★★★
()
Ответ на: комментарий от pihter

Да нет, у Вас просто ненависть к языку. Произошло то, чего быть не должно.

Что до самолётов, мне не доводилось для них писать. И там либо системы защиты должны быть многоуровневыми, либо спец языки с доказательством корректности. Либо и то, и то.

bbc69
()

ИМХО тема заслуживает отдельной новости. Ну или в Толкс. Я думаю, что это нормальная ситуация, когда ЯП всё больше и больше используют, анализируют работу компилятора и т.д. Когда-то давно я решил потыкать раст палкой, взял ту версию, что шла в используемом мной дистрибутиве Линукс, и с полпинка нашёл баг с целочисленным переполнением. Но оказалось, что его уже исправили в более новых версиях компилятора. Классно, когда язык реально используется людьми, над его проблемами работакуют, фиксят баги.

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

seiken ★★★★★
()
Ответ на: комментарий от saahriktu

так вы свой тетеритический путь в раст апосля других языков(каких кста)(ну и сред и стилей программирования тож каких)резюмируйте - нам и мне наука !

qulinxao3 ★☆
()
Ответ на: комментарий от slackwarrior

Математически доказанных?

А математика и есть набор подогнанных костылей.

ant1
()
Ответ на: комментарий от pihter

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

Кто-то заявлял, что в компиляторе руста гарантированно нет ошибок?

ugoday ★★★★★
()
Ответ на: комментарий от shdown

Код на Rust, в теории, должен распечатать опциональный вектор векторов (в моём коде я сократил это до вывода первого значения первого вектора):

Да, только вектор умирает при выходе из блока (на закрывающей скобке). Собственно, потому и падает.

bbc69
()
Ответ на: комментарий от man-from-36

Тут выше аналог предложили:

template<class T> struct Q : public std::pair<std::optional<T>, std::function<void(T&)>> {
    using std::pair<std::optional<T>, std::function<void(T&)>>::pair;

    ~Q() {
        this->second(this->first.value());
    }
};

Абсолютно другое дело, согласись. Сразу всё понятно стало.

bbc69
()

Попробовал поразбираться в силу способностей.

Проблема, как я понял, замыкание, которое компилятор не может нормально проверить. С учётом того, что замыкание - это объекты для функцианутых, не удивительно даже. При переделке на объекты, всё ожидаемо грохается. Не пользуйтесь замыканиями и будет вас счастье.

bbc69
()
Ответ на: комментарий от man-from-36

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

ugoday ★★★★★
()
Ответ на: комментарий от qulinxao3

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

Тем более, что в 99,99% случаев используются одинаковые подходы и я их вычисляю на ходу.

Так и тут, смотрим на Rust и подмечаем:

  • Тип данных задаётся в таком же формате как в Паскале через «имя: тип»;
  • Функции объявляются коротким ключевым словом как в Python'е, только вместо ключевого слова «def» здесь ключевое слово «fn»;
  • switch'а нет, но есть match как в Python;
  • Переменные объявляются как в Basic'е через ключевое слово «let», только при этом нужно ещё указывать ключевое слово «mut» чтобы не получилась константа;
  • Вместо «#include» или «import» используется ключевое слово «use»;

и т.д.

saahriktu ★★★★★
()
Ответ на: комментарий от ggrn

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

hbee ★★★★
()
Ответ на: комментарий от qulinxao3

Как это можно доказать, имея std::mem::forget, Box::leak и возможность создать циклы из Rc? Не путаешь чего-то?

unC0Rr ★★★★★
()
Ответ на: комментарий от saahriktu

поскольку я со справочниками могу писать на любых языках программирования, даже на тех, которые вижу впервые

Ну напиши на хаскеле какой-нибудь сетевой сервис, вместе похихикаем над твоими справочниками.

unC0Rr ★★★★★
()
Ответ на: комментарий от ggrn

Внезапно, времена жизни ссылок есть в любом языке со ссылками. Только обычно заметаются под ковёр, чтоб ты мог с лёгкостью получить невалидный итератор после ресайза вектора в C++.

hbee ★★★★
()
Ответ на: комментарий от hbee

греческими буквами (может, сделают в будущем)

Прям вот так что ли impl<απο> Deserialize<απο> for Baz { /* ... */ }?

ratvier ★★
()
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария