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