TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Heartbleed in Rust

245 点作者 glass-超过 10 年前

18 条评论

MichaelGG超过 10 年前
As the offending commentor, I apologize. Particularly to the Rust team for generating this negative publicity, and to the person I replied to, for asserting a lie.<p>I misunderstood Heartbleed, exactly as Ted summarizes. I&#x27;ve no excuse other than commenting when I shouldn&#x27;t. I am happy though to have my idiocy corrected as I&#x27;ll comment better in the future.<p>The rest of the original thread does point out that I <i>did</i> examine every security advisory published by Microsoft over a year or two span, and that, from the descriptions, Rust would have prevented basically every serious (code exec) one. (Notable exceptions being failures in the sandboxed code loading, similar to the various Java in browser bugs.)
评论 #8985148 未加载
评论 #8985902 未加载
评论 #8986375 未加载
评论 #8985692 未加载
评论 #8988754 未加载
nikomatsakis超过 10 年前
I don&#x27;t know that anyone claimed that a bug similar or analogous to heartbleed couldn&#x27;t be reproduced in Rust. If they did, that was certainly an overstatement. I think more concretely people claimed that unreachable code yields a warning in Rust, which is absolutely true, but certainly not equivalent to saying something like a heartbleed bug would not happen.<p>In general, Rust is fairly aggressive about linting for &quot;small&quot; details like unused variables, unreachable code, names that don&#x27;t conform to expected conventions, unnecessary `mut` annotations, and so forth. I&#x27;ve found that these lints are surprisingly effective at catching bugs.<p>In particular, the lints about unused variables and unreachable code regularly catch bugs for me. These are invariably simple oversights (&quot;just plain forgot to write the code I meant to write which would have used that variable&quot;), but they would have caused devious problems that would have been quite a pain to track down.<p>I&#x27;ve also found that detailed use of types is similarly a great way to ensure that bugs like heartbleed are less common. Basically making sure that your types match as precisely as possible the shape of your data -- with no extra cases or weird hacks -- will help steer your code in the right direction. This is a technique you can apply in any language, but good, lightweight support for algebraic data types really makes it easier to do.
评论 #8984123 未加载
simias超过 10 年前
I mostly agree with the premise: logic errors are always going to be there, at least until the compiler is an IA strong enough to catch them for us (and by then we probably won&#x27;t need coders anyway...). There&#x27;s no silver bullet, bad coders are always going to produce. And I also don&#x27;t like it when people claim that bug X or vulnerability Y wouldn&#x27;t have happened if they had been technology Z, they&#x27;re just begging for that type of post.<p>That being said I&#x27;m a bit more skeptical of this part: &quot;code no true C programmer would write : heartbleed :: code no true rust programmer would write :: (exercise for the reader)&quot;<p>If I look at the examples in the acticle, the C version doesn&#x27;t look that terrible and contrieved to me. I wonder what the author means by &quot;Survey says no true C programmer would ever write a program like that, either.&quot; That looks like a lot of C code I&#x27;ve read, there&#x27;s nothing particularly weird about it.<p>On the other hand the rust version looks very foreign to me (and I&#x27;ve been writing quite a lot of rust lately). You basically have to go out of your way to create the same issue.<p>I guess my point is that while it&#x27;s true that as long as there&#x27;ll be coders there&#x27;ll be bugs and security vulnerabilities it doesn&#x27;t mean we shouldn&#x27;t try to make things better. And in my opinion Rust makes it much more difficult to shoot yourself in the foot than plain C.
评论 #8984545 未加载
评论 #8984831 未加载
评论 #8984977 未加载
评论 #8984349 未加载
Torgo超过 10 年前
Here is what I noticed about this, sorry if it is considered too off-topic:<p>There was an argument, about something specific and technical; It was refuted without singling out a specific person by name; without using humiliation or insults; using code to do so (&quot;show me the code!&quot;); and there was a polite acknowledgement and resolution.<p>This is an example of an interaction in a community that I think anyone would want to be a part of. Thank you.
评论 #8985273 未加载
geofft超过 10 年前
I&#x27;m very confused at the argument here. The C code looks remarkably close to idiomatic. Not &quot;good,&quot; mind you, but &quot;idiomatic&quot;. The Rust code looks significantly more contrived to my eyes. I&#x27;m reading the blog post as arguing that they&#x27;re equally contrived.<p>It&#x27;s true that you can do terrible things in any language, but the test of a language is <i>how easy</i> it makes it to do the right thing in the common case (plus <i>how possible</i> it makes it to do the thing you want in the uncommon case, without these goals compromising the other).<p>Is there a reason that reusing the buffer makes sense in Rust? (Zero allocation?)<p>Also, is it not true that Rust lends itself well, probably better than C, to abstractions like bounds-checked substrings within a single buffer? BoringSSL has been doing this in C, and this <i>definitely</i> would have stopped Heartbleed:<p><a href="https://boringssl.googlesource.com/boringssl/+/master/include/openssl/bytestring.h" rel="nofollow">https:&#x2F;&#x2F;boringssl.googlesource.com&#x2F;boringssl&#x2F;+&#x2F;master&#x2F;includ...</a>
steveklabnik超过 10 年前
This is why I get a little uncomfortable when people suggest Rust fixes tons of security issues. Yes, it will fix some of them. No, just because a Rust program compiles doesn&#x27;t mean that it won&#x27;t have problems.<p>Rust is _memory safe_. Nothing more, nothing less.
评论 #8984112 未加载
nickik超过 10 年前
Some people wrote a completly new TLS Stack in Ocaml to combat this problem:<p><a href="http://openmirage.org/blog/introducing-ocaml-tls" rel="nofollow">http:&#x2F;&#x2F;openmirage.org&#x2F;blog&#x2F;introducing-ocaml-tls</a><p>Here a Video about Mirage OS and this TLS Stack from the 31C3.<p>Trustworthy secure modular operating system engineering - <a href="http://media.ccc.de/browse/congress/2014/31c3_-_6443_-_en_-_saal_2_-_201412271245_-_trustworthy_secure_modular_operating_system_engineering_-_hannes_-_david_kaloper.html" rel="nofollow">http:&#x2F;&#x2F;media.ccc.de&#x2F;browse&#x2F;congress&#x2F;2014&#x2F;31c3_-_6443_-_en_-_...</a><p>There goal is to reduce the trusted computing base to a minimal.<p>Rust could deliver some of the same benefits to writing highperformance low level code.
评论 #8984984 未加载
pacala超过 10 年前
If I&#x27;m reading the blog code correctly, the error is trusting user input:<p><pre><code> &#x2F;&#x2F; Rust let len = buffer[0] as usize; &#x2F;&#x2F; C size_t len = buffer[0]; </code></pre> I&#x27;m no Rust hacker, but can I expect the Rust type system to be able to encode some form of tainting? Making the leaky sequence illegal:<p><pre><code> let len = buffer[0] as usize; &#x2F;&#x2F; ERROR ERROR ERROR using unscrubbed user input ERROR ERROR ERROR buffer[0 .. len] </code></pre> How exactly to encode tainting is left as an exercise to the reader :) But ideally it should be able to identify that the buffer is reused between 2 different requests, and that data tainted from second request is used to index an array tainted with data from first request. This seems eery up Rust&#x27;s alley, given the concurrency &#x2F; allocation disambiguation support I&#x27;ve read (alas superficially) elsewhere.
评论 #8985435 未加载
ajanuary超过 10 年前
Wasn&#x27;t the heartbleed issue that you could trick it into reading past the memory it had allocated? That&#x27;s different to explicitly reusing memory you&#x27;ve allocated without clearing it in between.<p>The original claim was that rust would prevent the class of errors that caused Heartbleed. No one claimed rust would prevent you from writing a program with a different bug that just happens to exhibit similar behavior.<p>Buffer overruns are tricker to spot than explicitly reusing a buffer.<p>[Edit] An example of an actual buffer overrun, with no changes to pingback.<p>C:<p><pre><code> $:&#x2F;tmp # cat bleed.c #include &lt;fcntl.h&gt; #include &lt;unistd.h&gt; #include &lt;assert.h&gt; void pingback(char *path, char *outpath, unsigned char *buffer) { int fd; if ((fd = open(path, O_RDONLY)) == -1) assert(!&quot;open&quot;); if (read(fd, buffer, 256) &lt; 1) assert(!&quot;read&quot;); close(fd); size_t len = buffer[0]; if ((fd = creat(outpath, 0644)) == -1) assert(!&quot;creat&quot;); if (write(fd, buffer, len) != len) assert(!&quot;write&quot;); close(fd); } int main(int argc, char **argv) { unsigned char buffer2[10]; unsigned char buffer1[10]; pingback(&quot;yourping&quot;, &quot;yourecho&quot;, buffer1); pingback(&quot;myping&quot;, &quot;myecho&quot;, buffer2); } $:&#x2F;tmp # gcc bleed.c &amp;&amp; .&#x2F;a.out &amp;&amp; cat yourecho myecho #i have many secrets. this is one. #i know your one. Æ+x-core:&#x2F;tmp # </code></pre> Rust:<p><pre><code> C:\Users\ajanuary\Desktop&gt;cat hearbleed.rs use std::old_io::File; fn pingback(path : Path, outpath : Path, buffer : &amp;mut[u8]) { let mut fd = File::open(&amp;path); match fd.read(buffer) { Err(what) =&gt; panic!(&quot;say {}&quot;, what), Ok(x) =&gt; if x &lt; 1 { return; } } let len = buffer[0] as usize; let mut outfd = File::create(&amp;outpath); match outfd.write_all(&amp;buffer[0 .. len]) { Err(what) =&gt; panic!(&quot;say {}&quot;, what), Ok(_) =&gt; () } } fn main() { let buffer2 = &amp;mut[0u8; 10]; let buffer1 = &amp;mut[0u8; 10]; pingback(Path::new(&quot;yourping&quot;), Path::new(&quot;yourecho&quot;), buffer1); pingback(Path::new(&quot;myping&quot;), Path::new(&quot;myecho&quot;), buffer2); } C:\Users\ajanuary\Desktop&gt;hearbleed.exe thread &#x27;&lt;main&gt;&#x27; panicked at &#x27;assertion failed: index.end &lt;= self.len()&#x27;, C:\bot\slave\nightly-dist-rustc-win-64\build\src\libcore\slice.rs:524</code></pre>
评论 #8984169 未加载
评论 #8984103 未加载
leovonl超过 10 年前
I fail to see the point of this whole discussion.<p>The code reflects exactly what the program is doing, and there&#x27;s no undefined behaviour anywhere. There&#x27;s no way to access anything outside the very delimited scope of &quot;buffer&quot; memory area, like stack variables or any other part of the program.<p>What&#x27;s the point of using a high-level language for re-defining basic low-level operations on buffers and recreating everything using those low-level constructs without the proper boundary checks?<p>Of course, you can simply define a huge &quot;unsafe&quot; block and program everything inside it, but what&#x27;s the point? That you have a language powerful enough to shoot yourself?<p>Compare that to C or C++: the unsafe block is always on. Any code block can have unsafe properties anywhere. Not only that, but you have ZERO guarantees on memory safety and other general operations. Summarizing, high-level and low-level totally mixed and no way to isolate them.<p>Sorry, but if you can&#x27;t see how Rust avoids a &quot;Heartbleed&quot; or any other kind of similar issue, you have no understanding of programming or no experience debugging anything.<p>And yes: security != safety, but please note you are the one mixing both concepts.
kaoD超过 10 年前
Slightly OT: while trying to understand the vulnerability I came across a Rust question.<p>Why can you do this?<p><pre><code> let mut outfd = File::create(&amp;outpath); match outfd.write_all(&amp;buffer[0 .. len]) { ... } </code></pre> According to `old_io::File`&#x27;s doc[0] it returns an `IoResult&lt;File&gt;` which is an alias `type IoResult&lt;T&gt; = Result&lt;T, IoError&gt;` i.e. `Result&lt;File, IoError&gt;`. How come you can do `write_all` directly on a `Result&lt;File, IoError&gt;` without unwrapping the `File` first?<p>The example in the docs does something similar:<p><pre><code> let mut f = File::create(&amp;Path::new(&quot;foo.txt&quot;)); f.write(b&quot;This is a sample file&quot;); </code></pre> So I guess I&#x27;m missing something here.<p>[0] <a href="http://doc.rust-lang.org/std/old_io/fs/struct.File.html#method.create" rel="nofollow">http:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;old_io&#x2F;fs&#x2F;struct.File.html#meth...</a>
评论 #8984040 未加载
评论 #8984030 未加载
评论 #8984061 未加载
tormeh超过 10 年前
My take-away: Low-level code will burn you eventually, and unnecessarily low-level code will burn you unnecessarily
评论 #8984877 未加载
评论 #8984168 未加载
评论 #8984790 未加载
stevejones超过 10 年前
No true blogger would wilfully misunderstand a buffer overrun vulnerability in order to score some cheap pageviews.<p>To put it simply, his examples are the equivalent of doing this:<p><pre><code> unsigned char data[4096]; #define X (*(int *)(&amp;data[0])) #define Y (*(int *)(&amp;data[4])) ... </code></pre> Basically, he&#x27;s explicitly re-using a buffer, no buffer was overrun. In Rust you will not read something out of a buffer you didn&#x27;t put there first, in C you can, and you might even read several GB out of a 256 byte buffer.
评论 #8984115 未加载
yk超过 10 年前
Well of course this is possible. You can port a bug compatible version of a program to any other language. That is called Turing complete ( and may involve writing a x64 emulator in VB Script). &#x2F;snark<p>A bit more serious, I wonder which security problems Rust would have, if it would be as well studied as C.
krick超过 10 年前
So, let&#x27;s say I&#x27;m on drugs and I&#x27;m writing TLS implementation being not &quot;real Rust programmer&quot;. What are &quot;rules of the thumb&quot; I should follow (let&#x27;s assume I have that much self-control) to not end up with something like this?
评论 #8988489 未加载
lmm超过 10 年前
&quot;Code no true C programmer would write&quot;, eh? And yet one did, in a high-profile, security-critical library. When you find Rust code like this in the wild, I&#x27;ll start to believe in some kind of equivalence.
评论 #8984815 未加载
qguv超过 10 年前
Shouldn&#x27;t that analogy read:<p>code no true C programmer would write : heartbleed :: code no true rust programmer would write : (exercise for the reader)
mseepgood超过 10 年前
Type &#x2F; memory safety != security. The Rust people also mistake &quot;no segmentation faults&quot; for &quot;no crashes&quot;.
评论 #8986059 未加载
评论 #8986813 未加载