LINUX.ORG.RU

Fil-C — компилятор для языков C и C++, гарантирующий безопасную работу с памятью

 , , ,


1

5

Цель разработки компилятора – полная совместимость с синтаксисом языков Си и С++ при обеспечении полной безопасности работы с памятью. Заявляется, что для использования достаточно пересобрать существующий код, так уже компилируются и работают bzip2, zip, pcre и ncurses. С незначительными модификациями поддерживается сборка OpenSSH, OpenSSL, CPython, SQLite, Lua, Curl, Lynx, jpeg6b, zsh, xzutils и simdutf.

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

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

Компиляция занимает в 1,5-5 раз больше времени, чем у gcc. Скорость выполнения в 1.2 раза ниже, чем при работе аналогичных программ, скомпилированных gcc. Пока компилятор доступен только для linux-платформ, такое решение было принято разработчиками для того, чтобы не распылять усилия. Линковка с объектным кодом, созданным другими компиляторами, невозможна в силу разного ABI.

Задействованный в Fil-C механизм MonoCap основывается на применении 16-байтовых указателей, в которых помимо адреса в памяти, указывается ссылка на объект, включающий сведения о возможностях (capability), таких как верхняя и нижняя границы буфера, ассоциированного с указателем, а также массив, определяющий типы данных, хранимые в каждом блоке памяти (1 байт с информацией о типе (unset, int, ptr, free) для каждого 16-байтового блока памяти). При каждом обращении к памяти по указателю осуществляется проверка границ и типа (например, в память с типом «ptr» не могут быть записаны данные с типом «int» и наоборот).

Все операции выделения и освобождения памяти обрабатываются сборщиком мусора FUGC (Fil’s Unbelievable Garbage Collector), который при освобождении памяти переводит все связанные с освобождаемым буфером записи о типах в значение «free» и затем перенаправляет все указатели на освободившиеся объекты на отдельный объект, сигнализирующий о том, что память уже освобождена. Любое дальнейшее обращение к блоку данных с типом «free» или по указателю, связанному с освобождённым объектом, приводит к генерации исключения, что позволяет защититься от уязвимостей класса use-after-free. Сборщик мусора работает параллельно и не приостанавливает выполнение других потоков.

Использование комбинации из MonoCaps и FUGC позволяет сохранить возможность привычной работы с указателями и оставить неизменной семантику вызовов malloc и free, предоставив при этом гарантированную защиту. Код программы может содержать различные логические ошибки, такие как неправильное приведение типов, неверные арифметические операции с указателями, состояния гонки и несвоевременный вызов функции free(), но независимо от всего этого, Fil-C запомнит исходные границы и тип данных, и прервёт выполнение, если будет предпринята попытка доступа по указателю к области вне запомненных границ, обращения к освобождённому блоку памяти или чтения данных с типом «int» как указателя или наоборот.

Автор Fil-C, Филипп Пизло (Filip Pizlo), занимает в компании Epic Games пост директора, отвечающего за проекты, связанные с языками программирования. Филипп имеет богатый опыт работы над виртуальными машинами, языками программирования, компиляторами и сборщиками мусора, например, в IBM он развивал язык программирования X10, в Microsoft работал над сборщиками мусора Stopless, Clover и Chicken, в Apple занимался JIT-компилятором и оптимизациями браузерного движка WebKit, в Epic Games возглавляет команду разработчиков, развивающую язык программирования Verse и связанную с ним виртуальную машину. Филипп также является одним из ключевых разработчиков виртуальных машин Jikes RVM, Ovm и Fiji VM.

>>> Подробности

★★★★★

Проверено: hobbit ()
Последнее исправление: unfo (всего исправлений: 7)
Ответ на: комментарий от zabbal

16-байтовых указателей

Размерность перепутал?

нет, компилятор использует 128 битную размерность для указателей.

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

Охренеть: https://github.com/pizlonator/llvm-project-deluge/blob/deluge/Manifesto.md#monocap

Правда непонятно как он в 128 бит упихал две границы по 64 бита, 16 бит флагов, да ещё и массив (!) где байт типа на каждые 16 байт выделенной памяти.

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

Насколько я понял, вся это инфа в лежит в другом месте в специальном объекте. А в 128-бит указателе есть ссылка на этот объект.

Logopeft ★★
()

В целом выглядит как костыль для профайлинга. Использовать распухшие в памяти и тормознутые программы ради «безопасности» - сомнительное удовольствие.

Logopeft ★★
()

На текущем этапе развития, собираемые в Fil-C программы медленнее примерно в 1.5-5 раз, по сравнению со сборкой обычными компиляторами.

LLVM

Если для чего-то критически важного, но на инспекцию кода нет времени и тупо пресобрать, то ладно. Для всего остального, фигня какая-то. Но сама суть с 128битным указателем хорошая Привет Эльбрус хехе. Это прям родной по идее способ проверок памяти. Но лучше бы это работало аппаратно, ну как минимум для полноценных ЭВМ, ПК,сервера,рабочие станции.

Пока GCC нет равных.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от hobbit

Только вот валгринд работает на 1-2 порядка медленнее.

Скорее уже такая дебажная сборка, непонятно как с оптимизацией.

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)

Цель разработки компилятора – полная совместимость с синтаксисом языков Си и С++

Защита обеспечивается благодаря применению 128-битных указателей

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

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

Интересно, доживем ли мы до версии плюсов которая будет иметь обратную совместимость и при этом на уровне ЯП будет исключать утечки? Шоб не прыгать со всем этим зоопарком умных указателей и вообще об этом не думать;-)

AntonI ★★★★★
()

гарантирующий

Компилятор со встроенным страховым полисом? :)

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

Лучше не доживать. Оставьте плюсы как есть! Пишите уже на Русте, Гошечке, Черте лысом... А то удумают писать на этих исправленных Сях интерфейс с ядром бинарными структурами, где явно есть заклад на то, что sizeof(off_t) == sizeof(ptrdiff_t) == sizeof(void*)

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

Ну перепишите ядро линукса. getpage() возвращает long int :)

Как раз в юзерспейсе и ядре иметь общий хидер с общими типами данных удобно. Не придумывать же очередной протобуф

gns ★★★★★
()

Филипу Пизло удалось сделать казалось бы невозможное - научить Си тормозить, поломать ABI и впихнуть-таки GC. Такой Пизло

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

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

Нет, причём в оригинальной документации описано почему так. Уж лучше бы прямую ссылку на неё добавили вместо опеннета.

zabbal ★★★★★
()

Ох, не доверяю я в наши дни подобным бравурным заявлениям и глобальным планам.

...при обеспечении полной безопасности работы с памятью...

Дохлый вариант же.

sparkie ★★★★★
()

Пригодится. Ведь есть же address sanitizer и под ним работает медленно но безопасно. Может это эксплуатирует похожие идеи но быстрее и оптимальнее

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от Logopeft

Это если нет поддержки со стороны процессора. А если есть, как в эльбрусе, то вполне неплохо.

Aceler ★★★★★
()

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

А как такое можно сделать без остановки? Почему те же явы и питоны «останавливают мир» когда надо мусор собрать? Как можно перемещать объекты параллельно и при этом быть уверенным что в любой момент времени код будет смотреть в нужные адреса?

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

Ну так Epic Games же! Эпик, такой Эпик :)

и это тоже..как говорят вишенька от яблоньки :-) Джек-пот, двойной вин, win-win, Филип Пизло is Эпик..эпичный

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

Т.е. КАЖДОЕ обращение к памяти как вызов виртуального метода (со всей сопутствующей индирекцией)? А с софтом посложнее тоже только в 1.2 раза просадка?

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

Для критически вжаного кода может иметь смысл. Или ля систем повышенной защиты.

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

Microsoft такой уже сделала %) Но указатели с GC имеют отдельный синтаксис, то есть старый код автоматически не получит GC. Но к новому можно прикрутить, и старый код должен компилироваться и подключаться к новому.

https://learn.microsoft.com/ru-ru/cpp/extensions/handle-to-object-operator-ha...

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

Fil-C uses a pointer representation that is a 16-byte atomic tuple of filc_object* and void*. The raw pointer component can point anywhere as a result of pointer arithmetic. The object component points to the base of a GC-allocated monotonic capability object (hence the MonoCap name).

ну вот filc_object* на это все и указывает.

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

И сберовский кэшбокс надо переписать, там возвращается int как HANDLE (void *)

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

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

А как такое можно сделать без остановки? Почему те же явы и питоны «останавливают мир» когда надо мусор собрать? Как можно перемещать объекты параллельно и при этом быть уверенным что в любой момент времени код будет смотреть в нужные адреса?

Во-первых ява не останавливает мир уже давно.

Во-вторых из текста новости не заявлено, что этот GC перемещает объекты.

В-третьих в корректной программе он вообще ничего не будет делать. Если он что-то делает, значит в программе баг. И уж лучше хоть как-то освободить утекшую память.

vbr ★★★★
()

Я, кстати, думал над этим вопросом, мне такая идея в голову приходила. Это, конечно, не safe, но может быть полезно. malloc всякий раз возвращает адрес, сильно отличающийся от других. 64 бита в принципе позволяют. При освобождении памяти адрес освобождается. Т.е. use after free ловится стандартными средствами ОС. Также адресной арифметикой случайно точно не забредёшь нетуда. И при этом вроде как особых тормозов не должно быть. По сути только меняется реализация malloc, он грубо говоря возвращает результат sbrk или как там его.

Только со стеком в данной схеме ничего не защищается.

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

Он мало того, что эпик, он ещё и анбеливэбл! Скромняга:)

Fil’s Unbelievable Garbage Collector

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

Судя по тому что там написано, это подсчет ссылок в compile-time, а не GC в run-time. МС изобрела умный указатель.

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

С аллокаторами проблемы могут быть и дроблением памяти. Типа если в цикле повыделять пару миллионов чанков на 16 байт, то память быстро кончится.

gns ★★★★★
()

Я не знаю ничего про С и С++, но, судя по обсуждениям на легендарном ЛОРе, это звучит как раст здорового человека.

vitruss ★★★★★
()

Если защита отслеживает ошибку, программа аварийно завершается, что позволяет не эксплуатировать уязвимость.

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

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

К сожалению, нет. Они поломали ABI. Rust линкует стандартные C-библиотеки, а эта штука видится как вещь в себе.

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

Зависит от компилятора, там несколько глав есть, COM это подсчет ссылок, CLR это уже GC.

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

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

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

__get_free_page, простите. Я уж в своих макросах запутался

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

Все, что доставляет удовольствие или незаконно, или аморально, или ведет к ожирению. :)

При static_assert(sizeof(void*) == sizeof(unsigned long)) вполне можно.

gns ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.