- Oct 29, 2020
-
-
Todd Kjos authored
commit f3277cbf upstream. When releasing a thread todo list when tearing down a binder_proc, the following race was possible which could result in a use-after-free: 1. Thread 1: enter binder_release_work from binder_thread_release 2. Thread 2: binder_update_ref_for_handle() -> binder_dec_node_ilocked() 3. Thread 2: dec nodeA --> 0 (will free node) 4. Thread 1: ACQ inner_proc_lock 5. Thread 2: block on inner_proc_lock 6. Thread 1: dequeue work (BINDER_WORK_NODE, part of nodeA) 7. Thread 1: REL inner_proc_lock 8. Thread 2: ACQ inner_proc_lock 9. Thread 2: todo list cleanup, but work was already dequeued 10. Thread 2: free node 11. Thread 2: REL inner_proc_lock 12. Thread 1: deref w->type (UAF) The problem was that for a BINDER_WORK_NODE, the binder_work element must not be accessed after releasing the inner_proc_lock while processing the todo list elements since another thread might be handling a deref on the node containing the binder_work element leading to the node being freed. Signed-off-by:
Todd Kjos <tkjos@google.com> Link: https://lore.kernel.org/r/20201009232455.4054810-1-tkjos@google.com Cc: <stable@vger.kernel.org> # 4.14, 4.19, 5.4, 5.8 Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Aug 21, 2020
-
-
Jann Horn authored
commit 4b836a14 upstream. Binder is designed such that a binder_proc never has references to itself. If this rule is violated, memory corruption can occur when a process sends a transaction to itself; see e.g. <https://syzkaller.appspot.com/bug?extid=09e05aba06723a94d43d >. There is a remaining edgecase through which such a transaction-to-self can still occur from the context of a task with BINDER_SET_CONTEXT_MGR access: - task A opens /dev/binder twice, creating binder_proc instances P1 and P2 - P1 becomes context manager - P2 calls ACQUIRE on the magic handle 0, allocating index 0 in its handle table - P1 dies (by closing the /dev/binder fd and waiting a bit) - P2 becomes context manager - P2 calls ACQUIRE on the magic handle 0, allocating index 1 in its handle table [this triggers a warning: "binder: 1974:1974 tried to acquire reference to desc 0, got 1 instead"] - task B opens /dev/binder once, creating binder_proc instance P3 - P3 calls P2 (via magic handle 0) with (void*)1 as argument (two-way transaction) - P2 receives the handle and uses it to call P3 (two-way transaction) - P3 calls P2 (via magic handle 0) (two-way transaction) - P2 calls P2 (via handle 1) (two-way transaction) And then, if P2 does *NOT* accept the incoming transaction work, but instead closes the binder fd, we get a crash. Solve it by preventing the context manager from using ACQUIRE on ref 0. There shouldn't be any legitimate reason for the context manager to do that. Additionally, print a warning if someone manages to find another way to trigger a transaction-to-self bug in the future. Cc: stable@vger.kernel.org Fixes: 457b9a6f ("Staging: android: add binder driver") Acked-by:
Todd Kjos <tkjos@google.com> Signed-off-by:
Jann Horn <jannh@google.com> Reviewed-by:
Martijn Coenen <maco@android.com> Link: https://lore.kernel.org/r/20200727120424.1627555-1-jannh@google.com Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Aug 04, 2019
-
-
Todd Kjos authored
commit a370003c upstream. There is a race between the binder driver cleaning up a completed transaction via binder_free_transaction() and a user calling binder_ioctl(BC_FREE_BUFFER) to release a buffer. It doesn't matter which is first but they need to be protected against running concurrently which can result in a UAF. Signed-off-by:
Todd Kjos <tkjos@google.com> Cc: stable <stable@vger.kernel.org> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Jul 31, 2019
-
-
Hridya Valsaraju authored
commit 49ed9694 upstream. Currently, a transaction to context manager from its own process is prevented by checking if its binder_proc struct is the same as that of the sender. However, this would not catch cases where the process opens the binder device again and uses the new fd to send a transaction to the context manager. Reported-by:
<syzbot+8b3c354d33c4ac78bfad@syzkaller.appspotmail.com> Signed-off-by:
Hridya Valsaraju <hridya@google.com> Acked-by:
Todd Kjos <tkjos@google.com> Cc: stable <stable@vger.kernel.org> Link: https://lore.kernel.org/r/20190715191804.112933-1-hridya@google.com Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Jul 21, 2019
-
-
Todd Kjos authored
commit 1909a671 upstream. syzkallar found a 32-byte memory leak in a rarely executed error case. The transaction complete work item was not freed if put_user() failed when writing the BR_TRANSACTION_COMPLETE to the user command buffer. Fixed by freeing it before put_user() is called. Reported-by:
<syzbot+182ce46596c3f2e1eb24@syzkaller.appspotmail.com> Signed-off-by:
Todd Kjos <tkjos@google.com> Cc: stable <stable@vger.kernel.org> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Dec 05, 2018
-
-
Todd Kjos authored
commit 7bada55a upstream. Malicious code can attempt to free buffers using the BC_FREE_BUFFER ioctl to binder. There are protections against a user freeing a buffer while in use by the kernel, however there was a window where BC_FREE_BUFFER could be used to free a recently allocated buffer that was not completely initialized. This resulted in a use-after-free detected by KASAN with a malicious test program. This window is closed by setting the buffer's allow_user_free attribute to 0 when the buffer is allocated or when the user has previously freed it instead of waiting for the caller to set it. The problem was that when the struct buffer was recycled, allow_user_free was stale and set to 1 allowing a free to go through. Signed-off-by:
Todd Kjos <tkjos@google.com> Acked-by:
Arve Hjønnevåg <arve@android.com> Cc: stable <stable@vger.kernel.org> # 4.14 Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- May 01, 2018
-
-
Martijn Coenen authored
commit 7aa135fc upstream. This can't happen with normal nodes (because you can't get a ref to a node you own), but it could happen with the context manager; to make the behavior consistent with regular nodes, reject transactions into the context manager by the process owning it. Reported-by:
<syzbot+09e05aba06723a94d43d@syzkaller.appspotmail.com> Signed-off-by:
Martijn Coenen <maco@android.com> Cc: stable <stable@vger.kernel.org> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Feb 25, 2018
-
-
Todd Kjos authored
commit 8ca86f16 upstream. The format specifier "%p" can leak kernel addresses. Use "%pK" instead. There were 4 remaining cases in binder.c. Signed-off-by:
Todd Kjos <tkjos@google.com> Cc: stable <stable@vger.kernel.org> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Eric Biggers authored
commit f8898267 upstream. If the kzalloc() in binder_get_thread() fails, binder_poll() dereferences the resulting NULL pointer. Fix it by returning POLLERR if the memory allocation failed. This bug was found by syzkaller using fault injection. Reported-by:
syzbot <syzkaller@googlegroups.com> Fixes: 457b9a6f ("Staging: android: add binder driver") Cc: stable@vger.kernel.org Signed-off-by:
Eric Biggers <ebiggers@google.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Martijn Coenen authored
commit 5eeb2ca0 upstream. To prevent races with ep_remove_waitqueue() removing the waitqueue at the same time. Reported-by:
<syzbot+a2a3c4909716e271487e@syzkaller.appspotmail.com> Signed-off-by:
Martijn Coenen <maco@android.com> Cc: stable <stable@vger.kernel.org> # 4.14+ Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Todd Kjos authored
commit e46a3b3b upstream. binder_send_failed_reply() is called when a synchronous transaction fails. It reports an error to the thread that is waiting for the completion. Given that the transaction is synchronous, there should never be more than 1 error response to that thread -- this was being asserted with a WARN(). However, when exercising the driver with syzbot tests, cases were observed where multiple "synchronous" requests were sent without waiting for responses, so it is possible that multiple errors would be reported to the thread. This testing was conducted with panic_on_warn set which forced the crash. This is easily reproduced by sending back-to-back "synchronous" transactions without checking for any response (eg, set read_size to 0): bwr.write_buffer = (uintptr_t)&bc1; bwr.write_size = sizeof(bc1); bwr.read_buffer = (uintptr_t)&br; bwr.read_size = 0; ioctl(fd, BINDER_WRITE_READ, &bwr); sleep(1); bwr2.write_buffer = (uintptr_t)&bc2; bwr2.write_size = sizeof(bc2); bwr2.read_buffer = (uintptr_t)&br; bwr2.read_size = 0; ioctl(fd, BINDER_WRITE_READ, &bwr2); sleep(1); The first transaction is sent to the servicemanager and the reply fails because no VMA is set up by this client. After binder_send_failed_reply() is called, the BINDER_WORK_RETURN_ERROR is sitting on the thread's todo list since the read_size was 0 and the client is not waiting for a response. The 2nd transaction is sent and the BINDER_WORK_RETURN_ERROR has not been consumed, so the thread's reply_error.cmd is still set (normally cleared when the BINDER_WORK_RETURN_ERROR is handled). Therefore when the servicemanager attempts to reply to the 2nd failed transaction, the error is already set and it triggers this warning. This is a user error since it is not waiting for the synchronous transaction to complete. If it ever does check, it will see an error. Changed the WARN() to a pr_warn(). Signed-off-by:
Todd Kjos <tkjos@android.com> Reported-by:
syzbot <syzkaller@googlegroups.com> Cc: stable <stable@vger.kernel.org> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Feb 03, 2018
-
-
Martijn Coenen authored
commit f5cb779b upstream. binder_poll() passes the thread->wait waitqueue that can be slept on for work. When a thread that uses epoll explicitly exits using BINDER_THREAD_EXIT, the waitqueue is freed, but it is never removed from the corresponding epoll data structure. When the process subsequently exits, the epoll cleanup code tries to access the waitlist, which results in a use-after-free. Prevent this by using POLLFREE when the thread exits. Signed-off-by:
Martijn Coenen <maco@android.com> Reported-by:
syzbot <syzkaller@googlegroups.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Jan 02, 2018
-
-
Todd Kjos authored
commit 7f3dc008 upstream. proc->files cleanup is initiated by binder_vma_close. Therefore a reference on the binder_proc is not enough to prevent the files_struct from being released while the binder_proc still has a reference. This can lead to an attempt to dereference the stale pointer obtained from proc->files prior to proc->files cleanup. This has been seen once in task_get_unused_fd_flags() when __alloc_fd() is called with a stale "files". The fix is to protect proc->files with a mutex to prevent cleanup while in use. Signed-off-by:
Todd Kjos <tkjos@google.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Dec 10, 2017
-
-
Martijn Coenen authored
commit fb2c4452 upstream. If a call to put_user() fails, we failed to properly free a transaction and send a failed reply (if necessary). Signed-off-by:
Martijn Coenen <maco@android.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Oct 20, 2017
-
-
Martijn Coenen authored
Because we're not guaranteed that subsequent calls to poll() will have a poll_table_struct parameter with _qproc set. When _qproc is not set, poll_wait() is a noop, and we won't be woken up correctly. Signed-off-by:
Martijn Coenen <maco@android.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Oct 04, 2017
-
-
Todd Kjos authored
User-space normally keeps the node alive when creating a transaction since it has a reference to the target. The local strong ref keeps it alive if the sending process dies before the target process processes the transaction. If the source process is malicious or has a reference counting bug, this can fail. In this case, when we attempt to decrement the node in the failure path, the node has already been freed. This is fixed by taking a tmpref on the node while constructing the transaction. To avoid re-acquiring the node lock and inner proc lock to increment the proc's tmpref, a helper is used that does the ref increments on both the node and proc. Signed-off-by:
Todd Kjos <tkjos@google.com> Cc: stable <stable@vger.kernel.org> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Sep 18, 2017
-
-
Xu YiPing authored
commit 7a4408c6 ("binder: make sure accesses to proc/thread are safe") made a change to enqueue tcomplete to thread->todo before enqueuing the transaction. However, in err_dead_proc_or_thread case, the tcomplete is directly freed, without dequeued. It may cause the thread->todo list to be corrupted. So, dequeue it before freeing. Fixes: 7a4408c6 ("binder: make sure accesses to proc/thread are safe") Signed-off-by:
Xu YiPing <xuyiping@hisilicon.com> Signed-off-by:
Todd Kjos <tkjos@google.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Xu YiPing authored
commit 372e3147 ("binder: guarantee txn complete / errors delivered in-order") incorrectly defined a local ret value. This ret value will be invalid when out of the if block Fixes: 372e3147 ("binder: refactor binder ref inc/dec for thread safety") Signed-off-by:
Xu YiPing <xuyiping@hislicon.com> Signed-off-by:
Todd Kjos <tkjos@google.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Arnd Bergmann authored
Allowing binder to expose the 64-bit API on 32-bit kernels caused a build warning: drivers/android/binder.c: In function 'binder_transaction_buffer_release': drivers/android/binder.c:2220:15: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] fd_array = (u32 *)(parent_buffer + fda->parent_offset); ^ drivers/android/binder.c: In function 'binder_translate_fd_array': drivers/android/binder.c:2445:13: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] fd_array = (u32 *)(parent_buffer + fda->parent_offset); ^ drivers/android/binder.c: In function 'binder_fixup_parent': drivers/android/binder.c:2511:18: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] This adds extra type casts to avoid the warning. However, there is another problem with the Kconfig option: turning it on or off creates two incompatible ABI versions, a kernel that has this enabled cannot run user space that was built without it or vice versa. A better solution might be to leave the option hidden until the binder code is fixed to deal with both ABI versions. Fixes: e8d2ed7d ("Revert "staging: Fix build issues with new binder API"") Signed-off-by:
Arnd Bergmann <arnd@arndb.de> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Sep 01, 2017
-
-
Martijn Coenen authored
This can cause issues with processes using the poll() interface: 1) client sends two oneway transactions 2) the second one gets queued on async_todo (because the server didn't handle the first one yet) 3) server returns from poll(), picks up the first transaction and does transaction work 4) server is done with the transaction, sends BC_FREE_BUFFER, and the second transaction gets moved to thread->todo 5) libbinder's handlePolledCommands() only handles the commands in the current data buffer, so doesn't see the new transaction 6) the server continues running and issues a new outgoing transaction. Now, it suddenly finds the incoming oneway transaction on its thread todo, and returns that to userspace. 7) userspace does not expect this to happen; it may be holding a lock while making the outgoing transaction, and if handling the incoming trasnaction requires taking the same lock, userspace will deadlock. By queueing the async transaction to the proc workqueue, we make sure it's only picked up when a thread is ready for proc work. Signed-off-by:
Martijn Coenen <maco@android.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Martijn Coenen authored
This allows userspace to request death notifications without having to worry about getting an immediate callback on the same thread; one scenario where this would be problematic is if the death recipient handler grabs a lock that was already taken earlier (eg as part of a nested transaction). Signed-off-by:
Martijn Coenen <maco@android.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Martijn Coenen authored
Because is_spin_locked() always returns false on UP systems. Use assert_spin_locked() instead, and remove the WARN_ON() instances, since those were easy to verify. Signed-off-by:
Martijn Coenen <maco@android.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Colin Cross authored
The BINDER_GET_NODE_DEBUG_INFO ioctl will return debug info on a node. Each successive call reusing the previous return value will return the next node. The data will be used by libmemunreachable to mark the pointers with kernel references as reachable. Signed-off-by:
Colin Cross <ccross@android.com> Signed-off-by:
Martijn Coenen <maco@android.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Martijn Coenen authored
Instead of pushing new transactions to the process waitqueue, select a thread that is waiting on proc work to handle the transaction. This will make it easier to improve priority inheritance in future patches, by setting the priority before we wake up a thread. If we can't find a waiting thread, submit the work to the proc waitqueue instead as we did previously. Signed-off-by:
Martijn Coenen <maco@android.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Martijn Coenen authored
Removes the process waitqueue, so that threads can only wait on the thread waitqueue. Whenever there is process work to do, pick a thread and wake it up. Having the caller pick a thread is helpful for things like priority inheritance. This also fixes an issue with using epoll(), since we no longer have to block on different waitqueues. Signed-off-by:
Martijn Coenen <maco@android.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Sherry Yang authored
Add the number of active, lru, and free pages for each binder process in binder stats Signed-off-by:
Sherry Yang <sherryy@android.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Aug 28, 2017
-
-
Sherry Yang authored
Hold on to the pages allocated and mapped for transaction buffers until the system is under memory pressure. When that happens, use linux shrinker to free pages. Without using shrinker, patch "android: binder: Move buffer out of area shared with user space" will cause a significant slow down for small transactions that fit into the first page because free list buffer header used to be inlined with buffer data. In addition to prevent the performance regression for small transactions, this patch improves the performance for transactions that take up more than one page. Modify alloc selftest to work with the shrinker change. Test: Run memory intensive applications (Chrome and Camera) to trigger shrinker callbacks. Binder frees memory as expected. Test: Run binderThroughputTest with high memory pressure option enabled. Signed-off-by:
Sherry Yang <sherryy@android.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Sherry Yang authored
binder_alloc_selftest tests that alloc_new_buf handles page allocation and deallocation properly when allocate and free buffers. The test allocates 5 buffers of various sizes to cover all possible page alignment cases, and frees the buffers using a list of exhaustive freeing order. Test: boot the device with ANDROID_BINDER_IPC_SELFTEST config option enabled. Allocator selftest passes. Signed-off-by:
Sherry Yang <sherryy@android.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Aug 23, 2017
-
-
Todd Kjos authored
commit 26549d17 ("binder: guarantee txn complete / errors delivered in-order") passed the locally declared and undefined cmd to binder_stat_br() which results in a bogus cmd field in a trace event and BR stats are incremented incorrectly. Change to use e->cmd which has been initialized. Signed-off-by:
Todd Kjos <tkjos@google.com> Reported-by:
Dan Carpenter <dan.carpenter@oracle.com> Fixes: 26549d17 ("binder: guarantee txn complete / errors delivered in-order") Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Christian Brauner authored
On binder_init() the devices string is duplicated and smashed into individual device names which are passed along. However, the original duplicated string wasn't freed in case binder_init() failed. Let's free it on error. Signed-off-by:
Christian Brauner <christian.brauner@ubuntu.com> Cc: stable <stable@vger.kernel.org> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Martijn Coenen authored
Commit c4ea41ba ("binder: use group leader instead of open thread")' was incomplete and didn't update a check in binder_mmap(), causing all mmap() calls into the binder driver to fail. Signed-off-by:
Martijn Coenen <maco@android.com> Tested-by:
John Stultz <john.stultz@linaro.org> Cc: stable <stable@vger.kernel.org> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
- Jul 17, 2017
-
-
Dmitry Safonov authored
It was never used since addition of binder to linux mainstream tree. Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: "Arve Hjønnevåg" <arve@android.com> Cc: Riley Andrews <riandrews@android.com> Cc: devel@driverdev.osuosl.org Signed-off-by:
Dmitry Safonov <dsafonov@virtuozzo.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Krzysztof Opasiak authored
Use rlimit() helper instead of manually writing whole chain from current task to rlim_cur Signed-off-by:
Krzysztof Opasiak <k.opasiak@samsung.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Todd Kjos authored
Remove global mutex and rely on fine-grained locking Signed-off-by:
Todd Kjos <tkjos@google.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Martijn Coenen authored
A race existed where one thread could register a death notification for a node, while another thread was cleaning up that node and sending out death notifications for its references, causing simultaneous access to ref->death because different locks were held. Signed-off-by:
Martijn Coenen <maco@google.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Todd Kjos authored
When printing transactions there were several race conditions that could cause a stale pointer to be deferenced. Fixed by reading the pointer once and using it if valid (which is safe). The transaction buffer also needed protection via proc lock, so it is only printed if we are holding the correct lock. Signed-off-by:
Todd Kjos <tkjos@google.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Todd Kjos authored
Use proc->outer_lock to protect the binder_ref structure. The outer lock allows functions operating on the binder_ref to do nested acquires of node and inner locks as necessary to attach refs to nodes atomically. Binder refs must never be accesssed without holding the outer lock. Signed-off-by:
Todd Kjos <tkjos@google.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Todd Kjos authored
Use the inner lock to protect thread accounting fields in proc structure: max_threads, requested_threads, requested_threads_started and ready_threads. Signed-off-by:
Todd Kjos <tkjos@google.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Martijn Coenen authored
This makes future changes to priority inheritance easier, since we want to be able to look at a thread's transaction stack when selecting a thread to inherit priority for. It also allows us to take just a single lock in a few paths, where we used to take two in succession. Signed-off-by:
Martijn Coenen <maco@google.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Todd Kjos authored
proc->threads will need to be accessed with higher locks of other processes held so use proc->inner_lock to protect it. proc->tmp_ref now needs to be protected by proc->inner_lock. Signed-off-by:
Todd Kjos <tkjos@google.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-