LINUX.ORG.RU

Fil-C 0.682 — memory safety без переписывания

 , , , ,


1

2

Состоялся выпуск Fil-C 0.682 — компилятора C и C++, обеспечивающего полную безопасность работы с памятью (memory safety) и дающего гарантии бОльшие, чем многие другие языки, такие как, например, Rust. Проект разрабатывается Филипом Пизло (Filip Pizlo), который в представлениях не нуждается.

Fil-C основан на кодовой базе Clang/LLVM 20.x и позволяет компилировать традиционный код на C/C++ с гарантией предотвращения всех основных уязвимостей (out-of-bounds access, use-after-free, double free, type confusion). В отличие от ASan или MTE, Fil-C использует строго безопасную объектную модель и принципиально не содержит лазеек вроде блоков unsafe.

За прошедший год проект прошёл путь от концептуального доказательства возможностей до полноценного инструментария с масштабной экосистемой.

Основные особенности и технические детали:

  • InvisiCaps 2.0 и развитие модели Capability: Существенно переработана система полномочий (capabilities), отслеживающих границы и типы указателей без изменения их 64-битного размера в адресном пространстве C. Оптимизировано хранение capability, снижены накладные расходы, а также добавлена корректная поддержка union, memcpy, атомарных операций со структурами и передачи мандатов через инлайн-ассемблер.
  • Параллельный сборщик мусора (FUGC): В рантайм-сборщик мусора Fil’s Unbelievable Garbage Collector добавлены параллельная сборка, поддержка сложных объектов вроде замыканий и GNU Indirect Function.
  • Поддержка ARM64: Практически с нуля реализован бэкенд, рантайм, загрузчик и ABI для архитектуры ARM64 (Linux/aarch64), проект перешел в фазу бета-тестирования на этой платформе.
  • Безопасный инлайн-ассемблер и SIMD: Добавлена уникальная возможность выполнения безопасных ассемблерных вставок (включая ассемблерные блоки OpenSSL) с сохранением проверки полномочий. Реализована полная поддержка векторных инструкций SSE, AVX, AVX2 и AVX512 (включая masked load/store, expand/compress, sfence и prefetch).
  • Escape Analysis: Начиная с версии 0.671 внедрен статический анализ утечек памяти из областей стека. Это стало самым крупным оптимизационным изменением за год: скорость выполнения QuickJS выросла более чем в 6 раз, а большинства остальных программ — более чем на 10%.
  • Совместимость с C++ и современными стандартами: Реализована поддержка исключений C++, принудительного развертывания стека, ucontext, вычисляемых переходов, std::optional и указателей на члены классов.
  • Защита от опасных UB-оптимизаций LLVM: Fil-C фактически отключил агрессивные оптимизации LLVM, полагающиеся на Undefined Behavior (UB). В частности, принудительно отключен strict aliasing и включен аналог -fwrapv, что предотвращает некорректное удаление проверок безопасности компилятором.
  • Переход на LLVM/Clang 20: Компилятор переведен на кодовую базу Clang 20 (c версии Fil-C 0.670), что обеспечило лучшую совместимость и переносимость кодогенерации.
  • Расширение Linux ABI и FFI нового поколения: Реализована эмуляция и безопасные обертки для десятков системных вызовов Linux (statx, openat2, pidfd, epoll, splice, futex, timer API и др.), а также поддержка dlopen, dlvsym, libffi и FFI-слоя для взаимодействия с внешним кодом.
  • Новая конвенция вызовов и API рантайма: Оптимизирован внутренний ABI вызова функций для снижения оверхеда. Добавлены новые API, включая zlock_runtime_threads() (фиксация потоков для построения строгих песочниц), а также встроенный sampling profiler и инструменты дампов памяти.
  • Полноценный userspace-дистрибутив /opt/fil: безопасное системное окружение на базе glibc 2.40, включающее OpenSSH, OpenSSL, sudo, git, curl, wget, rsync, tmux, make, grep, а также системные библиотеки (PAM, Kerberos, SELinux, ICU).

Готовые бинарные сборки распространяются в двух вариантах: автономном на базе musl (filc) и полном системном окружении /opt/fil для архитектур x86_64 и ARM64.

GitHub проекта

Также отметим, что имеется и безопасный по памяти дистрибутив Linux — Pizlix

>>> Сайт проекта

★★★★

Проверено: hobbit ()
Последнее исправление: hobbit (всего исправлений: 2)
Ответ на: комментарий от ya-betmen

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

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

А как тогда работает

и дающего гарантии бОльшие, чем многие другие языки, такие как, например, Rust

Сек, а чем оно тогда отличается от запуска с санитайзером? Тут его типа внутрь вкомпиливают сразу?

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

Сек, а чем оно тогда отличается от запуска с санитайзером? Тут его типа внутрь вкомпиливают сразу?

Да. Но Fil-C в отличие от санитайзера чуть более ориентирован на быстрое выполнение. И в отличие от санитайзера нормально отслеживает UB типа int x = 1, y = 2, z = 3; int* p = &y; p[1] = 5;.

monk ★★★★★
()
Ответ на: комментарий от X-Pilot

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

Fil-C only works on Linux/X86_64 or Linux/ARM64 with 4K page size.

Previous versions worked on Darwin/ARM64 and FreeBSD, but now I’m focusing just on Linux because it allows me to do a more faithful job of implementing libc. There’s nothing fundamentally stopping Fil-C from working on other architectures or OSes other than Linux.

GC используется не для управления памятью, а потому что инженерно прост и позволяет дать гарантии. Тут стоит ещё подумать-померять, что может меньшее вляние на производительность оказать.

BruteForce ★★★★
() автор топика
Ответ на: комментарий от pftBest
  1. Не 4х. Для каждого конкретного случая надо идти и мерить. Например:
~ ❯❯❯ taskset -c 31 hyperfine --warmup 10 \
            'openssl speed -seconds 1 -evp sha256' \
            '/opt/fil/bin/openssl speed -seconds 1 -evp sha256'
Benchmark 1: openssl speed -seconds 1 -evp sha256
  Time (mean ± σ):      6.005 s ±  0.000 s    [User: 6.001 s, System: 0.001 s]
  Range (min … max):    6.004 s …  6.005 s    10 runs
 
Benchmark 2: /opt/fil/bin/openssl speed -seconds 1 -evp sha256
  Time (mean ± σ):      6.023 s ±  0.001 s    [User: 5.929 s, System: 0.091 s]
  Range (min … max):    6.022 s …  6.024 s    10 runs
 
Summary
  openssl speed -seconds 1 -evp sha256 ran
    1.00 ± 0.00 times faster than /opt/fil/bin/openssl speed -seconds 1 -evp sha256
~ ❯❯❯ taskset -c 31 hyperfine --warmup 10 \
            'curl http://0.0.0.0:8123/tmp-e04.xpi > /dev/null' \
            '/opt/fil/bin/curl http://0.0.0.0:8123/tmp-e04.xpi > /dev/null'
Benchmark 1: curl http://0.0.0.0:8123/tmp-e04.xpi > /dev/null
  Time (mean ± σ):       5.7 ms ±   0.1 ms    [User: 2.2 ms, System: 2.5 ms]
  Range (min … max):     4.8 ms …   6.1 ms    480 runs
 
  Warning: Command took less than 5 ms to complete. Note that the results might be inaccurate because hyperfine can not calibrate the shell startup time much more precise than this limit. You can try to use the `-N`/`--shell=none` option to disable the shell completely.
 
Benchmark 2: /opt/fil/bin/curl http://0.0.0.0:8123/tmp-e04.xpi > /dev/null
  Time (mean ± σ):      18.0 ms ±   0.2 ms    [User: 7.2 ms, System: 10.0 ms]
  Range (min … max):    17.4 ms …  18.8 ms    163 runs
 
Summary
  curl http://0.0.0.0:8123/tmp-e04.xpi > /dev/null ran
    3.18 ± 0.09 times faster than /opt/fil/bin/curl http://0.0.0.0:8123/tmp-e04.xpi > /dev/null

@hobbit А можно добавить в новость, что имеются задачи, для которых влияние на производительность не более 0.05%? (я доказал только что)

  1. В одном интервью Ф. Пизло говорит что у него много идей где и как улучшить производительность, но очень ограничен во времени и ищет свободные руки.
BruteForce ★★★★
() автор топика
Ответ на: комментарий от yvv1

Давно у тебя криптография уже таким образом написана?

BruteForce ★★★★
() автор топика
Ответ на: комментарий от ya-betmen

то он не должен компилится

Но он компилится( И вот в случае, если у тебя в коде, который компилится и нужен в ответственном месте, где лучше упасть чем дать доступ злоумышленнику — есть Fil-C.

Так если ты уже забил на варнинги, чем поможет ещё один?

Если мы всерьёз говорим о девелопменте, то это для непробиваемых — приложение будет падать.

 ❯❯❯ cat df.c
#include <stdio.h>
#include <stdlib.h>

void mf(void *ptr) { free(ptr); }

int main() {
  int *a = malloc(4);
  mf(a);
  printf("Hello from Fil-C!\n");
  free(a);
  return 0;
}
 ❯❯❯ /opt/fil/bin/filcc -O2 -g df.c
 ❯❯❯ ./a.out
Hello from Fil-C!
filc safety error: cannot free already free object 0x772c273058f0,0x772c273058f0,free.
    (a.out) df.c:9:3: main
    (libc.so.6666) ../sysdeps/nptl/libc_start_call_main.h:58:16: __libc_start_call_main
    (libc.so.6666) ../csu/libc-start.c:161:3: __libc_start_main
    (libpizlo.so) <runtime>: start_program
[2081759] filc panic: thwarted a futile attempt to violate memory safety.
fish: Job 1, './a.out' terminated by signal SIGTRAP (Trace or breakpoint trap)
BruteForce ★★★★
() автор топика
Последнее исправление: BruteForce (всего исправлений: 1)
Ответ на: комментарий от Atlant

Это как раз для использования в продакшене, в первую очередь, ИМХО.

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

Fil-C при компиляции выдаст

Смотря с какими флагами. Флаги анализаторов из шланга доступны))

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

бОльшие гарантии заключаются в том, что понятия unsafe, например, нет вообще и безопасными по памяти становятся также и вызовы функций из библиотек, для этого введён свой ABI вызовов функций. Если у тебя http сервер на русте или на Го, но дёргает для TLS какую-нибудь OpenSSL — ты зависишь от качеcтва кода в OpenSSL. При использовании Fil-C такой проблемы нет: OpenSSL также собирается Fil-C и «становится» безопасной по памяти.

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

Странно, всякой фигни к своим буквам он пририсовывает, будто поляк.

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

обнаружит ошибку на этапе компиляции

В ансейфе ее найдет васян на проде. Прямо на презентации инвесторам.

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

thwarted a futile attempt to violate memory safety

А он юморист )

GAMer ★★★★★
()
Ответ на: комментарий от ya-betmen

Тут его типа внутрь вкомпиливают сразу?

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

GAMer ★★★★★
()
Ответ на: комментарий от ya-betmen
~/s/filc ❯❯❯ cat df.c                                                                                                                                      ✘ 133
#include <stdio.h>

int main(void) {
    printf("Hello from Fil-C!\n");

    int a = 0;
    int b = 1;
    int *a_ptr = &a;
    int *b_ptr = a_ptr + (&b - &a);

    *b_ptr = 161;

    printf("%d\n", b);
    return 0;
}
~/s/filc ❯❯❯ clang -Werror -fsanitize=address df.c
~/s/filc ❯❯❯ ./a.out
Hello from Fil-C!
161
~/s/filc ❯❯❯ /opt/fil/bin/filcc -Werror -g df.c
~/s/filc ❯❯❯ ./a.out
Hello from Fil-C!
filc safety error: cannot write pointer with ptr >= upper.
    pointer: 0x7dfa1bd05970,0x7dfa1bd05950,0x7dfa1bd05960
    expected 4 writable bytes.
semantic origin:
    (a.out) df.c:11:12: main
check scheduled at:
    (a.out) df.c:11:12: main
    (libc.so.6666) ../sysdeps/nptl/libc_start_call_main.h:58:16: __libc_start_call_main
    (libc.so.6666) ../csu/libc-start.c:161:3: __libc_start_main
    (libpizlo.so) <runtime>: start_program
[2087802] filc panic: thwarted a futile attempt to violate memory safety.
fish: Job 1, './a.out' terminated by signal SIGTRAP (Trace or breakpoint trap)

Out Of Bounds But In Bounds

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

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

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

BruteForce ★★★★
() автор топика

ну вы поняли да, поняли?
filthy

Bad_ptr ★★★★★
()

Дистрибутив optfil (200-че-то-там-мегабайт) даёт такое:

================================================================================
                       Fil-C 0.682 /opt/fil Distribution
================================================================================

This distribution includes the Fil-C compiler (filcc/fil++) and runtime and
these memory safe programs and libraries compiled with Fil-C:

    acl       attr      bash     binutils bzip2  coreutils curl     diff    
    find      flex      gawk     git      glibc  grep      gzip     icu4c   
    keyutils  krb5      less     libaudit libc++ libedit   libevent libidn2 
    libpsl    libtasn1  libuv    lz4      m4     make      mg       nghttp2 
    openssh   openssl   p11-kit  pam      patch  patchelf  pcre2    pkgconf 
    procps-ng psmisc    readline rsync    sed    selinux   sudo     tar     
    tmux      unistring wget     xxhash   xz     zlib      zstd   

а также с хедерами и пред-собранными либами.

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

Было бы интересно посмотреть не инстринсики и IO, а какую-нибудь тяжёлую шаблонную магию, помогают ли абстракции избежать лишних проверок?

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

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

ya-betmen ★★★★★
()
Ответ на: комментарий от BruteForce

При использовании Fil-C такой проблемы нет: OpenSSL также собирается Fil-C

Так если в опенссл есть проблема она ж не соберется. Ты выше пример привел.

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

главное, что этот парень правду-матку рубит... :о)

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

В ансейфе

на проде

Как говорил незабвенный Sun-ch: "Вот для таких людей на гранатах пишут «в рот не класть»

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

в итоге Си выведут из эксплуатации

ну это вы загнули... :о)

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

А без ансейфа просадка производительности может быть даже сильнее, чем с Fil-C.

monk ★★★★★
()
Ответ на: комментарий от ya-betmen

Так если в опенссл есть проблема она ж не соберется.

Если ошибка провоцируется подобранными данными, то соберётся. На Fil-C при этих данных будет гарантированно завершать работу, при использовании из Rust портить память процесса и нарушать гарантии Rust’а.

monk ★★★★★
()

Состоялся выпуск Fil-C 0.682 — компилятора C и C++, обеспечивающего полную безопасность работы с памятью (memory safety) и дающего гарантии бОльшие, чем многие другие языки, такие как, например, Rust.

Так раст же дает гарантии на этапе компиляции, а fil-c роняет приложение. Т.е. это полезно там где важна безопасность, но не надежность.

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

А раст не падает что-ли? Ты пробовал за границы массива выходить, например? Раст точно также выпишет панику. А ещё НЕ выпишет в ансейф блоках и НЕ выпишит во всех сторонних либах.

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

Ты пробовал за границы массива выходить, например?

В расте вроде как есть метод .get() с широким контрактом, нет?

А ещё НЕ выпишет в ансейф блоках

На то он и unsafe

и НЕ выпишит во всех сторонних либах

Ну ок

Я-то вообще на расте не пишу, но мне интересна тема написания приложений которые не падают (а не просто безопасны по памяти), и по описанию все-таки раст тут все равно лучше чем связка C++ + fil-c.

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

Вот для таких людей на гранатах пишут «в рот не класть»

Вот о таких людях потом пишут «в рот мне ноги»! Поправил, не благодари.

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

Такое и gcc умеет

Получается, язык си позволяет некоторые ошибки работы с памятью отловить на этапе компеляции :)

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

Так раст же дает гарантии на этапе компиляции, а fil-c роняет приложение

нет. Все рекламируемые «гарантии» раста получаются из-за того что там тупо не реализована «небезопасная» функциональность. Типа вот этого «не более одной мутабельной ссылки в скоупе». А то что из-за этого приходится писать говнокод, растоманов не волнует.

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