Skip to content

Instantly share code, notes, and snippets.

@bb010g
Last active Oct 18, 2020
Embed
What would you like to do?
actix/actix-net#83, actix/actix-net#87

actix-service Cell::get_mut() is unsound #83


Shnatsel opened this issue on 2020-01-08T17:36:50Z

@Shnatsel < Shnatsel commented on 2020-01-08T17:36:49Z

The following code is unsound:

https://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36

This uses Rc::as_ref() to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:

let mycell = Cell::new(vec![1,2,3]);
let ref1 = mysell.get_mut();
let ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here

This may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.

A proper way to implement Cell:get_mut() would be calling Rc::get_mut() which guarantees uniqueness instead of Rc::as_ref().


@fafhrd91 < fafhrd91 commented on 2020-01-08T17:39:01Z [Member]

This is internal code. There is no repeated call to get_mut() anywhere in code


fafhrd91 closed this issue on 2020-01-08T17:39:02Z

@Shnatsel < Shnatsel commented on 2020-01-08T17:36:49Z (updated 2020-01-08T17:39:02Z)

The following code is unsound:

https://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36

This uses Rc::as_ref() to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:

let mycell = Cell::new(vec![1,2,3]);
let ref1 = mysell.get_mut();
let ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here

This may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.

A proper way to implement Cell:get_mut() would be calling Rc::get_mut() which guarantees uniqueness instead of Rc::as_ref().


@fafhrd91 < fafhrd91 commented on 2020-01-08T17:39:18Z [Member]

Please, don’t start


@Shnatsel < Shnatsel commented on 2020-01-08T17:49:00Z

These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.

An easy way to see if this is a problem in practice is replace .as_ref() with .get_mut().unwrap() and see if anything panics.


@cdbattags < cdbattags commented on 2020-01-08T19:07:20Z [Member]

@fafhrd91, I don't think "unsound" was meant to be personal or offensive.

Why close this so quickly?


@fafhrd91 < fafhrd91 commented on 2020-01-09T00:24:48Z [Member]

I need unit test that shows UB.


@Nemo157 < Nemo157 commented on 2020-01-10T17:02:32Z

The unsoundness of the Cell API is publicly exposed through AndThenService::{clone, call}. The code in this playground exhibits MIRI detected UB from multiple unrelated &mut First borrows existing simultaneously while using only the safe public API of actix-service.

Running the code via cargo miri results in:

error: Miri evaluation error: not granting access to tag <untagged> because incompatible item is protected: [Unique for <7869> (call 4775)]
  --> /Users/nemo157/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-service-1.0.2/src/cell.rs:35:18
   |
35 |         unsafe { &mut *self.inner.as_ref().get() }
   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Miri evaluation error: not granting access to tag <untagged> because incompatible item is protected: [Unique for <7869> (call 4775)]
   |
   = note: inside call to `actix_service::cell::Cell::<(First, &mut Second)>::get_mut` at /Users/nemo157/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-service-1.0.2/src/and_then.rs:54:29
   = note: inside call to `<actix_service::and_then::AndThenService<First, &mut Second> as actix_service::Service>::call` at /Users/nemo157/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-service-1.0.2/src/pipeline.rs:160:9

(@repnop identified that AndThenService allowed accessing these APIs and helped developing the PoC)


@JohnTitor < JohnTitor commented on 2020-01-10T19:36:13Z [Member]

I think it's worth to fix, re-opening.


JohnTitor reopened this issue on 2020-01-10T19:36:13Z

@Shnatsel < Shnatsel commented on 2020-01-08T17:36:49Z (updated 2020-01-10T19:36:13Z)

The following code is unsound:

https://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36

This uses Rc::as_ref() to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:

let mycell = Cell::new(vec![1,2,3]);
let ref1 = mysell.get_mut();
let ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here

This may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.

A proper way to implement Cell:get_mut() would be calling Rc::get_mut() which guarantees uniqueness instead of Rc::as_ref().


@fafhrd91 < fafhrd91 commented on 2020-01-15T19:38:25Z [Member]

@Nemo157 @repnop nice! finally some real code!


@cdbattags < cdbattags commented on 2020-01-15T19:40:21Z [Member]

Hehehe thanks @fafhrd91, @Nemo157 and @repnop!


@fafhrd91 < fafhrd91 commented on 2020-01-15T19:41:57Z [Member]

should be fixed in master


fafhrd91 closed this issue on 2020-01-15T19:41:58Z

@Shnatsel < Shnatsel commented on 2020-01-08T17:36:49Z (updated 2020-01-15T19:41:57Z)

The following code is unsound:

https://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36

This uses Rc::as_ref() to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:

let mycell = Cell::new(vec![1,2,3]);
let ref1 = mysell.get_mut();
let ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here

This may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.

A proper way to implement Cell:get_mut() would be calling Rc::get_mut() which guarantees uniqueness instead of Rc::as_ref().


@Nemo157 < Nemo157 commented on 2020-01-15T20:05:47Z

It's possible to get around the 'static bound by using Arc, see this playground (I've also removed the unnecessary &mut Second, that was where I was trying to trigger the UB but miri caught the duplicate &mut (First, &mut Second) before it even got to checking the &mut Second itself).


@repnop < repnop commented on 2020-01-15T20:21:28Z

its also worth noting that adding a + 'static bound is a breaking change. I think ideally this should be fixed internally in a way that doesn't break the public API, especially in a patch version if possible


@Shnatsel < Shnatsel commented on 2020-01-15T20:24:09Z

Undefined behavior occurs when external code attempts to obtain two mutable references to the same data. The lifetime of the data is irrelevant to this issue.

If Rc<RefCell> were used instead of a custom implementation it would panic on the provided testcase instead of triggering undefined behavior. It should be possible to bring the behavior of the current implementation in line with Rc<RefCell>.

If panicking is undesirable, it is possible to return Option or Result from this function instead of panicking, see RefCell::try_borrow_mut for an example of such API.

I wonder, what was the original rationale for migrating from Rc<RefCell> to a custom implementation?


@fafhrd91 < fafhrd91 commented on 2020-01-15T20:56:23Z [Member]

@Nemo157 new playground panics with BorrowMutError, is that what should happen?


@fafhrd91 < fafhrd91 commented on 2020-01-15T20:58:22Z [Member]

@repnop i dont see how this could be fixed internally


@Nemo157 < Nemo157 commented on 2020-01-15T21:06:30Z

If you run the code from the playground under MIRI it fails before the BorrowMutError with:

error: Miri evaluation error: not granting access to tag <untagged> because incompatible item is protected: [Unique for <7923> (call 4813)]
  --> /Users/nemo157/.cargo/git/checkouts/actix-net-8b378701d4b3767e/5940731/actix-service/src/cell.rs:35:18
   |
35 |         unsafe { &mut *self.inner.as_ref().get() }
   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Miri evaluation error: not granting access to tag <untagged> because incompatible item is protected: [Unique for <7923> (call 4813)]
   |
   = note: inside call to `actix_service::cell::Cell::<(First, Second)>::get_mut` at /Users/nemo157/.cargo/git/checkouts/actix-net-8b378701d4b3767e/5940731/actix-service/src/and_then.rs:54:29
   = note: inside call to `<actix_service::and_then::AndThenService<First, Second> as actix_service::Service>::call` at /Users/nemo157/.cargo/git/checkouts/actix-net-8b378701d4b3767e/5940731/actix-service/src/pipeline.rs:160:9
   = note: inside call to `<actix_service::pipeline::Pipeline<actix_service::and_then::AndThenService<First, Second>> as actix_service::Service>::call` at src/main.rs:36:18
   = note: inside call to `<Second as actix_service::Service>::call` at /Users/nemo157/.cargo/git/checkouts/actix-net-8b378701d4b3767e/5940731/actix-service/src/and_then.rs:97:31
   = note: inside call to `<actix_service::and_then::AndThenServiceResponse<First, Second> as core::future::future::Future>::poll` at src/main.rs:55:35
   = note: inside call to `block_on::<actix_service::and_then::AndThenServiceResponse<First, Second>>` at src/main.rs:47:5
   = note: inside call to `main` at /Users/nemo157/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/src/libstd/rt.rs:67:34

because at this point there exist two independent &mut (First, Second) on the stack referencing the same tuple.


@Restioson < Restioson commented on 2020-01-16T11:52:47Z

Would it be possible to simply change it to Rc<RefCell<T>>?


@Nemo157 < Nemo157 commented on 2020-01-16T12:22:52Z

As a PoC this patch applied to actix-net passes all tests, and when the second playground is run against it under Miri it soundly fails with thread 'main' panicked at 'already borrowed: BorrowMutError' from within the AndThenServiceResponse. Presumably this requires benchmarking/more exhaustive testing which I don't have time to do, but if someone wants to take the patch and get it merged feel free (I license it under Apache-2.0 OR MIT, though I don't consider it to be creative enough to be copyrightable).


@fafhrd91 < fafhrd91 commented on 2020-01-16T13:43:12Z [Member]

this patch is boring


@CJKay < CJKay commented on 2020-01-16T21:35:04Z

this patch is boring

So is resolving silent data corruption.


@bbqsrc < bbqsrc commented on 2020-01-16T23:11:06Z

@fafhrd91 seriously? Please just stop writing Rust. You do not respect semver, you do not respect soundness, so why are you using a language predominantly based around doing these things right?


@JohnTitor < JohnTitor commented on 2020-01-16T23:24:47Z [Member]

@bbqsrc I understand your point, but that doesn't mean you should use offensive words.


Why was issue #83 deleted? #87


cdbattags opened this issue on 2020-01-17T00:12:30Z

@cdbattags < cdbattags commented on 2020-01-17T00:12:30Z [Member]

Issue #83 contained some pretty good discussion surrounding unsafe rust and I don't think we should ignore or delete a constructive conversation.

@fafhrd91, please please please can we try not to use phrases like "this patch is boring"?


fafhrd91 closed this issue on 2020-01-17T00:20:02Z

@cdbattags < cdbattags commented on 2020-01-17T00:12:30Z (updated 2020-01-17T00:20:02Z) [Member]

Issue #83 contained some pretty good discussion surrounding unsafe rust and I don't think we should ignore or delete a constructive conversation.

@fafhrd91, please please please can we try not to use phrases like "this patch is boring"?

❤️


@fafhrd91 < fafhrd91 commented on 2020-01-17T00:20:30Z [Member]

Next stage will be deleting organization. Please, do not continue


@cdbattags < cdbattags commented on 2020-01-17T00:22:17Z [Member]

Why the hostility though? I know it's hard over text/internet/GitHub but I'm coming from a place of wanting this project to succeed.


@fafhrd91 < fafhrd91 commented on 2020-01-17T01:01:14Z [Member]

boring, because nobody actually wants to fix existing code, everyone just want to remove unsafe.

it is fixed, Actix-service 1.0.5 is released.


@cdbattags < cdbattags commented on 2020-01-17T01:04:20Z [Member]

Thank you, Nikolay! I think it was just a misunderstanding of tone.

I appreciate everything you've done for this project this far and I think this is the future of server-side web development for sure.

Any sort of list of TODOs for the actix ecosystem right now?


@fafhrd91 < fafhrd91 commented on 2020-01-17T01:06:37Z [Member]

It is not very interesting to continue development. I will work only on functionality that is required for my job.


@cdbattags < cdbattags commented on 2020-01-17T01:12:29Z [Member]

@carllerche am I right to assume that tokio org would potentially take this project under its wing?


@fafhrd91 < fafhrd91 commented on 2020-01-17T01:16:17Z [Member]

We use it for large project. If this project goes to other org then we’ll change to fully private development.


@cdbattags < cdbattags commented on 2020-01-17T01:10:05Z [Member]

Maybe time to pass it off then? I think most of us want to do right by you and the project and get things under the org umbrella but Rust for sure needs a defacto web server (i.e. Express for the Node ecosystem) and that'll require much more continuous dev down the road, no?

Also, might I ask what's Microsoft's current stake in this project?


[
{
"id": "11230537254",
"type": "IssuesEvent",
"actor": {
"id": 291257,
"login": "Shnatsel",
"display_login": "Shnatsel",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"avatar_url": "https://avatars.githubusercontent.com/u/291257?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "opened",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "open",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 0,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-08T17:36:49Z",
"closed_at": null,
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
}
},
"public": true,
"created_at": "2020-01-08T17:36:50Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11230554806",
"type": "IssueCommentEvent",
"actor": {
"id": 598990,
"login": "fafhrd91",
"display_login": "fafhrd91",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"avatar_url": "https://avatars.githubusercontent.com/u/598990?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 0,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-08T17:39:01Z",
"closed_at": "2020-01-08T17:39:01Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/572177259",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-572177259",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 572177259,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3MjE3NzI1OQ==",
"user": {
"login": "fafhrd91",
"id": 598990,
"node_id": "MDQ6VXNlcjU5ODk5MA==",
"avatar_url": "https://avatars2.githubusercontent.com/u/598990?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"html_url": "https://github.com/fafhrd91",
"followers_url": "https://api.github.com/users/fafhrd91/followers",
"following_url": "https://api.github.com/users/fafhrd91/following{/other_user}",
"gists_url": "https://api.github.com/users/fafhrd91/gists{/gist_id}",
"starred_url": "https://api.github.com/users/fafhrd91/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/fafhrd91/subscriptions",
"organizations_url": "https://api.github.com/users/fafhrd91/orgs",
"repos_url": "https://api.github.com/users/fafhrd91/repos",
"events_url": "https://api.github.com/users/fafhrd91/events{/privacy}",
"received_events_url": "https://api.github.com/users/fafhrd91/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-08T17:39:01Z",
"updated_at": "2020-01-08T17:39:01Z",
"author_association": "MEMBER",
"body": "This is internal code. There is no repeated call to get_mut() anywhere in code"
}
},
"public": true,
"created_at": "2020-01-08T17:39:02Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11230554833",
"type": "IssuesEvent",
"actor": {
"id": 598990,
"login": "fafhrd91",
"display_login": "fafhrd91",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"avatar_url": "https://avatars.githubusercontent.com/u/598990?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "closed",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 1,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-08T17:39:02Z",
"closed_at": "2020-01-08T17:39:01Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
}
},
"public": true,
"created_at": "2020-01-08T17:39:02Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11230556986",
"type": "IssueCommentEvent",
"actor": {
"id": 598990,
"login": "fafhrd91",
"display_login": "fafhrd91",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"avatar_url": "https://avatars.githubusercontent.com/u/598990?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 2,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-08T17:39:18Z",
"closed_at": "2020-01-08T17:39:01Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/572177369",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-572177369",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 572177369,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3MjE3NzM2OQ==",
"user": {
"login": "fafhrd91",
"id": 598990,
"node_id": "MDQ6VXNlcjU5ODk5MA==",
"avatar_url": "https://avatars2.githubusercontent.com/u/598990?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"html_url": "https://github.com/fafhrd91",
"followers_url": "https://api.github.com/users/fafhrd91/followers",
"following_url": "https://api.github.com/users/fafhrd91/following{/other_user}",
"gists_url": "https://api.github.com/users/fafhrd91/gists{/gist_id}",
"starred_url": "https://api.github.com/users/fafhrd91/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/fafhrd91/subscriptions",
"organizations_url": "https://api.github.com/users/fafhrd91/orgs",
"repos_url": "https://api.github.com/users/fafhrd91/repos",
"events_url": "https://api.github.com/users/fafhrd91/events{/privacy}",
"received_events_url": "https://api.github.com/users/fafhrd91/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-08T17:39:18Z",
"updated_at": "2020-01-08T17:39:18Z",
"author_association": "MEMBER",
"body": "Please, don’t start"
}
},
"public": true,
"created_at": "2020-01-08T17:39:18Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11230628398",
"type": "IssueCommentEvent",
"actor": {
"id": 291257,
"login": "Shnatsel",
"display_login": "Shnatsel",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"avatar_url": "https://avatars.githubusercontent.com/u/291257?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 3,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-08T17:49:00Z",
"closed_at": "2020-01-08T17:39:01Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/572181161",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-572181161",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 572181161,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3MjE4MTE2MQ==",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-08T17:49:00Z",
"updated_at": "2020-01-08T17:49:00Z",
"author_association": "NONE",
"body": "These two references _do not need to exist in the same function_ to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nAn easy way to see if this is a problem in practice is replace `.as_ref()` with `.get_mut().unwrap()` and see if anything panics."
}
},
"public": true,
"created_at": "2020-01-08T17:49:00Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11231193687",
"type": "IssueCommentEvent",
"actor": {
"id": 4399055,
"login": "cdbattags",
"display_login": "cdbattags",
"gravatar_id": "",
"url": "https://api.github.com/users/cdbattags",
"avatar_url": "https://avatars.githubusercontent.com/u/4399055?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 3,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-08T19:07:20Z",
"closed_at": "2020-01-08T17:39:01Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/572211743",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-572211743",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 572211743,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3MjIxMTc0Mw==",
"user": {
"login": "cdbattags",
"id": 4399055,
"node_id": "MDQ6VXNlcjQzOTkwNTU=",
"avatar_url": "https://avatars1.githubusercontent.com/u/4399055?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/cdbattags",
"html_url": "https://github.com/cdbattags",
"followers_url": "https://api.github.com/users/cdbattags/followers",
"following_url": "https://api.github.com/users/cdbattags/following{/other_user}",
"gists_url": "https://api.github.com/users/cdbattags/gists{/gist_id}",
"starred_url": "https://api.github.com/users/cdbattags/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/cdbattags/subscriptions",
"organizations_url": "https://api.github.com/users/cdbattags/orgs",
"repos_url": "https://api.github.com/users/cdbattags/repos",
"events_url": "https://api.github.com/users/cdbattags/events{/privacy}",
"received_events_url": "https://api.github.com/users/cdbattags/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-08T19:07:20Z",
"updated_at": "2020-01-08T19:07:20Z",
"author_association": "MEMBER",
"body": "@fafhrd91, I don't think \"unsound\" was meant to be personal or offensive.\r\n\r\nWhy close this so quickly?"
}
},
"public": true,
"created_at": "2020-01-08T19:07:21Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11233221676",
"type": "IssueCommentEvent",
"actor": {
"id": 598990,
"login": "fafhrd91",
"display_login": "fafhrd91",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"avatar_url": "https://avatars.githubusercontent.com/u/598990?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 4,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-09T00:24:48Z",
"closed_at": "2020-01-08T17:39:01Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/572322464",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-572322464",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 572322464,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3MjMyMjQ2NA==",
"user": {
"login": "fafhrd91",
"id": 598990,
"node_id": "MDQ6VXNlcjU5ODk5MA==",
"avatar_url": "https://avatars2.githubusercontent.com/u/598990?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"html_url": "https://github.com/fafhrd91",
"followers_url": "https://api.github.com/users/fafhrd91/followers",
"following_url": "https://api.github.com/users/fafhrd91/following{/other_user}",
"gists_url": "https://api.github.com/users/fafhrd91/gists{/gist_id}",
"starred_url": "https://api.github.com/users/fafhrd91/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/fafhrd91/subscriptions",
"organizations_url": "https://api.github.com/users/fafhrd91/orgs",
"repos_url": "https://api.github.com/users/fafhrd91/repos",
"events_url": "https://api.github.com/users/fafhrd91/events{/privacy}",
"received_events_url": "https://api.github.com/users/fafhrd91/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-09T00:24:48Z",
"updated_at": "2020-01-09T00:24:48Z",
"author_association": "MEMBER",
"body": "I need unit test that shows UB."
}
},
"public": true,
"created_at": "2020-01-09T00:24:48Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11248813009",
"type": "IssueCommentEvent",
"actor": {
"id": 81079,
"login": "Nemo157",
"display_login": "Nemo157",
"gravatar_id": "",
"url": "https://api.github.com/users/Nemo157",
"avatar_url": "https://avatars.githubusercontent.com/u/81079?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 6,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-10T17:02:32Z",
"closed_at": "2020-01-08T17:39:01Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/573119526",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-573119526",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 573119526,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3MzExOTUyNg==",
"user": {
"login": "Nemo157",
"id": 81079,
"node_id": "MDQ6VXNlcjgxMDc5",
"avatar_url": "https://avatars1.githubusercontent.com/u/81079?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Nemo157",
"html_url": "https://github.com/Nemo157",
"followers_url": "https://api.github.com/users/Nemo157/followers",
"following_url": "https://api.github.com/users/Nemo157/following{/other_user}",
"gists_url": "https://api.github.com/users/Nemo157/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Nemo157/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Nemo157/subscriptions",
"organizations_url": "https://api.github.com/users/Nemo157/orgs",
"repos_url": "https://api.github.com/users/Nemo157/repos",
"events_url": "https://api.github.com/users/Nemo157/events{/privacy}",
"received_events_url": "https://api.github.com/users/Nemo157/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-10T17:02:32Z",
"updated_at": "2020-01-10T17:02:32Z",
"author_association": "NONE",
"body": "The unsoundness of the `Cell` API is publicly exposed through `AndThenService::{clone, call}`. The [code in this playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7a21d3354904c233f2e02c17ffa10fb6) exhibits MIRI detected UB from multiple unrelated `&mut First` borrows existing simultaneously while using only the safe public API of `actix-service`.\r\n\r\nRunning the code via `cargo miri` results in:\r\n\r\n```text\r\nerror: Miri evaluation error: not granting access to tag <untagged> because incompatible item is protected: [Unique for <7869> (call 4775)]\r\n --> /Users/nemo157/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-service-1.0.2/src/cell.rs:35:18\r\n |\r\n35 | unsafe { &mut *self.inner.as_ref().get() }\r\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Miri evaluation error: not granting access to tag <untagged> because incompatible item is protected: [Unique for <7869> (call 4775)]\r\n |\r\n = note: inside call to `actix_service::cell::Cell::<(First, &mut Second)>::get_mut` at /Users/nemo157/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-service-1.0.2/src/and_then.rs:54:29\r\n = note: inside call to `<actix_service::and_then::AndThenService<First, &mut Second> as actix_service::Service>::call` at /Users/nemo157/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-service-1.0.2/src/pipeline.rs:160:9\r\n```\r\n\r\n(@repnop identified that `AndThenService` allowed accessing these APIs and helped developing the PoC)"
}
},
"public": true,
"created_at": "2020-01-10T17:02:32Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11249882966",
"type": "IssueCommentEvent",
"actor": {
"id": 25030997,
"login": "JohnTitor",
"display_login": "JohnTitor",
"gravatar_id": "",
"url": "https://api.github.com/users/JohnTitor",
"avatar_url": "https://avatars.githubusercontent.com/u/25030997?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "open",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 6,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-10T19:36:13Z",
"closed_at": null,
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/573175873",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-573175873",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 573175873,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3MzE3NTg3Mw==",
"user": {
"login": "JohnTitor",
"id": 25030997,
"node_id": "MDQ6VXNlcjI1MDMwOTk3",
"avatar_url": "https://avatars3.githubusercontent.com/u/25030997?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/JohnTitor",
"html_url": "https://github.com/JohnTitor",
"followers_url": "https://api.github.com/users/JohnTitor/followers",
"following_url": "https://api.github.com/users/JohnTitor/following{/other_user}",
"gists_url": "https://api.github.com/users/JohnTitor/gists{/gist_id}",
"starred_url": "https://api.github.com/users/JohnTitor/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/JohnTitor/subscriptions",
"organizations_url": "https://api.github.com/users/JohnTitor/orgs",
"repos_url": "https://api.github.com/users/JohnTitor/repos",
"events_url": "https://api.github.com/users/JohnTitor/events{/privacy}",
"received_events_url": "https://api.github.com/users/JohnTitor/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-10T19:36:13Z",
"updated_at": "2020-01-10T19:36:13Z",
"author_association": "MEMBER",
"body": "I think it's worth to fix, re-opening."
}
},
"public": true,
"created_at": "2020-01-10T19:36:13Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11249883019",
"type": "IssuesEvent",
"actor": {
"id": 25030997,
"login": "JohnTitor",
"display_login": "JohnTitor",
"gravatar_id": "",
"url": "https://api.github.com/users/JohnTitor",
"avatar_url": "https://avatars.githubusercontent.com/u/25030997?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "reopened",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "open",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 7,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-10T19:36:13Z",
"closed_at": null,
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
}
},
"public": true,
"created_at": "2020-01-10T19:36:13Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11284548322",
"type": "IssueCommentEvent",
"actor": {
"id": 598990,
"login": "fafhrd91",
"display_login": "fafhrd91",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"avatar_url": "https://avatars.githubusercontent.com/u/598990?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "open",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 7,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-15T19:38:25Z",
"closed_at": null,
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/574821789",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-574821789",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 574821789,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3NDgyMTc4OQ==",
"user": {
"login": "fafhrd91",
"id": 598990,
"node_id": "MDQ6VXNlcjU5ODk5MA==",
"avatar_url": "https://avatars2.githubusercontent.com/u/598990?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"html_url": "https://github.com/fafhrd91",
"followers_url": "https://api.github.com/users/fafhrd91/followers",
"following_url": "https://api.github.com/users/fafhrd91/following{/other_user}",
"gists_url": "https://api.github.com/users/fafhrd91/gists{/gist_id}",
"starred_url": "https://api.github.com/users/fafhrd91/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/fafhrd91/subscriptions",
"organizations_url": "https://api.github.com/users/fafhrd91/orgs",
"repos_url": "https://api.github.com/users/fafhrd91/repos",
"events_url": "https://api.github.com/users/fafhrd91/events{/privacy}",
"received_events_url": "https://api.github.com/users/fafhrd91/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-15T19:38:25Z",
"updated_at": "2020-01-15T19:38:25Z",
"author_association": "MEMBER",
"body": "@Nemo157 @repnop nice! finally some real code!"
}
},
"public": true,
"created_at": "2020-01-15T19:38:25Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11284563284",
"type": "IssueCommentEvent",
"actor": {
"id": 4399055,
"login": "cdbattags",
"display_login": "cdbattags",
"gravatar_id": "",
"url": "https://api.github.com/users/cdbattags",
"avatar_url": "https://avatars.githubusercontent.com/u/4399055?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "open",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 8,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-15T19:40:21Z",
"closed_at": null,
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/574822585",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-574822585",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 574822585,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3NDgyMjU4NQ==",
"user": {
"login": "cdbattags",
"id": 4399055,
"node_id": "MDQ6VXNlcjQzOTkwNTU=",
"avatar_url": "https://avatars1.githubusercontent.com/u/4399055?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/cdbattags",
"html_url": "https://github.com/cdbattags",
"followers_url": "https://api.github.com/users/cdbattags/followers",
"following_url": "https://api.github.com/users/cdbattags/following{/other_user}",
"gists_url": "https://api.github.com/users/cdbattags/gists{/gist_id}",
"starred_url": "https://api.github.com/users/cdbattags/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/cdbattags/subscriptions",
"organizations_url": "https://api.github.com/users/cdbattags/orgs",
"repos_url": "https://api.github.com/users/cdbattags/repos",
"events_url": "https://api.github.com/users/cdbattags/events{/privacy}",
"received_events_url": "https://api.github.com/users/cdbattags/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-15T19:40:21Z",
"updated_at": "2020-01-15T19:40:21Z",
"author_association": "MEMBER",
"body": "Hehehe thanks @fafhrd91, @Nemo157 and @repnop!"
}
},
"public": true,
"created_at": "2020-01-15T19:40:22Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11284575979",
"type": "IssueCommentEvent",
"actor": {
"id": 598990,
"login": "fafhrd91",
"display_login": "fafhrd91",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"avatar_url": "https://avatars.githubusercontent.com/u/598990?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 10,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-15T19:41:57Z",
"closed_at": "2020-01-15T19:41:57Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/574823255",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-574823255",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 574823255,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3NDgyMzI1NQ==",
"user": {
"login": "fafhrd91",
"id": 598990,
"node_id": "MDQ6VXNlcjU5ODk5MA==",
"avatar_url": "https://avatars2.githubusercontent.com/u/598990?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"html_url": "https://github.com/fafhrd91",
"followers_url": "https://api.github.com/users/fafhrd91/followers",
"following_url": "https://api.github.com/users/fafhrd91/following{/other_user}",
"gists_url": "https://api.github.com/users/fafhrd91/gists{/gist_id}",
"starred_url": "https://api.github.com/users/fafhrd91/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/fafhrd91/subscriptions",
"organizations_url": "https://api.github.com/users/fafhrd91/orgs",
"repos_url": "https://api.github.com/users/fafhrd91/repos",
"events_url": "https://api.github.com/users/fafhrd91/events{/privacy}",
"received_events_url": "https://api.github.com/users/fafhrd91/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-15T19:41:57Z",
"updated_at": "2020-01-15T19:41:57Z",
"author_association": "MEMBER",
"body": "should be fixed in master"
}
},
"public": true,
"created_at": "2020-01-15T19:41:58Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11284576014",
"type": "IssuesEvent",
"actor": {
"id": 598990,
"login": "fafhrd91",
"display_login": "fafhrd91",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"avatar_url": "https://avatars.githubusercontent.com/u/598990?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "closed",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 10,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-15T19:41:57Z",
"closed_at": "2020-01-15T19:41:57Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
}
},
"public": true,
"created_at": "2020-01-15T19:41:58Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11284754023",
"type": "IssueCommentEvent",
"actor": {
"id": 81079,
"login": "Nemo157",
"display_login": "Nemo157",
"gravatar_id": "",
"url": "https://api.github.com/users/Nemo157",
"avatar_url": "https://avatars.githubusercontent.com/u/81079?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 10,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-15T20:05:47Z",
"closed_at": "2020-01-15T19:41:57Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/574833865",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-574833865",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 574833865,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3NDgzMzg2NQ==",
"user": {
"login": "Nemo157",
"id": 81079,
"node_id": "MDQ6VXNlcjgxMDc5",
"avatar_url": "https://avatars1.githubusercontent.com/u/81079?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Nemo157",
"html_url": "https://github.com/Nemo157",
"followers_url": "https://api.github.com/users/Nemo157/followers",
"following_url": "https://api.github.com/users/Nemo157/following{/other_user}",
"gists_url": "https://api.github.com/users/Nemo157/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Nemo157/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Nemo157/subscriptions",
"organizations_url": "https://api.github.com/users/Nemo157/orgs",
"repos_url": "https://api.github.com/users/Nemo157/repos",
"events_url": "https://api.github.com/users/Nemo157/events{/privacy}",
"received_events_url": "https://api.github.com/users/Nemo157/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-15T20:05:47Z",
"updated_at": "2020-01-15T20:05:47Z",
"author_association": "NONE",
"body": "It's possible to get around the `'static` bound by using `Arc`, [see this playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3b2cabc2ba83096418d55ecee5c71809) (I've also removed the unnecessary `&mut Second`, that was where I was trying to trigger the UB but miri caught the duplicate `&mut (First, &mut Second)` before it even got to checking the `&mut Second` itself)."
}
},
"public": true,
"created_at": "2020-01-15T20:05:47Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11284868199",
"type": "IssueCommentEvent",
"actor": {
"id": 24203105,
"login": "repnop",
"display_login": "repnop",
"gravatar_id": "",
"url": "https://api.github.com/users/repnop",
"avatar_url": "https://avatars.githubusercontent.com/u/24203105?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 11,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-15T20:21:28Z",
"closed_at": "2020-01-15T19:41:57Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/574839600",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-574839600",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 574839600,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3NDgzOTYwMA==",
"user": {
"login": "repnop",
"id": 24203105,
"node_id": "MDQ6VXNlcjI0MjAzMTA1",
"avatar_url": "https://avatars3.githubusercontent.com/u/24203105?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/repnop",
"html_url": "https://github.com/repnop",
"followers_url": "https://api.github.com/users/repnop/followers",
"following_url": "https://api.github.com/users/repnop/following{/other_user}",
"gists_url": "https://api.github.com/users/repnop/gists{/gist_id}",
"starred_url": "https://api.github.com/users/repnop/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/repnop/subscriptions",
"organizations_url": "https://api.github.com/users/repnop/orgs",
"repos_url": "https://api.github.com/users/repnop/repos",
"events_url": "https://api.github.com/users/repnop/events{/privacy}",
"received_events_url": "https://api.github.com/users/repnop/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-15T20:21:28Z",
"updated_at": "2020-01-15T20:21:28Z",
"author_association": "NONE",
"body": "its also worth noting that adding a `+ 'static` bound is a breaking change. I think ideally this should be fixed internally in a way that doesn't break the public API, especially in a patch version if possible"
}
},
"public": true,
"created_at": "2020-01-15T20:21:29Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11284887531",
"type": "IssueCommentEvent",
"actor": {
"id": 291257,
"login": "Shnatsel",
"display_login": "Shnatsel",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"avatar_url": "https://avatars.githubusercontent.com/u/291257?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 12,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-15T20:24:09Z",
"closed_at": "2020-01-15T19:41:57Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/574840595",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-574840595",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 574840595,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3NDg0MDU5NQ==",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-15T20:24:09Z",
"updated_at": "2020-01-15T20:24:09Z",
"author_association": "NONE",
"body": "Undefined behavior occurs when external code attempts to obtain two mutable references to the same data. The lifetime of the data is irrelevant to this issue.\r\n\r\nIf `Rc<RefCell>` were used instead of a custom implementation it would panic on the provided testcase instead of triggering undefined behavior. It should be possible to bring the behavior of the current implementation in line with `Rc<RefCell>`.\r\n\r\nIf panicking is undesirable, it is possible to return Option or Result from this function instead of panicking, see [`RefCell::try_borrow_mut`](https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.try_borrow_mut) for an example of such API.\r\n\r\nI wonder, what was the original rationale for migrating from `Rc<RefCell>` to a custom implementation?"
}
},
"public": true,
"created_at": "2020-01-15T20:24:09Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11285119031",
"type": "IssueCommentEvent",
"actor": {
"id": 598990,
"login": "fafhrd91",
"display_login": "fafhrd91",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"avatar_url": "https://avatars.githubusercontent.com/u/598990?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 13,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-15T20:56:23Z",
"closed_at": "2020-01-15T19:41:57Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/574852443",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-574852443",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 574852443,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3NDg1MjQ0Mw==",
"user": {
"login": "fafhrd91",
"id": 598990,
"node_id": "MDQ6VXNlcjU5ODk5MA==",
"avatar_url": "https://avatars2.githubusercontent.com/u/598990?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"html_url": "https://github.com/fafhrd91",
"followers_url": "https://api.github.com/users/fafhrd91/followers",
"following_url": "https://api.github.com/users/fafhrd91/following{/other_user}",
"gists_url": "https://api.github.com/users/fafhrd91/gists{/gist_id}",
"starred_url": "https://api.github.com/users/fafhrd91/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/fafhrd91/subscriptions",
"organizations_url": "https://api.github.com/users/fafhrd91/orgs",
"repos_url": "https://api.github.com/users/fafhrd91/repos",
"events_url": "https://api.github.com/users/fafhrd91/events{/privacy}",
"received_events_url": "https://api.github.com/users/fafhrd91/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-15T20:56:23Z",
"updated_at": "2020-01-15T20:56:23Z",
"author_association": "MEMBER",
"body": "@Nemo157 new playground panics with BorrowMutError, is that what should happen?"
}
},
"public": true,
"created_at": "2020-01-15T20:56:24Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11285133049",
"type": "IssueCommentEvent",
"actor": {
"id": 598990,
"login": "fafhrd91",
"display_login": "fafhrd91",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"avatar_url": "https://avatars.githubusercontent.com/u/598990?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 14,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-15T20:58:22Z",
"closed_at": "2020-01-15T19:41:57Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/574853149",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-574853149",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 574853149,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3NDg1MzE0OQ==",
"user": {
"login": "fafhrd91",
"id": 598990,
"node_id": "MDQ6VXNlcjU5ODk5MA==",
"avatar_url": "https://avatars2.githubusercontent.com/u/598990?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/fafhrd91",
"html_url": "https://github.com/fafhrd91",
"followers_url": "https://api.github.com/users/fafhrd91/followers",
"following_url": "https://api.github.com/users/fafhrd91/following{/other_user}",
"gists_url": "https://api.github.com/users/fafhrd91/gists{/gist_id}",
"starred_url": "https://api.github.com/users/fafhrd91/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/fafhrd91/subscriptions",
"organizations_url": "https://api.github.com/users/fafhrd91/orgs",
"repos_url": "https://api.github.com/users/fafhrd91/repos",
"events_url": "https://api.github.com/users/fafhrd91/events{/privacy}",
"received_events_url": "https://api.github.com/users/fafhrd91/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-15T20:58:22Z",
"updated_at": "2020-01-15T20:58:22Z",
"author_association": "MEMBER",
"body": "@repnop i dont see how this could be fixed internally"
}
},
"public": true,
"created_at": "2020-01-15T20:58:22Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11285192902",
"type": "IssueCommentEvent",
"actor": {
"id": 81079,
"login": "Nemo157",
"display_login": "Nemo157",
"gravatar_id": "",
"url": "https://api.github.com/users/Nemo157",
"avatar_url": "https://avatars.githubusercontent.com/u/81079?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 15,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-15T21:06:30Z",
"closed_at": "2020-01-15T19:41:57Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/574856151",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-574856151",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 574856151,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3NDg1NjE1MQ==",
"user": {
"login": "Nemo157",
"id": 81079,
"node_id": "MDQ6VXNlcjgxMDc5",
"avatar_url": "https://avatars1.githubusercontent.com/u/81079?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Nemo157",
"html_url": "https://github.com/Nemo157",
"followers_url": "https://api.github.com/users/Nemo157/followers",
"following_url": "https://api.github.com/users/Nemo157/following{/other_user}",
"gists_url": "https://api.github.com/users/Nemo157/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Nemo157/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Nemo157/subscriptions",
"organizations_url": "https://api.github.com/users/Nemo157/orgs",
"repos_url": "https://api.github.com/users/Nemo157/repos",
"events_url": "https://api.github.com/users/Nemo157/events{/privacy}",
"received_events_url": "https://api.github.com/users/Nemo157/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-15T21:06:30Z",
"updated_at": "2020-01-15T21:06:30Z",
"author_association": "NONE",
"body": "If you run the code from the playground under MIRI it fails before the `BorrowMutError` with:\r\n\r\n```\r\nerror: Miri evaluation error: not granting access to tag <untagged> because incompatible item is protected: [Unique for <7923> (call 4813)]\r\n --> /Users/nemo157/.cargo/git/checkouts/actix-net-8b378701d4b3767e/5940731/actix-service/src/cell.rs:35:18\r\n |\r\n35 | unsafe { &mut *self.inner.as_ref().get() }\r\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Miri evaluation error: not granting access to tag <untagged> because incompatible item is protected: [Unique for <7923> (call 4813)]\r\n |\r\n = note: inside call to `actix_service::cell::Cell::<(First, Second)>::get_mut` at /Users/nemo157/.cargo/git/checkouts/actix-net-8b378701d4b3767e/5940731/actix-service/src/and_then.rs:54:29\r\n = note: inside call to `<actix_service::and_then::AndThenService<First, Second> as actix_service::Service>::call` at /Users/nemo157/.cargo/git/checkouts/actix-net-8b378701d4b3767e/5940731/actix-service/src/pipeline.rs:160:9\r\n = note: inside call to `<actix_service::pipeline::Pipeline<actix_service::and_then::AndThenService<First, Second>> as actix_service::Service>::call` at src/main.rs:36:18\r\n = note: inside call to `<Second as actix_service::Service>::call` at /Users/nemo157/.cargo/git/checkouts/actix-net-8b378701d4b3767e/5940731/actix-service/src/and_then.rs:97:31\r\n = note: inside call to `<actix_service::and_then::AndThenServiceResponse<First, Second> as core::future::future::Future>::poll` at src/main.rs:55:35\r\n = note: inside call to `block_on::<actix_service::and_then::AndThenServiceResponse<First, Second>>` at src/main.rs:47:5\r\n = note: inside call to `main` at /Users/nemo157/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/src/libstd/rt.rs:67:34\r\n```\r\n\r\nbecause at this point there exist two independent `&mut (First, Second)` on the stack referencing the same tuple."
}
},
"public": true,
"created_at": "2020-01-15T21:06:30Z",
"org": {
"id": 32776943,
"login": "actix",
"gravatar_id": "",
"url": "https://api.github.com/orgs/actix",
"avatar_url": "https://avatars.githubusercontent.com/u/32776943?"
}
},
{
"id": "11290299477",
"type": "IssueCommentEvent",
"actor": {
"id": 6688948,
"login": "Restioson",
"display_login": "Restioson",
"gravatar_id": "",
"url": "https://api.github.com/users/Restioson",
"avatar_url": "https://avatars.githubusercontent.com/u/6688948?"
},
"repo": {
"id": 145325275,
"name": "actix/actix-net",
"url": "https://api.github.com/repos/actix/actix-net"
},
"payload": {
"action": "created",
"issue": {
"url": "https://api.github.com/repos/actix/actix-net/issues/83",
"repository_url": "https://api.github.com/repos/actix/actix-net",
"labels_url": "https://api.github.com/repos/actix/actix-net/issues/83/labels{/name}",
"comments_url": "https://api.github.com/repos/actix/actix-net/issues/83/comments",
"events_url": "https://api.github.com/repos/actix/actix-net/issues/83/events",
"html_url": "https://github.com/actix/actix-net/issues/83",
"id": 547007125,
"node_id": "MDU6SXNzdWU1NDcwMDcxMjU=",
"number": 83,
"title": "actix-service Cell::get_mut() is unsound",
"user": {
"login": "Shnatsel",
"id": 291257,
"node_id": "MDQ6VXNlcjI5MTI1Nw==",
"avatar_url": "https://avatars1.githubusercontent.com/u/291257?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Shnatsel",
"html_url": "https://github.com/Shnatsel",
"followers_url": "https://api.github.com/users/Shnatsel/followers",
"following_url": "https://api.github.com/users/Shnatsel/following{/other_user}",
"gists_url": "https://api.github.com/users/Shnatsel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Shnatsel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Shnatsel/subscriptions",
"organizations_url": "https://api.github.com/users/Shnatsel/orgs",
"repos_url": "https://api.github.com/users/Shnatsel/repos",
"events_url": "https://api.github.com/users/Shnatsel/events{/privacy}",
"received_events_url": "https://api.github.com/users/Shnatsel/received_events",
"type": "User",
"site_admin": false
},
"labels": [],
"state": "closed",
"locked": false,
"assignee": null,
"assignees": [],
"milestone": null,
"comments": 16,
"created_at": "2020-01-08T17:36:49Z",
"updated_at": "2020-01-16T11:52:47Z",
"closed_at": "2020-01-15T19:41:57Z",
"author_association": "NONE",
"body": "The following code is unsound:\r\n\r\nhttps://github.com/actix/actix-net/blob/7c5fa25b23a802b27e8066caf4e01e3c2cedeb35/actix-service/src/cell.rs#L34-L36\r\n\r\nThis uses `Rc::as_ref()` to obtain a reference to the underlying data, which does not guarantee uniqueness. It is possible to obtain several mutable references to the same memory location by calling this function repeatedly:\r\n\r\n```rust\r\nlet mycell = Cell::new(vec![1,2,3]);\r\nlet ref1 = mysell.get_mut();\r\nlet ref2 = mysell.get_mut(); // obtained a second mutable reference; UB starts here\r\n```\r\nThis may lead to arbitrary memory errors triggered from safe code, the most common of which would be use-after-free. These two references do not need to exist in the same function to trigger undefined behavior, they only need to exist at the same point in time.\r\n\r\nA proper way to implement `Cell:get_mut()` would be calling [Rc::get_mut()](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.get_mut) which guarantees uniqueness instead of `Rc::as_ref()`."
},
"comment": {
"url": "https://api.github.com/repos/actix/actix-net/issues/comments/575117595",
"html_url": "https://github.com/actix/actix-net/issues/83#issuecomment-575117595",
"issue_url": "https://api.github.com/repos/actix/actix-net/issues/83",
"id": 575117595,
"node_id": "MDEyOklzc3VlQ29tbWVudDU3NTExNzU5NQ==",
"user": {
"login": "Restioson",
"id": 6688948,
"node_id": "MDQ6VXNlcjY2ODg5NDg=",
"avatar_url": "https://avatars2.githubusercontent.com/u/6688948?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Restioson",
"html_url": "https://github.com/Restioson",
"followers_url": "https://api.github.com/users/Restioson/followers",
"following_url": "https://api.github.com/users/Restioson/following{/other_user}",
"gists_url": "https://api.github.com/users/Restioson/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Restioson/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Restioson/subscriptions",
"organizations_url": "https://api.github.com/users/Restioson/orgs",
"repos_url": "https://api.github.com/users/Restioson/repos",
"events_url": "https://api.github.com/users/Restioson/events{/privacy}",
"received_events_url": "https://api.github.com/users/Restioson/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2020-01-16T11:52:47Z",
"updated_at": "2020-01-16T11:52:47Z",
"author_association": "NONE",
"body": "Would it be possible to simply change it to `Rc<RefCell<T>>`? "
}
},
"public": true,
"created_at": "2020-01-16T11:52:47Z",
"org": {