mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-27 22:13:55 -04:00
rust_binder: do not query current thread for all ioctls
The get_current_thread() method is currently called for every ioctl to
ensure that a Thread struct exists for the thread calling into the
driver. However, not all ioctls require a Thread object, so this means
we are unnecessarily creating these objects in cases where we don't need
to. If said thread does not invoke BINDER_THREAD_EXIT on exit, Binder's
Thread struct stays around until the fd is closed. For long-lived
processes the Thread object is effectively leaked.
Furthermore, when the BINDER_GET_NODE_DEBUG_INFO ioctl is invoked by
libmemunreachable to ensure that objects reachable only through the
Binder driver are not considered leaked, this is done from a fork of the
process owning the fd, which means that it fails the group_leader check
inside get_current_thread(). This results in EINVAL errors for this
ioctl, causing libmemunreachable to report a false positive memory leak.
Thus, do not invoke get_current_thread() for ioctls that do not require
it.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Cc: stable <stable@kernel.org>
Fixes: eafedbc7c0 ("rust_binder: add Rust Binder driver")
Acked-by: Carlos Llamas <cmllamas@google.com>
Link: https://patch.msgid.link/20260727-binder-cur-thread-v1-1-8edf2b64e235@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
b5be879519
commit
dd7aea9ee2
@@ -1586,6 +1586,10 @@ fn ioctl_write_only(
|
||||
cmd: u32,
|
||||
reader: &mut UserSliceReader,
|
||||
) -> Result {
|
||||
if cmd == uapi::BINDER_FREEZE {
|
||||
return ioctl_freeze(reader);
|
||||
}
|
||||
|
||||
let thread = this.get_current_thread()?;
|
||||
match cmd {
|
||||
uapi::BINDER_SET_MAX_THREADS => this.set_max_threads(reader.read()?),
|
||||
@@ -1597,7 +1601,6 @@ fn ioctl_write_only(
|
||||
uapi::BINDER_ENABLE_ONEWAY_SPAM_DETECTION => {
|
||||
this.set_oneway_spam_detection_enabled(reader.read()?)
|
||||
}
|
||||
uapi::BINDER_FREEZE => ioctl_freeze(reader)?,
|
||||
_ => return Err(EINVAL),
|
||||
}
|
||||
Ok(())
|
||||
@@ -1612,15 +1615,16 @@ fn ioctl_write_read(
|
||||
cmd: u32,
|
||||
data: UserSlice,
|
||||
) -> Result {
|
||||
let thread = this.get_current_thread()?;
|
||||
let blocking = (file.flags() & file::flags::O_NONBLOCK) == 0;
|
||||
match cmd {
|
||||
uapi::BINDER_WRITE_READ => thread.write_read(data, blocking)?,
|
||||
uapi::BINDER_WRITE_READ => this.get_current_thread()?.write_read(data, blocking)?,
|
||||
uapi::BINDER_GET_NODE_DEBUG_INFO => this.get_node_debug_info(data)?,
|
||||
uapi::BINDER_GET_NODE_INFO_FOR_REF => this.get_node_info_from_ref(data)?,
|
||||
uapi::BINDER_VERSION => this.version(data)?,
|
||||
uapi::BINDER_GET_FROZEN_INFO => get_frozen_status(data)?,
|
||||
uapi::BINDER_GET_EXTENDED_ERROR => thread.get_extended_error(data)?,
|
||||
uapi::BINDER_GET_EXTENDED_ERROR => {
|
||||
this.get_current_thread()?.get_extended_error(data)?
|
||||
}
|
||||
_ => return Err(EINVAL),
|
||||
}
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user