惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
Lohrmann on Cybersecurity
Martin Fowler
Martin Fowler
Engineering at Meta
Engineering at Meta
腾讯CDC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Azure Blog
Microsoft Azure Blog
G
Google Developers Blog
TaoSecurity Blog
TaoSecurity Blog
博客园_首页
Vercel News
Vercel News
Hugging Face - Blog
Hugging Face - Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Last Week in AI
Last Week in AI
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
The Exploit Database - CXSecurity.com
量子位
Project Zero
Project Zero
A
Arctic Wolf
小众软件
小众软件
NISL@THU
NISL@THU
C
CERT Recently Published Vulnerability Notes
有赞技术团队
有赞技术团队
MongoDB | Blog
MongoDB | Blog
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News and Events Feed by Topic
宝玉的分享
宝玉的分享
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Troy Hunt's Blog
P
Privacy & Cybersecurity Law Blog
Security Latest
Security Latest
B
Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
D
DataBreaches.Net
Schneier on Security
Schneier on Security
The Hacker News
The Hacker News
K
Kaspersky official blog
C
Check Point Blog
Hacker News: Ask HN
Hacker News: Ask HN
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Webroot Blog
Webroot Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
人人都是产品经理
人人都是产品经理
AI
AI
Cisco Talos Blog
Cisco Talos Blog
MyScale Blog
MyScale Blog
Cloudbric
Cloudbric
B
Blog RSS Feed
S
Schneier on Security
P
Palo Alto Networks Blog

Henri Sivonen’s pages

Parin vuoden tutkimattomuus crates.io: Rust Package Registry Asiakirjatonta toimintaa It’s not wrong that "🤦🏼‍♂️".length == 7 Koulutartuntojen tilastointimenettely Perusteasiakirjoja hallussapitämättä ikärajoitettu Asiantuntijat ja nukkuva vallan vahtikoira Koronapassilausunto Suppealla tietopohjalla ohimeneväksi väitetty Text Encoding Menu in 2021 The Text Encoding Submenu Is Gone An HTML5 Conformance Checker Not Part of the Technology Stack Browser Technology Stack Bogo-XML Declaration Returns to Gecko A Look at Encoding Detection and Encoding Menu Telemetry from Firefox 86 Why Supporting Unlabeled UTF-8 in HTML on the Web Would Be Problematic Rust Target Names Aren’t Passed to LLVM Toimintamalli Activating Browser Modes with Doctype Johtopäätöksiä mallin rakenteesta Tehtävänmäärittelyä kirjoittamatta ja kuolemia laskematta laumasuojamallinnettu Character Encoding Menu in 2014 Erillissuosituksen tarpeettomuudesta yleissuosituksen poikkeukseksi? STM:n maskiaikajana Rust 2021 Oma-aloitteisesti mallinnettu Kokopinovaatimuksin kilpailutettu chardetng: A More Compact Character Encoding Detector for the Legacy Web Varauksia paisutellen tiedotettu Perusteasiakirjoitta tiedotettu Always Use UTF-8 & Always Label Your HTML Saying So IME Smoke Testing The Validator.nu HTML Parser About the Hiragino Fonts with CSS It’s Time to Stop Adding New Features for Non-Unicode Execution Encodings in C++ Rust 2020 The Last of the Parsing Quirks About about:blank Rust 2019 a Web-Compatible Character Encoding Library in Rust How I Wrote a Modern C++ Library in Rust A Rust Crate that Also Quacks Like a Modern C++ Library #Rust2018 No Namespaces in JSON, Please A Lecture about HTML5 Julkisesti luotettu varmenne ikidomainille TLS:ää (SSL:ää) varten -webkit-HTML5 Lists in Attribute Values The Sad Story of PNG Gamma “Correction” If You Want Software Freedom on Phones, You Should Work on Firefox OS, Custom Hardware and Web App Self-Hostablility HTML5 Parser Improvements ARIA in HTML5 Integration: Document Conformance (Draft, Take Two) Schema.org and Pre-Existing Communities Lowering memory requirements by replacing Schematron HTML5 Parsing in Gecko: A Build Introducing SAX Tree NVDL Support in Validator.nu HOWTO Avoid Being Called a Bozo When Producing XML An Unofficial Q&A about the Discontinuation of the XHTML2 WG Thoughts on HTML5 Becoming a W3C Recommendation Four Finnish Banks Training Users to Give Banking Credentials to Another Site Unimpressed by Leopard Sergeant Semantics The Content Sink Inheritance Diagram – 2006-06-30 What is EME? About Points and Pixels as Units The Performance Cost of the HTML Tree Builder Social Media Impression Management The spacer Element Is Gone Openmind 2006 Performance Mistake XHTML and Mobile Devices WebM-Enabled Browser Usage Share Exceeds H.264-Enabled Browser Usage Share on Desktop (in StatCounter Numbers) HTML5 Parser-Based View Source Syntax Highlighting Vendor Prefixes Are Hurting the Web Accept-Charset Is No More Dualroids Writing Structural Stylable Document in Mozilla Editor ISO-8859-15 on haitallinen Hourglass The Scientific Method According to Hixie Maemo Source Code Karpelan lukkovertaus ontuu Digitaalisesta arkistoinnista ARIA in HTML5 Integration: Document Conformance (Draft) XHTML—What’s the Point? (Draft, incomplete) Mac OS X Browser Comparison HOWTO Spot a Wannabe Web Standards Advocate An Idea About Intermediate Language Trees and Web UI Generation Thoughts on Using SSL/TLS Certificates as the Solution to Phishing Bureaucracy Meets the Web Europe Day HOWTO Establish a 100% Literacy Rate What to Do with All These Photos? Charmod Norm Checking Validator Web Service Interface Ideas DTDs Don’t Work on the Web EFFI’s Day in Court Speaking at XTech
Using cargo-fuzz to Transfer Code Review of Simple Safe Code to Complex Code that Uses unsafe
Henri Sivonen · 2018-12-03 · via Henri Sivonen’s pages

encoding_rs::mem is a Rust module for performing conversions between different in-RAM text representations that are relevant to Gecko. Specifically, it converts between potentially invalid UTF-16, Latin1 (in the sense that unsigned byte value equals the Unicode scalar value), potentially invalid UTF-8, and guaranteed-valid UTF-8, and provides some operations on buffers in these encodings, such as checking if a UTF-16 or UTF-8 buffer only has code points in the ASCII range or only has code points in the Latin1 range. (You can read more about encoding_rs::mem in a write-up about encoding_rs as a whole.)

The whole point of this module is to make things very fast using Rust’s (not-yet-stable) portable SIMD features. The code was written before slices in the standard library had the align_to method or the chunks_exact method. Moreover, to get speed competitive with the instruction set-specific and manually loop-unrolled C++ code that the Rust code replaced, some loop unrolling is necessary, but Rust does not yet support directives for the compiler that would allow the programmer to request specific loop unrolling from the compiler.

As a result, the code is a relatively unreviewable combination of manual alignment calculations, manual loop unrolling and manual raw pointer handling. This indeed achieves high speed, but by looking at the code, it isn’t at all clear whether the code is actually safe or otherwise correct.

To validate the correctness of the rather unreviewable code, I used model-based testing with cargo-fuzz. cargo-fuzz provides Rust integration for LLVM’s libFuzzer coverage-guided fuzzer. That is, the fuzzer varies the inputs it tries based on observing how the inputs affect the branches taken inside the code being fuzzed. The fuzzer runs with one of LLVM’s sanitizers enabled. By default, the Address Sanitizer (ASAN) is used. (Even though the sanitizers should never find bugs in safe Rust code, the sanitizers are relevant to bugs in Rust code that uses unsafe.)

I wrote a second implementation (the “model”) of the same API in the most obvious way possible using Rust standard-library facilities and without unsafe, except where required to be able to write into an &mut str. I also used the second implementation to validate the speed of the complex implementation. Obviously, there’d be no point in having a complex implementation if it wasn’t faster than the simple and obvious one. (The complex implementation is, indeed, faster.)

For example, the function for checking if a buffer of potentially invalid UTF-16 only contains characters in the Latin1 range is 8 lines (including the function name and the closing brace) in the safe version. In the fast version, it’s 3 lines that just call to another function expanded from a macro, where the expansion is either generated using either a 76-line SIMD-using macro or a 71-line ALU-using macro depending on whether the code was compiled with SIMD enabled. Of these macros, the SIMD calls another (tiny) function that has a specialized implementation for aarch64 and a portable implementation.

To use cargo-fuzz, you create a “fuzzer script”, which is a Rust function that gets a slice of bytes from the fuzzer and exercises the code being fuzzed. In the case of fuzzing encoding_rs::mem, the first byte is used to decide which function to exercise and the rest of the slice is used as the input to the function. When the function being called takes a slice of u16, a suitably aligned u16 subslice of the input is taken.

For each function, the fuzzer script calls both the complex implementation and the corresponding simple implementation with the same input and checks that the outputs match. The fuzzer finds a bug if the outputs don’t match, if there is a panic, or if the LLVM Address Sanitizer notices bad memory access, which could arise from the use of unsafe.

Once the fuzzer fails to find problems after having run for a few days, we can have high confidence that the complex implementation is correct in the sense that its observable behavior, ignoring speed, matches the observable behavior of the simple implementation. Therefore, a code review for the correctness of the simple implementation can, with high confidence, be considered to apply to the complex implementation as well.