Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix soundness concern in h1 decoder #1614

Merged
merged 2 commits into from
Jul 21, 2020
Merged

fix soundness concern in h1 decoder #1614

merged 2 commits into from
Jul 21, 2020

Conversation

robjtede
Copy link
Member

@robjtede robjtede commented Jul 20, 2020

PR Type

Unsoundness Fix

PR Checklist

  • Tests for the changes have been added / updated.
  • Documentation comments have been added / updated.
  • A changelog entry has been made for the appropriate packages.

Overview

From all the sources I can see, its never okay to do:

let arr:[T; n] = unsafe { MaybeUninit::uninit().assume_init() };

unless T is MaybeUninit<T> (see the nomicon).

Parsing HTTP headers in the h1 decoder currently uses code like this which Miri flags as unsound. See this playground for a simplified example.

This PR removes all the unsound memory initializations in h1 decoder and opts to use a pre-filled const array to be handed to httparse.

I believe this to be the fastest sound solution without requiring changes to httparse. (Aside: I think in theory, httparse could provide a parse function that fills in a MaybeUninit header array and allows caller to declare the array intitialized with the number of headers it parsed. You can imagine it's data flow with the setup in this modifed playground. However, I opted for the safer approach for now)

Benchmark code is included. Using test cases from httparse we see the following regressions:

Short Response:

Original (Unsound) [short]        time:   [162.17 ns 166.87 ns 172.44 ns]
New (safe) [short]                time:   [207.06 ns 210.67 ns 214.79 ns]

Realistic Response:

Original (Unsound) [realistic]    time:   [516.38 ns 526.95 ns 538.79 ns]
New (safe) [realistic]            time:   [532.47 ns 543.05 ns 556.96 ns]

@robjtede robjtede force-pushed the fix/ub-uninit-assume branch from 461165f to 9e8fa36 Compare July 20, 2020 01:35
@robjtede robjtede marked this pull request as ready for review July 20, 2020 01:37
@robjtede robjtede requested review from a team July 20, 2020 01:40
@robjtede robjtede changed the title fix safety concern in h1 decoder fix soundness concern in h1 decoder Jul 20, 2020
@robjtede robjtede added the A-http project: actix-http label Jul 20, 2020
@robjtede robjtede force-pushed the fix/ub-uninit-assume branch from 9e8fa36 to befad57 Compare July 20, 2020 01:41
@codecov-commenter
Copy link

codecov-commenter commented Jul 20, 2020

Codecov Report

Merging #1614 into master will increase coverage by 0.03%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1614      +/-   ##
==========================================
+ Coverage   53.15%   53.18%   +0.03%     
==========================================
  Files         122      122              
  Lines       11774    11770       -4     
==========================================
+ Hits         6258     6260       +2     
+ Misses       5516     5510       -6     
Impacted Files Coverage Δ
actix-http/src/h1/decoder.rs 61.64% <100.00%> (+1.50%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0ec335a...1c39a86. Read the comment docs.

@robjtede robjtede removed the A-http project: actix-http label Jul 20, 2020
Copy link
Member

@JohnTitor JohnTitor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering benchmarks, I think it's reasonable trade-off. Thanks for detail explanation and implementation, great work :)

@robjtede robjtede force-pushed the fix/ub-uninit-assume branch from 0c5fc0a to ce839a3 Compare July 20, 2020 23:56
@robjtede robjtede mentioned this pull request Jul 21, 2020
15 tasks
@robjtede robjtede merged commit 6dc47c4 into master Jul 21, 2020
@robjtede robjtede deleted the fix/ub-uninit-assume branch July 22, 2020 02:24
@Shnatsel
Copy link

This RFC will allow getting performance back safely: rust-lang/rfcs#2930

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants