rust_binder: reject context manager self-transaction
Subsystems (2)
PATCH 1/1 rust_binder: reject context manager self-transaction
Rust binder resolved handle 0 to the context manager node, but it does not reject the case where the caller owns the same node.
The C binder driver rejects transactions from the context-manager process to handle 0 after resolving the target node. Match that behavior in Rust Binder by rejecting handle 0 transactions when the resolved context-manager node is owned by the calling process.
This applies to both synchronous and oneway transactions because both paths resolve the target through Process::get_transaction_node().
--- drivers/android/binder/process.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/android/binder/process.rs +5 -1
@@ -901,7 +901,11 @@ pub(crate) fn insert_or_update_handle(pub (crate )fn get_transaction_node (&self, handle:u32 ) ->BinderResult <NodeRef > {// When handle is zero, try to get the context manager. if handle ==0 { -Ok (self.ctx.get_manager_node (true )?) +let node_ref = self.ctx.get_manager_node (true )?; +if core::ptr::eq (self, &*node_ref.node.owner) { +return Err (EINVAL .into ()); + } +Ok (node_ref) }else {Ok (self.get_node_from_handle (handle,true )?) }
Signature · 1 line
2.39.5
PATCH v2 1/1 rust_binder: reject context manager self-transaction
Rust binder resolved handle 0 to the context manager node, but it does not reject the case where the caller owns the same node.
The C binder driver rejects transactions from the context-manager process to handle 0 after resolving the target node. Match that behavior in Rust Binder by rejecting handle 0 transactions when the resolved context-manager node is owned by the calling process.
This applies to both synchronous and oneway transactions because both paths resolve the target through Process::get_transaction_node().
---
Changes in v2:
- Compare the underlying OS process task instead of Rust Binder Process object.
drivers/android/binder/process.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/android/binder/process.rs +5 -1
@@ -901,7 +901,11 @@ pub(crate) fn insert_or_update_handle(pub (crate )fn get_transaction_node (&self, handle:u32 ) ->BinderResult <NodeRef > {// When handle is zero, try to get the context manager. if handle ==0 { -Ok (self.ctx.get_manager_node (true )?) +let node_ref = self.ctx.get_manager_node (true )?; +if self.task == node_ref.node.owner.task { +return Err (EINVAL .into ()); + } +Ok (node_ref) }else {Ok (self.get_node_from_handle (handle,true )?) }
Signature · 1 line
2.39.5
Alice Ryhl
maintainerQuoted 11 lines · Keshav Verma
Rust binder resolved handle 0 to the context manager node, but it does not reject the case where the caller owns the same node.
The C binder driver rejects transactions from the context-manager process to handle 0 after resolving the target node. Match that behavior in Rust Binder by rejecting handle 0 transactions when the resolved context-manager node is owned by the calling process.
This applies to both synchronous and oneway transactions because both paths resolve the target through
Process::get_transaction_node().
Quoted 6 lines
Fixes eafedbc7c050 ("rust_binder: add Rust Binder driver")Signed-off-by Keshav Verma <[email protected]>---
Changes in v2:
- Compare the underlying OS process task instead of Rust BinderProcessobject.
I would prefer to compare the Binder Process object. Rejecting transactions between different fds owned by the same process doesn't really have any benefit and makes fuzz testing much harder.
Alice
Carlos Llamas
maintainerQuoted 19 lines · Alice Ryhl
Quoted 11 lines · Keshav Verma
Rust binder resolved handle 0 to the context manager node, but it does not reject the case where the caller owns the same node.
The C binder driver rejects transactions from the context-manager process to handle 0 after resolving the target node. Match that behavior in Rust Binder by rejecting handle 0 transactions when the resolved context-manager node is owned by the calling process.
This applies to both synchronous and oneway transactions because both paths resolve the target through
Process::get_transaction_node().Quoted 6 lines
Fixes eafedbc7c050 ("rust_binder: add Rust Binder driver")Signed-off-by Keshav Verma <[email protected]>---
Changes in v2:
- Compare the underlying OS process task instead of Rust BinderProcessobject.
Quoted 5 lines
I would prefer to compare the Binder Process object. Rejecting transactions between different fds owned by the same process doesn't really have any benefit and makes fuzz testing much harder.
Alice
Hey Alice,
The restrictions were added in the C version in order to patch vulnerabilities associated with this "self-transaction" behavior.
See: http://git.kernel.org/torvalds/c/4b836a1426cb
I haven't really looked much into this, but do we even need this for the Rust version? Is this even fixing anything at all?
--
Carlos Llamas
Alice Ryhl
maintainerQuoted 27 lines · Carlos Llamas
Quoted 19 lines · Alice Ryhl
Quoted 11 lines · Keshav Verma
Rust binder resolved handle 0 to the context manager node, but it does not reject the case where the caller owns the same node.
The C binder driver rejects transactions from the context-manager process to handle 0 after resolving the target node. Match that behavior in Rust Binder by rejecting handle 0 transactions when the resolved context-manager node is owned by the calling process.
This applies to both synchronous and oneway transactions because both paths resolve the target through
Process::get_transaction_node().Quoted 6 lines
Fixes eafedbc7c050 ("rust_binder: add Rust Binder driver")Signed-off-by Keshav Verma <[email protected]>---
Changes in v2:
- Compare the underlying OS process task instead of Rust BinderProcessobject.Quoted 5 lines
I would prefer to compare the Binder Process object. Rejecting transactions between different fds owned by the same process doesn't really have any benefit and makes fuzz testing much harder.
Alice
Quoted 8 lines
Hey Alice,
The restrictions were added in the C version in order to patch vulnerabilities associated with this "self-transaction" behavior.
See: http://git.kernel.org/torvalds/c/4b836a1426cbI haven't really looked much into this, but do we even need this for the Rust version? Is this even fixing anything at all?
Even if there's no vulnerability, self-transactions are still very weird and may introduce edge cases I can't think of. I would prefer to reject them.
Alice
PATCH v3 1/1 rust_binder: reject context manager self-transaction
In reply to Keshav VermaRust binder resolved handle 0 to the context manager node, but it does not reject the case where the caller owns the same node.
The C binder driver rejects transactions from the context-manager process to handle 0 after resolving the target node. Match that behavior in Rust Binder by rejecting handle 0 transactions when the resolved context-manager node is owned by the calling process.
This applies to both synchronous and oneway transactions because both paths resolve the target through Process::get_transaction_node().
---
Changes in v3:
- Keep the check scoped to the Binder Process object, allowing transactions between different binder fds owned by the same OS process.
Changes in v2:
- Compare the underlying OS process task instead of Rust Binder Process object.
drivers/android/binder/process.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/android/binder/process.rs +5 -1
@@ -901,7 +901,11 @@ pub(crate) fn insert_or_update_handle(pub (crate )fn get_transaction_node (&self, handle:u32 ) ->BinderResult <NodeRef > {// When handle is zero, try to get the context manager. if handle ==0 { -Ok (self.ctx.get_manager_node (true )?) +let node_ref = self.ctx.get_manager_node (true )?; +if core::ptr::eq (self, &*node_ref.node.owner) { +return Err (EINVAL .into ()); + } +Ok (node_ref) }else {Ok (self.get_node_from_handle (handle,true )?) }
Signature · 1 line
2.39.5
Quoted 8 lines · Keshav Verma
Rust binder resolved handle 0 to the context manager node, but it does not reject the case where the caller owns the same node.
The C binder driver rejects transactions from the context-manager process to handle 0 after resolving the target node. Match that behavior in Rust Binder by rejecting handle 0 transactions when the resolved context-manager node is owned by the calling process.
Quoted 6 lines
This applies to both synchronous and oneway transactions because both paths resolve the target through
Process::get_transaction_node().Fixes eafedbc7c050 ("rust_binder: add Rust Binder driver")Signed-off-by Keshav Verma <[email protected]>