LINUX.ORG.RU

Продемонстрирована возможность разработки частей Linux на Rust

 , ,


4

9

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

В статье отмечено, что данный язык хорошо подходит для системного программирования, будучи достаточно низкоуровневым и при этом лишённым многих недостатков C, и уже используется для написания новых ОС. Однако автор не считает создание ОС с нуля перспективным для серьёзного применения, и последовательный перенос отдельных частей Linux на Rust для решения различных проблем безопасности кажется ему более целесообразным.

В качестве «Proof of Concept» была приведена реализация системного вызова, содержащая вставки на Assembler внутри unsafe-блоков. Код компилируется в объектный файл, не связанный с библиотеками и интегрируемый в ядро во время сборки. Работа производилась на основе исходного кода Linux 4.8.17.

>>> Статья



Проверено: Shaman007 ()
Последнее исправление: sudopacman (всего исправлений: 5)

Ответ на: комментарий от www_linux_org_ru

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

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

Так и ООП в C++ ничего не позволяет, но почему-то можно сделать так:

class A {
    int private_val;
}

class B {
    void break_A(A* a) {
        *(int*)(a) = 0; 
    }
}

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

эээ... ммм... кому непонятные, а кому...

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

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

зачем выкидывать? использовать по отдельности — вполне рабочий вариант

До конца моё сообщение ты похоже не дочитал.

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

До конца моё сообщение ты похоже не дочитал.

не дочитал, да, но там ведь вроде что-то совсем очевидное сказано, типа «волга впадает в каспийское море»?

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

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

вот, например, почти весь с++ обслуживает библиотеку вокруг одной структуры данных под названием vtable (а та часть с++, которая си, обслуживает библиотеку вокруг функций setjmp и longjmp)

че скажешь, что не так?

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

В Rust assumptions принято выражать с помощью системы типов. Так что не представляю как такой вариант может пройти.

если бы так, то unsafe вероятно был бы не нужен

как в расте выразить тот факт, что struct A { int payload; A& next; } всегда закольцовано по указателям? (т.е. по ссылкам в данном случае)

(при этом в кольце м.б. от 0 до бесконечности экземпляров А)

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

как в расте выразить тот факт, что struct A { int payload; A& next; } всегда закольцовано по указателям? (т.е. по ссылкам в данном случае) (при этом в кольце м.б. от 0 до бесконечности экземпляров А)

struct A<'a> { payload: i32, next: &'a mut A }

Из гарантий того, что ссылки всегда валидны и может существовать только одна мутабельная ссылка на объект, можно вывести, что эти структуры всегда должны быть закольцованы.

Правда ещё гарантируется, что на эти структуры в программе не может быть никаких ссылок. Что не удивительно. Safe Rust предотвращает data races, а с такими структурами data races неизбежны.

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

а с такими структурами data races неизбежны.

я так полагаю, что ты хотел сказать «а с такими структурами раст не сможет предохранить от data races», поскольку избежать data races можно; но разница существенна

а теперь предположим, что payload константный; какие такие data races возможны в этом случае при наличии внешних ссылок на такие объекты?

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

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

не дочитал, да, но там ведь вроде что-то совсем очевидное сказано, типа «волга впадает в каспийское море»?

Ага. То есть, в точности то же, что ты ответил в предыдущем сообщении.

че скажешь, что не так?

Скажу, что ты опять занимаешься демагогией.

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

Да, я неправильно выразился, не «data races неизбежны», а Rust не может гарантировать их отсутствие.

Safe Rust гарантирует, что в успешно скомпилированной программе отсутствуют data races, double free, reference invalidation, но не гарантирует, что программа, в которой всё это отсутствует, скомпилируется.

какие такие data races возможны в этом случае при наличии внешних ссылок на такие объекты?

Вопрос неправильно поставлен. В Rust изменение структуры A<'a> будет undefined behavior, поскольку требует наличия более одной мутабельной ссылки на объект.

Правильно поставленный вопрос: как можно предоставить безопасный интерфейс к такой кольцевой структуре со следующим дополнительным набором условий: наличие/отсутствие многопоточного доступа, наличие/отсутствие возможности хранить указатели на элементы кольца, наличие/отсутствие возможности вставки/удаления в произвольном месте кольца.

Ответ будет зависеть от набора условий.

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

Дополнение. Естественно, не всё можно выразить с помощью системы типов. Что-то можно изолировать в модуле.

mod circular_single_linked_list {
    pub struct Finger<T> {
        ptr: *mut A<T>,
        count: usize,
    }

    impl<T> Finger<T> {
        pub fn new() -> Finger<T> { ... }
        pub fn point_to_next(&mut self) { ... }
        pub fn insert_after(&mut self, v: T) { ... }
        pub fn get_payload(&self) -> &T { ... }
        pub fn get_payload_mut(&mut self) -> &mut T { ... }
    }

    impl<T> Drop for Finger<T> { ... }

    struct A<T> {
        payload: T,
        next: *mut A<T>,
    }
}

Этот модуль гарантирует, что на кольцо будет только одна внешняя ссылка через Finger. Потом этот Finger можно безопасно расшаривать Rc<RefCell<Finger>>, Arc<RwLock<Finger>>.

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

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

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

ну вот простейший: указатель имеет класс Internal::RawPointer, а стандартная библиотека предоставляет RawPointer, который обычно с ним совпадает, но если хочется использовать 2 бита — то RawPointer надо делать потомком Internal::RawPointer (вот это 2 разных библиотеки не смогут сделать одновременно) и перекомпилировать стандартную библиотеку

(однако более приятно выглядит перегрузка оператора *, причем в стиле именно trait-ов)

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

Ага. То есть, в точности то же, что ты ответил в предыдущем сообщении.

ты как-то очень сложно выражаешься; если ты считаешь, что я говорю очевидные вещи — то просто замечательно! разъясни мне их пожалуйста... а то я сам их до конца не понимаю...

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

объясни, что такое по-твоему демагогия и где именно ты ее усмотрел

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

Да и вообще вводить такие абстракции на уровне указателей кажется странной идеей.

В любом случае, я по прежнему не понимаю сути претензий. Ты говоришь о том, что ООП (именно в этой ситуации) делает что-то лучше, но реальных примеров, а не гипотетических, нет. Опять же, не понятно почему с таким странным примером не справились трейты раста, которые «недо-ООП». Или разговор про С++ заходил, где данная «проблема», опять же, никак не решается. Тогда в чём смысл сравнения?

Если что, я не хочу сказать, что раст - это предел мечтаний и улучшить ничего нельзя. Даже без таких «радикальных улучшений» в языке очень многое надо допиливать. Просто сейчас имеется условно стройная и не противоречивая система возможностей. Да, не решаются все-все проблемы, но я очень сомневаюсь, что они в принципе могут решиться. И тут предлагается делать нечто, которое всё усложнит, а профит не особо очевиден. У меня, как у «пользователя языка» совершенно другие хотелки. Статьи/рассуждения о том, что можно было бы улучшить периодически попадаются, причём от людей с очень разными «основными языками», но там как-то тоже более вменяемые желания описаны.

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

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

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

я считаю данную претензию неуместной (и еще и удивительной)

пример: видя, как кто-то крадет, я могу закричать «воруют!», и мой крик будет общественно полезным даже при том, что я не сопроводил свой крик выполнимыми способами поимки вора либо закрытия для него возможностей воровать

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

добавлю: «воровство» раста идет не только по фронту завышения его возможностей, но и фронту преувеличения ненадежности си; к примеру «as soon as your program starts talking to C it stops being safe»

Even other safe languages generally expose C interfaces for the world at large! Regardless of why you're doing it, as soon as your program starts talking to C it stops being safe. https://doc.rust-lang.org/nomicon/meet-safe-and-unsafe.html

это ложь, так как существуют интерфейсы, которые можно выставить на си, не повредив корректности программы

з.ы. под «си» я называю код на языке, отвечающий стандарту си — это важно

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

Ты говоришь о том, что ООП (именно в этой ситуации) делает что-то лучше, но реальных примеров, а не гипотетических, нет.

что значит «реальных»? ты мне предлагаешь молчать до тех пор, пока 2 библиотеки реально не подерутся (из-за совместной модификации чего-то через unsafe), а потом сказать «ну я еще 10 лет назад, в 2017, думал об этом, но нигде не написал»? так?

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

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

короче: для дошкольников сойдет

для меня — нет

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

это ложь, так как существуют интерфейсы, которые можно выставить на си, не повредив корректности программы

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

Так и тут, как только вызвал код на C, компилятор уже не может проверить корректность интерфейсов и не даcт гарантии безопасности. А отсутствие гарантий это и есть unsafe.

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

Так и тут, как только вызвал код на C, компилятор уже не может проверить корректность интерфейсов и не даcт гарантии безопасности. А отсутствие гарантий это и есть unsafe.

похоже нет — там говорится про «expose C interfaces for the world», а не вызов си-кода

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

Статьи/рассуждения о том, что можно было бы улучшить периодически попадаются, причём от людей с очень разными «основными языками», но там как-то тоже более вменяемые желания описаны.

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

однако статьи/рассуждения (про которые ты говоришь) я бы почитал — накидай ссылок

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

упс?

по крайней мере есть принципиальная разница между «компилятор не может доказать, что это safe» и «it stops being safe»

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

ну и еще — ты таки поймешь разницу, или мне привести пример проги на чем-то, что expose C interfaces и не перестает быть safe?

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

Так и тут, как только вызвал код на C, компилятор уже не может проверить корректность интерфейсов и не даcт гарантии безопасности.

кстати, рассмотрим такой случай

у нас в каком-то safe-языке есть какие-то константные структуры данных; мы expose C interfaces для того и так, чтобы через эти интерфейсы только читать эти структуры данных

теперь, с какого такого перепугу, компилятор в safe-языке «уже не может проверить корректность интерфейсов и не даcт гарантии безопасности» ?

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

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

что инвалидирует твою аналогию — это возможность «открутить крышку» только на чтение с помощью модификаторов const или средствами os, например сегмента разделяемой памяти «только на чтение»

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

у нас в каком-то safe-языке есть какие-то константные структуры данных; мы expose C interfaces для того и так, чтобы через эти интерфейсы только читать эти структуры данных

Код на C тебе даст указатель и размер куда писать эти твои «константные данные». А будет ли указатель валидным уже не изветно. А может еще и из разных потоков в один и тот же буфер попросить записать.

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

чувак, уясни разницу — я утверждаю, что иногда существуют безопасные C interfaces к safe-языку, а вовсе не то, что все C interfaces к safe-языку всегда безопасны

поэтому твой пример про указатель к буферу меня не опровергает

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

так?

Нет, не так.

Предлагаю показать конкретный пример как ООП чем-то помогает в описанных условиях.

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

пример: видя, как кто-то крадет, я могу закричать «воруют!»

Очередная неадекватная аналогия, причём сразу по двум причинам. Во первых, кричишь ты (например) о том, что в Москве воруют находясь при этом в диком лесу - аудитория не та. Во вторых, ты кричишь «воруют!» - люди оглядываются, проверяют карманы - всё на месте и начинают недоуменно на тебя смотреть.

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

чувак, уясни разницу — я утверждаю, что иногда существуют безопасные C interfaces к safe-языку

Ну и как часто ты на практике встречаешь C интерфейсы в которых совсем нет указателей? Можешь привести пример какой-нибудь готовой библиотеки?

Ну и вообще в оригинальной цитате говорилось не только про C интерфейсы к безопасным языкам (это был просто пример), а в целом про взаимодействие с C кодом. И в общем случае оно не безопасно.

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

я, конечно, ценю твои попытки научить меня тому, какие мои желания вменяемые, а какие — нет,

У тебя явно какие-то проблемы с чтением (или пониманием).

Совсем недавно проскакивало сравнение от Scala-программиста: https://beachape.com/blog/2017/05/24/rust-from-scala/ Видел сравнения с D, Swift и ещё всяким разным, но это уже искать надо.

Где-то была ещё интересная тема на реддите как раз про наиболее ожидаемые фичи, но сходу найти не смог.

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

Смотри от пафоса не лопни.

и где тут пафос?

когда окружающие упорно не хотят (или не могут?) отличить https://ru.wikipedia.org/wiki/Квантор_существования от https://ru.wikipedia.org/wiki/Квантор_всеобщности несмотря на несколько попыток им это объяснить для данного конкретного случая — да, я про дискуссию «as soon as your program starts talking to C it stops being safe» — остается им мягко напомнить, что не все люди настолько альтернативно одаренные, как они

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

Ну и как часто ты на практике встречаешь C интерфейсы в которых совсем нет указателей? Можешь привести пример какой-нибудь готовой библиотеки?

для того, чтобы доказать, что высказывание «as soon as your program starts talking to C it stops being safe» — ложь, я не должен встречать на практике «C интерфейсы в которых совсем нет указателей» и/или приводить подобный пример «какой-нибудь готовой библиотеки»

з.ы. тем не менее хинт: интерфейс может быть построен на целых числах вместо указателей; вот один софт — ты про него точно много раз слышал — так и делает, юзает file descriptor в интерфейсе

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.