-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Unsound uses of Unsafe in API #289
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
Comments
@axon-q First of all if your concern is
Most likely no, but it should be investigated on per case basis, not overall
No, I don't believe it is right approach to problem. P.s. Of course if code is not correct it should be corrected
AFAIK there is no long-term plan, but nothing stops you from eliminating it on per case basis(as long as it doens't impact performance significantly) But overall goal should not be to remove 100% of unsafe code |
unsafe code is used mostly for two reasons:
in any case we have to evaluate every use case for unsafe. i used unsafe for the reason, in most cases i couldnt come up with safe solution. also you need to take into account size of the codebase, at the moment actix-web is ~27k loc |
@DoumanAsh The point is to reduce risk and the attack surface. Of course the entire stack, including I agree that |
@fafhrd91 Makes sense! Good to know that it might be possible to work toward removing some of the non-performance-critical usages. Also, some uses of |
If anyone would like to try fuzzing, these will come in handy:
|
After noticing this issue, and then noticing #301, I figured I'd do a more in-depth analysis of the I haven't done a complete review. I first looked in public API files, and so have not analyzed The two main classes of issues I have found are:
While a couple
The issues I've found so far: Actix core
Actix-web
|
@seanmonstar thanks for analysis. i will think about this. |
@seanmonstar thanks again for pointing.
last is header_mut(), i need to think how to fix it |
fixed most of the problems. let's open new ticket for each new case. |
I'm glad that some of the issues could be fixed, that's great! However, I think it's early to close this issue, as "most of the problems" are not actually fixed. Some of the holes have been filled in, but the underlying unsafety still exists, and several of the "fixes" actually still leave a public API that is unsound.
The biggest problem is there several different versions of code like this: let alias: &mut Foo = unsafe { &mut *(self as *const Foo as *mut Foo) };
self.inner.do_something_mut(alias) This is a very unsafe thing to do! True, it's possible for the For that reason, I'm not spelling out exactly how to trigger the memory bugs that still exist (though I have exact steps), since it's not my goal to have the ones I find fixed. It's my goal to have people using and writing safe software. Instead, I can write up some steps on how to fix the roots.
Besides the unsoundness that I've been able to identify, there may exist other instances that I haven't noticed yet. Instead of fixing the individual issues, fixing the root makes any unnoticed issues go away too. I'd expect this issue to remain open so users of Actix can track how to know that the code they rely on is safe, until everything has been resolved.
(An example of number 2 is how I believe Actix users would want these to be addressed. If not by reopening this issue, then by opening a new one with that objective. |
Also, the issue's headline is:
This is still the case. Being able to track this is useful... |
@seanmonstar i can not see how to trigger memory unsafety with |
Each use of OTOH
Do you mean that you couldn't come up with a safe solution in safe Rust? Because |
So I'm a newish Rust developer (but long time developer in other stuff). Will efforts to start refactoring the API/Code to remove reliance on |
Recommended to follows three rules-of-thumb for designing a hybrid, memory-safe architecture, as proposed by the Rust SGX SDK project:
|
I am going to reopen this issue as there is clear evidence that the API exposed currently is not sound. Thanks @seanmonstar for pointing this out. I want to spend some time in helping to solve these problems. At the same time I want to set some expectations that this is going to be a process that will take quite a bit of time. I identified one issue #332 which is the core of a lot of this. It's that we currently use an inner type that is used among multiple clonable request objects and through it multiple mutable references can be obtained. It's also clear that this happens in practice. The solution will require some API changes and I want to find out what good ways there are to do this. That request object also sets a pattern that has been used in various places in actix so getting a good story there in place is likely to then set some guidelines of how to do this elsewhere. This is a topic that's very important to me and I would love if people with experience in that field would be able to assist us. |
@mitsuhiko As I mentioned in gitter I think it would be better to look in direction of removing Things like |
@DoumanAsh and then replace it with explicit I think i like the idea of removing |
It is true that it is going to be difficult but the whole need for smart pointers here is to let you clone requests around. But this is really pain as you mentioned since clone is used extensively. P.s. it may imply performance degradation I wonder? @fafhrd91 I wonder what do you think? |
I really don't see how So for instance it would be trivial to have an API contract like The trickest one is |
I think for now I want to land some changes that mark functions as unsafe that should need that or tag them to be only there for internal test uses. That should make it clearer which ones are okay and which ones are not. And add markers to indicate why things are unsafe. |
Let’s not rush. We need to play with different approaches. In general, I am inclined to remove unsafe rather than making unsafe fn. I am not very happy about this shitstorm atm |
For anyone keeping track of this, last week |
@mitsuhiko first I want to say that I'm not really an expert on web development or any of the such so my understanding of these issues is relatively low. However, I did have several times have to spend time in Rust developing things which were very counter-intuitive to do with the borrow checker as they required various mutations which are not allowed. As such I'm quite curious what exactly is the issue/use-case/problem here. Is it possible for you to describe a bit the flow of the API and where/why this is required and which bits make it harder? Again for someone not so familiar with HTTP libraries. |
@botev unsafe can make safe Rust to perform an UB operation which would lead to anything, including data corruption or panic. Here is an example on playground. Although it compiles it crashes at runtime (best outcome). However, UB says that it could silently corrupt your data or send your credit card number to African drug dealers (not so nice outcome). |
Right now the actix-web code contains 100+ uses of unsafe. Presumably this is in order to achieve the best possible performance in hot parts of the code.
However, web servers often face the public Internet, so security is extremely important for web server implementations. This issue is especially critical for organizations that intend to use the software in large-scale production environments. One of the main reasons to choose a Rust-based HTTP implementation is the guaranteed memory safety that safe Rust provides. Unfortunately this guarantee is eroded for every use of
unsafe
in the codebase. Performance isn't worth much if it comes at the cost of critical security vulnerabilities due to unsafe memory access. It's also nice to know for certain that your web server won't segfault in production.I propose that we leave this open as a tracking issue to track design and implementation issues concerning the use of unsafe code. Some of the items that should be explored:
unsafe
without significantly impacting performance?unsafe
even if there's a performance impact?The text was updated successfully, but these errors were encountered: