TRACTOR BACKGROUND AND OBJECTIVESBuffer overflow vulnerabilities and other related “memory safety” software flaws allow an attacker toinject messages that hijack control of a computer. These vulnerabilities are only possible becauseprograms written in C and C++ don’t force their developers to check conditions, such as array bounds orpointer arithmetic, for correctness. Google and Microsoft have estimated that 70% of their securityvulnerabilities stem from these and other related memory safety issues. While there are a variety ofapproaches to mitigate these risks, newer languages, like Rust, can completely eliminate them whilepreserving efficiency. Unfortunately, significant and expensive manual effort is required to rewrite legacycode into idiomatic Rust.After at least two decades of experience applying sophisticated tools towards mitigating memory safetyissues in C and C++, the software engineering community has largely concluded that bug finding toolsDARPA-SN-24-89are not sufficient. Rather, the consensus is that it is preferable to use “safe” programming languages thatreject unsafe programs at compile time.The TRACTOR program aims to achieve a high degree of automation towards translating legacy C toRust, with the same quality and style that a skilled Rust developer would employ, thereby permanentlyeliminating the entire class of memory safety security vulnerabilities present in C programs. Performersmight employ novel combinations of software analysis (e.g., static analysis and dynamic analysis), andmachine learning techniques (e.g., large language models).A draft solicitation for TRACTOR will be posted at sam.gov after release of this special notice and willbe linked from https://www.darpa.mil/program/translating-all-c-to-rust.
ТРАКТОР: ФОН І ЦІЛІВразливості переповнення буфера та інші пов'язані з "безпекою пам'яті" програмні помилки дозволяють атакувачу впроваджувати повідомлення, які захоплюють контроль над комп'ютером. Ці вразливості можливі тільки тому, що програми, написані на C та C++, не змушують своїх розробників перевіряти умови, такі як межі масиву або арифметичні операції над вказівниками, на коректність. Google і Microsoft оцінили, що 70% їхніх проблем з безпекою походять від цих і інших пов'язаних з безпекою пам'яті питань. Хоча існують різноманітні підходи для мінімізації цих ризиків, нові мови програмування, такі як Rust, можуть повністю виключити їх, зберігаючи ефективність. На жаль, для переписання легасі-коду в ідіоматичний Rust необхідно значні і дорогі ручні втручання.Після принаймні двох десятиліть досвіду застосування складних інструментів для мінімізації проблем з безпекою пам'яті в C та C++, спільнота інженерів програмного забезпечення в цілому прийшла до висновку, що інструменти знаходження помилок недостатні. Натомість консенсус полягає в тому, що краще використовувати "безпечні" мови програмування, які відхиляють небезпечні програми під час компіляції.Програма TRACTOR має на меті досягти високого ступеня автоматизації перекладу легасі-коду C на Rust з такою ж якістю та стилем, що і досвідчений розробник Rust, таким чином назавжди виключивши всі класи безпеки програмних вразливостей, присутніх у програмах C. Виконавці можуть застосовувати нові комбінації аналізу програмного забезпечення (наприклад, статичний та динамічний аналіз) і технік машинного навчання (наприклад, великих мовних моделей).Чернетка звернення для TRACTOR буде опублікована на сайті sam.gov після виходу цього спеціального повідомлення і буде посилатися на https://www.darpa.mil/program/translating-all-c-to-rust.
don’t force their developers to check conditions, such as array bounds or pointer arithmetic, for correctness.
А якщо Rust, то вразливеостей не стане?
> а суттєва частина кодується з unsafe rust заради достатнього рівня швидкодіїUnsafe rust зменшує швидкість коду до швидкості Сі, через те що компілятор не може застосувати частину оптимізацій, а не збільшує.
Небезпечний код використовують тоді, коли можливості мови не дозволяють реалізувати задумане безпечними методами.
Також unsafe часто потрібен при роботі з бібліотеками на Сі/Сі++, ядром, апаратурою, пам'яттю, чи додатковими можливостями процесора, про які компілятор нічого не знає і не може допомогти переконатися у їхній коректності. Це малий відсоток від всього коду на Rust. За статистикою, 80% бібліотек взагалі не мають небезпечного коду.
не зовсім точно, або зовсім не точно: unsafe rust більш швидкий відносно safe rust переважно за рахунок відсутності runtime checks (ще трохи швидкості додає додаткова можлива оптимізація відповідного коду компілятором, але це тільки додатковий бонус). З unsafe rust код може досягати швидкодії C кода.
$ hyperfine './fib_gcc 100000000' './fibclang 100000000' 'target/release/fibvec_iterator_cell 100000000' 'target/release/fibvec_naive_indexing 100000000'Benchmark 1: ./fib_gcc 100000000 Time (mean ± σ): 278.3 ms ± 3.2 ms [User: 49.4 ms, System: 227.9 ms] Range (min … max): 273.5 ms … 283.7 ms 10 runs Benchmark 2: ./fibclang 100000000 Time (mean ± σ): 307.3 ms ± 4.1 ms [User: 78.6 ms, System: 227.5 ms] Range (min … max): 301.8 ms … 314.3 ms 10 runs Benchmark 3: target/release/fibvec_iterator_cell 100000000 Time (mean ± σ): 278.1 ms ± 5.4 ms [User: 46.2 ms, System: 230.7 ms] Range (min … max): 274.0 ms … 289.4 ms 10 runs Benchmark 4: target/release/fibvec_naive_indexing 100000000 Time (mean ± σ): 307.7 ms ± 2.3 ms [User: 78.0 ms, System: 228.4 ms] Range (min … max): 304.2 ms … 312.0 ms 10 runs Summary target/release/fibvec_iterator_cell 100000000 ran 1.00 ± 0.02 times faster than ./fib_gcc 100000000 1.11 ± 0.03 times faster than ./fibclang 100000000 1.11 ± 0.02 times faster than target/release/fibvec_naive_indexing 100000000
Цитата Небезпечний код використовують тоді, коли можливості мови не дозволяють реалізувати задумане безпечними методами.теж ні - переважно для швидкодії
(приклад - більшість з тих що часто юзаються rust crates, і спроби використання rust коду в модулях ядрах які виливаються в дискусії щодо необхідності стандарту на unsafe rust). Використання же unsafe в юзер код більш різноманітні.
- "Це малий відсоток від всього коду на Rust. За статистикою, 80% бібліотек взагалі не мають небезпечного коду".-- За сухою стат. самої Rust foundation щодо crates - там близько 20%... процентів unsafe (40 через кросзалежності).
Якщо взяти те що використовується часто і те що ні (cтд 20/80) - то процент буде значно біільш ніж 40%.Потім - якщо враховувати що зазвичай використовуються більш ніж один crate, то вірогідність що rust софт unsafe (transitive safety) ще значно більша навіть якщо там немає жодної unsafe конструкції.
-- і це тільки один з аспектів безпечного коду - memory safety, тут значно більше пунктів ніж memory (про які забувають говорячи про код в rust)
Цитата: yvs115 від 2024-08-05 13:10:45 не зовсім точно, або зовсім не точно: unsafe rust більш швидкий відносно safe rust переважно за рахунок відсутності runtime checks (ще трохи швидкості додає додаткова можлива оптимізація відповідного коду компілятором, але це тільки додатковий бонус). З unsafe rust код може досягати швидкодії C кода.Сі:Код: [Вибрати]iuint64_t* fib = (uint64_t*)malloc(sizeof(uint64_t)*length);...for(int i=2; i<length; i++) { fib[i] = fib[i-1] + fib[i-2];}Наївний переклад з Сі на Раст:Код: [Вибрати]let mut fib = vec![0; length];...for i in 2..length { fib[i] = fib[i-1] + fib[i-2];}Ідіоматичний Rust:Код: [Вибрати]let mut fib = vec![0; length];...for window in Cell::from_mut(&mut fib[..]).as_slice_of_cells().windows(3) { window[2].set(window[1].get() + window[0].get());}Компілював з -O3.Код: [Вибрати]$ hyperfine './fib_gcc 100000000' './fibclang 100000000' 'target/release/fibvec_iterator_cell 100000000' 'target/release/fibvec_naive_indexing 100000000'Benchmark 1: ./fib_gcc 100000000 Time (mean ± σ): 278.3 ms ± 3.2 ms [User: 49.4 ms, System: 227.9 ms] Range (min … max): 273.5 ms … 283.7 ms 10 runs Benchmark 2: ./fibclang 100000000 Time (mean ± σ): 307.3 ms ± 4.1 ms [User: 78.6 ms, System: 227.5 ms] Range (min … max): 301.8 ms … 314.3 ms 10 runs Benchmark 3: target/release/fibvec_iterator_cell 100000000 Time (mean ± σ): 278.1 ms ± 5.4 ms [User: 46.2 ms, System: 230.7 ms] Range (min … max): 274.0 ms … 289.4 ms 10 runs Benchmark 4: target/release/fibvec_naive_indexing 100000000 Time (mean ± σ): 307.7 ms ± 2.3 ms [User: 78.0 ms, System: 228.4 ms] Range (min … max): 304.2 ms … 312.0 ms 10 runs Summary target/release/fibvec_iterator_cell 100000000 ran 1.00 ± 0.02 times faster than ./fib_gcc 100000000 1.11 ± 0.03 times faster than ./fibclang 100000000 1.11 ± 0.02 times faster than target/release/fibvec_naive_indexing 100000000Висновок: ідіоматичний і безпечний Rust (llvm) на 11% швидший ніж ідіоматичний Сі (clang), і має таку ж швидкість як Сі (gcc). Наївний але безпечний Rust (llvm) має таку ж швидкість як Сі (clang).
iuint64_t* fib = (uint64_t*)malloc(sizeof(uint64_t)*length);...for(int i=2; i<length; i++) { fib[i] = fib[i-1] + fib[i-2];}
let mut fib = vec![0; length];...for i in 2..length { fib[i] = fib[i-1] + fib[i-2];}
let mut fib = vec![0; length];...for window in Cell::from_mut(&mut fib[..]).as_slice_of_cells().windows(3) { window[2].set(window[1].get() + window[0].get());}
% ./fib_gcc 1034% MALLOC_PERTURB_=13 ./fib_gcc 1017144620962624171516
% ./fib_gcc $((1000 * 1000 * 1000))13425198974673467106% ./fib_rs_naive $((1000 * 1000 * 1000))Some(13425198974673467106)% ./fib_gcc $((1000 * 1000 * 1000 * 10))6733232933538918685% ./fib_rs_naive $((1000 * 1000 * 1000 * 10))memory allocation of 80000000000 bytes failedIOT instruction (core dumped) ./fib_rs_naive $((1000 * 1000 * 1000 * 10))
% gcc -O3 -o fib_gcc fib_c.c% clang -O3 -o fib_clang fib_c.c% rustc -C opt-level=3 -o fib_rs_naive fib_rs_naive.rs% rustc -C opt-level=3 -o fib_rs_index fib_rs_index.rs% ls -l.rw-rw-r-- 530 yvs 6 сер 07:51 fib_c.c.rwxrwxr-x 16k yvs 6 сер 08:08 fib_clang.rwxrwxr-x 16k yvs 6 сер 08:08 fib_gcc.rwxrwxr-x 13M yvs 6 сер 08:09 fib_rs_index.rw-rw-r-- 602 yvs 6 сер 07:52 fib_rs_index.rs.rwxrwxr-x 13M yvs 6 сер 08:09 fib_rs_naive.rw-rw-r-- 492 yvs 6 сер 07:52 fib_rs_naive.rs% N=$((10 * 1000 * 1000))% multitime -n 10 ./fib_gcc $N >/dev/null===> multitime results1: ./fib_gcc 10000000 Mean Std.Dev. Min Median Maxreal 0.047 0.002 0.043 0.047 0.050 user 0.008 0.002 0.003 0.008 0.012 sys 0.039 0.003 0.034 0.039 0.043 % multitime -n 10 ./fib_clang $N >/dev/null===> multitime results1: ./fib_clang 10000000 Mean Std.Dev. Min Median Maxreal 0.053 0.003 0.047 0.053 0.057 user 0.012 0.003 0.008 0.012 0.018 sys 0.041 0.004 0.034 0.041 0.045 % multitime -n 10 ./fib_rs_naive $N >/dev/null===> multitime results1: ./fib_rs_naive 10000000 Mean Std.Dev. Min Median Maxreal 0.052 0.002 0.048 0.052 0.054 user 0.014 0.003 0.007 0.014 0.018 sys 0.038 0.003 0.035 0.036 0.043 % multitime -n 10 ./fib_rs_index $N >/dev/null===> multitime results1: ./fib_rs_index 10000000 Mean Std.Dev. Min Median Maxreal 0.048 0.001 0.046 0.048 0.050 user 0.009 0.003 0.005 0.009 0.013 sys 0.039 0.003 0.033 0.038 0.043
% multitime -n 100 ./fib_rs_index 1000 >/dev/null===> multitime results1: ./fib_rs_index 1000 Mean Std.Dev. Min Median Maxreal 0.002 0.000 0.001 0.002 0.002 user 0.000 0.001 0.000 0.000 0.002 sys 0.001 0.001 0.000 0.001 0.002 % multitime -n 100 ./fib_gcc 1000 >/dev/null===> multitime results1: ./fib_gcc 1000 Mean Std.Dev. Min Median Maxreal 0.001 0.000 0.001 0.001 0.002 user 0.000 0.000 0.000 0.000 0.001 sys 0.001 0.000 0.000 0.001 0.002
ЦитатаЦитата Небезпечний код використовують тоді, коли можливості мови не дозволяють реалізувати задумане безпечними методами.теж ні - переважно для швидкодіїРезультати тестів покажете чи повірити вам на слово?
Цитата (приклад - більшість з тих що часто юзаються rust crates, і спроби використання rust коду в модулях ядрах які виливаються в дискусії щодо необхідності стандарту на unsafe rust). Використання же unsafe в юзер код більш різноманітні.Раст в ядрі хочуть використовувати якраз тому, що він дає додаткові гарантії безпеки.
Цитата- "Це малий відсоток від всього коду на Rust. За статистикою, 80% бібліотек взагалі не мають небезпечного коду".-- За сухою стат. самої Rust foundation щодо crates - там близько 20%... процентів unsafe (40 через кросзалежності). 20% бібліотек мають unsafe, 100%-20% = 80% не мають.
ЦитатаЯкщо взяти те що використовується часто і те що ні (cтд 20/80) - то процент буде значно біільш ніж 40%.Потім - якщо враховувати що зазвичай використовуються більш ніж один crate, то вірогідність що rust софт unsafe (transitive safety) ще значно більша навіть якщо там немає жодної unsafe конструкції.Ви про те, що якщо взяти будь яку програму на Раст, то там є небезпечний код в скомпільованому файлі? Це 100%.
Цитата-- і це тільки один з аспектів безпечного коду - memory safety, тут значно більше пунктів ніж memory (про які забувають говорячи про код в rust)Помилки при роботі з пам'яттю зараз складають приблизно 60% усіх вразливостей. Rust дозволяє позбутися від значної кількості цих помилок, тобто скоротити кількість всіх вразливостей на половину.
Ніхто не забуває про логічні помилки, арифметичні переповнення, або некоректне використання коду. В Rust це називається unsoundness (слабкість?).
$ hyperfine './fib_gcc 100000000' 'target/release/fibvec_naive_indexing 100000000' 'target/release/fibvec_unsafe_indexing 100000000'Benchmark 1: ./fib_gcc 100000000 Time (mean ± σ): 284.7 ms ± 3.7 ms [User: 47.8 ms, System: 235.9 ms] Range (min … max): 279.6 ms … 290.8 ms 10 runs Benchmark 2: target/release/fibvec_naive_indexing 100000000 Time (mean ± σ): 284.5 ms ± 2.6 ms [User: 47.4 ms, System: 236.1 ms] Range (min … max): 279.2 ms … 287.9 ms 10 runs Benchmark 3: target/release/fibvec_unsafe_indexing 100000000 Time (mean ± σ): 313.2 ms ± 2.8 ms [User: 76.2 ms, System: 235.9 ms] Range (min … max): 308.9 ms … 317.4 ms 10 runs Summary target/release/fibvec_naive_indexing 100000000 ran 1.00 ± 0.02 times faster than ./fib_gcc 100000000 1.10 ± 0.01 times faster than target/release/fibvec_unsafe_indexing 100000000
вже бачу що заюзан unsafe cell для швидкодії щоб зрівнятись з cі -ви ж розумієте що "Cell has the same memory layout and caveats as UnsafeCell"?
Цитатавже бачу що заюзан unsafe cell для швидкодії щоб зрівнятись з cі -ви ж розумієте що "Cell has the same memory layout and caveats as UnsafeCell"?Я чітко вказую компілятору, що я збираюся міняти значення елементів масиву незалежно один від одного, і він підтверджує що у даному випадку це безпечно. Cell ніяк не впливає на перевірки доступу до елементів масиву — я всеодно отримую зріз масиву і ітерую по ньому. Компілятор прибирає перевірки через те, що використовується ітератор, щодо якого компілятор впевнений що він не вийде за межі масиву, вікно на 3 елементи, і статичні індекси у вікні, які перевіряються статично на етапі компіляції.
for window in Cell::from_mut(&mut fib[..]).as_slice_of_cells().windows(3) { window[2].set(window[1].get() + window[0].get()); }
для чого використано unsafe в назві й відключаються деякі перевірки? (роблячи то потенціально unsafe як і зазначено в його назві - якщо розуміти unsafe як unsafe, а safe як safe)
відносно алокатора і функцій з ним роботи: де подивитись відносно алокатора в Rust, коли це heap allocation, stack allocation, initialiaziation? (нп щоб розуміти де яка швидкодія буде)
круто a+b виглядає з масивами, навіть не хочу уявляти як то буде виглядати якщо більш складна аріфметика буде необхідна
Я раджу запитатися у ШІ (напр. Gemini), якщо щось не зрозуміло. Він досить добре розжовує.