Loading drivers/android/binder.c +131 −49 Original line number Diff line number Diff line Loading @@ -406,6 +406,7 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) struct files_struct *files = proc->files; unsigned long rlim_cur; unsigned long irqs; int ret; if (files == NULL) return -ESRCH; Loading @@ -416,7 +417,11 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE); unlock_task_sighand(proc->tsk, &irqs); return __alloc_fd(files, 0, rlim_cur, flags); preempt_enable_no_resched(); ret = __alloc_fd(files, 0, rlim_cur, flags); preempt_disable(); return ret; } /* Loading @@ -425,8 +430,11 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) static void task_fd_install( struct binder_proc *proc, unsigned int fd, struct file *file) { if (proc->files) if (proc->files) { preempt_enable_no_resched(); __fd_install(proc->files, fd, file); preempt_disable(); } } /* Loading Loading @@ -454,6 +462,7 @@ static inline void binder_lock(const char *tag) { trace_binder_lock(tag); mutex_lock(&binder_main_lock); preempt_disable(); trace_binder_locked(tag); } Loading @@ -461,8 +470,62 @@ static inline void binder_unlock(const char *tag) { trace_binder_unlock(tag); mutex_unlock(&binder_main_lock); preempt_enable(); } static inline void *kzalloc_preempt_disabled(size_t size) { void *ptr; ptr = kzalloc(size, GFP_NOWAIT); if (ptr) return ptr; preempt_enable_no_resched(); ptr = kzalloc(size, GFP_KERNEL); preempt_disable(); return ptr; } static inline long copy_to_user_preempt_disabled(void __user *to, const void *from, long n) { long ret; preempt_enable_no_resched(); ret = copy_to_user(to, from, n); preempt_disable(); return ret; } static inline long copy_from_user_preempt_disabled(void *to, const void __user *from, long n) { long ret; preempt_enable_no_resched(); ret = copy_from_user(to, from, n); preempt_disable(); return ret; } #define get_user_preempt_disabled(x, ptr) \ ({ \ int __ret; \ preempt_enable_no_resched(); \ __ret = get_user(x, ptr); \ preempt_disable(); \ __ret; \ }) #define put_user_preempt_disabled(x, ptr) \ ({ \ int __ret; \ preempt_enable_no_resched(); \ __ret = put_user(x, ptr); \ preempt_disable(); \ __ret; \ }) static void binder_set_nice(long nice) { long min_nice; Loading Loading @@ -595,6 +658,8 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, else mm = get_task_mm(proc->tsk); preempt_enable_no_resched(); if (mm) { down_write(&mm->mmap_sem); vma = proc->vma; Loading Loading @@ -649,6 +714,9 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, up_write(&mm->mmap_sem); mmput(mm); } preempt_disable(); return 0; free_range: Loading @@ -671,6 +739,9 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, up_write(&mm->mmap_sem); mmput(mm); } preempt_disable(); return -ENOMEM; } Loading Loading @@ -939,7 +1010,7 @@ static struct binder_node *binder_new_node(struct binder_proc *proc, return NULL; } node = kzalloc(sizeof(*node), GFP_KERNEL); node = kzalloc_preempt_disabled(sizeof(*node)); if (node == NULL) return NULL; binder_stats_created(BINDER_STAT_NODE); Loading Loading @@ -1083,7 +1154,7 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, else return ref; } new_ref = kzalloc(sizeof(*ref), GFP_KERNEL); new_ref = kzalloc_preempt_disabled(sizeof(*ref)); if (new_ref == NULL) return NULL; binder_stats_created(BINDER_STAT_REF); Loading Loading @@ -1955,14 +2026,14 @@ static void binder_transaction(struct binder_proc *proc, e->to_proc = target_proc->pid; /* TODO: reuse incoming transaction for reply */ t = kzalloc(sizeof(*t), GFP_KERNEL); t = kzalloc_preempt_disabled(sizeof(*t)); if (t == NULL) { return_error = BR_FAILED_REPLY; goto err_alloc_t_failed; } binder_stats_created(BINDER_STAT_TRANSACTION); tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL); tcomplete = kzalloc_preempt_disabled(sizeof(*tcomplete)); if (tcomplete == NULL) { return_error = BR_FAILED_REPLY; goto err_alloc_tcomplete_failed; Loading Loading @@ -2023,14 +2094,14 @@ static void binder_transaction(struct binder_proc *proc, ALIGN(tr->data_size, sizeof(void *))); offp = off_start; if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t) if (copy_from_user_preempt_disabled(t->buffer->data, (const void __user *)(uintptr_t) tr->data.ptr.buffer, tr->data_size)) { binder_user_error("%d:%d got transaction with invalid data ptr\n", proc->pid, thread->pid); return_error = BR_FAILED_REPLY; goto err_copy_data_failed; } if (copy_from_user(offp, (const void __user *)(uintptr_t) if (copy_from_user_preempt_disabled(offp, (const void __user *)(uintptr_t) tr->data.ptr.offsets, tr->offsets_size)) { binder_user_error("%d:%d got transaction with invalid offsets ptr\n", proc->pid, thread->pid); Loading Loading @@ -2148,7 +2219,8 @@ static void binder_transaction(struct binder_proc *proc, return_error = BR_FAILED_REPLY; goto err_bad_offset; } if (copy_from_user(sg_bufp, if (copy_from_user_preempt_disabled( sg_bufp, (const void __user *)(uintptr_t) bp->buffer, bp->length)) { binder_user_error("%d:%d got transaction with invalid offsets ptr\n", Loading Loading @@ -2257,7 +2329,7 @@ static int binder_thread_write(struct binder_proc *proc, void __user *end = buffer + size; while (ptr < end && thread->return_error == BR_OK) { if (get_user(cmd, (uint32_t __user *)ptr)) if (get_user_preempt_disabled(cmd, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); trace_binder_command(cmd); Loading @@ -2275,7 +2347,7 @@ static int binder_thread_write(struct binder_proc *proc, struct binder_ref *ref; const char *debug_string; if (get_user(target, (uint32_t __user *)ptr)) if (get_user_preempt_disabled(target, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); if (target == 0 && context->binder_context_mgr_node && Loading Loading @@ -2327,10 +2399,10 @@ static int binder_thread_write(struct binder_proc *proc, binder_uintptr_t cookie; struct binder_node *node; if (get_user(node_ptr, (binder_uintptr_t __user *)ptr)) if (get_user_preempt_disabled(node_ptr, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); if (get_user(cookie, (binder_uintptr_t __user *)ptr)) if (get_user_preempt_disabled(cookie, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); node = binder_get_node(proc, node_ptr); Loading Loading @@ -2388,7 +2460,7 @@ static int binder_thread_write(struct binder_proc *proc, binder_uintptr_t data_ptr; struct binder_buffer *buffer; if (get_user(data_ptr, (binder_uintptr_t __user *)ptr)) if (get_user_preempt_disabled(data_ptr, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); Loading Loading @@ -2430,7 +2502,8 @@ static int binder_thread_write(struct binder_proc *proc, case BC_REPLY_SG: { struct binder_transaction_data_sg tr; if (copy_from_user(&tr, ptr, sizeof(tr))) if (copy_from_user_preempt_disabled(&tr, ptr, sizeof(tr))) return -EFAULT; ptr += sizeof(tr); binder_transaction(proc, thread, &tr.transaction_data, Loading @@ -2441,7 +2514,7 @@ static int binder_thread_write(struct binder_proc *proc, case BC_REPLY: { struct binder_transaction_data tr; if (copy_from_user(&tr, ptr, sizeof(tr))) if (copy_from_user_preempt_disabled(&tr, ptr, sizeof(tr))) return -EFAULT; ptr += sizeof(tr); binder_transaction(proc, thread, &tr, Loading Loading @@ -2492,10 +2565,10 @@ static int binder_thread_write(struct binder_proc *proc, struct binder_ref *ref; struct binder_ref_death *death; if (get_user(target, (uint32_t __user *)ptr)) if (get_user_preempt_disabled(target, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); if (get_user(cookie, (binder_uintptr_t __user *)ptr)) if (get_user_preempt_disabled(cookie, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); ref = binder_get_ref(proc, target, false); Loading Loading @@ -2524,7 +2597,7 @@ static int binder_thread_write(struct binder_proc *proc, proc->pid, thread->pid); break; } death = kzalloc(sizeof(*death), GFP_KERNEL); death = kzalloc_preempt_disabled(sizeof(*death)); if (death == NULL) { thread->return_error = BR_ERROR; binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, Loading Loading @@ -2578,8 +2651,7 @@ static int binder_thread_write(struct binder_proc *proc, struct binder_work *w; binder_uintptr_t cookie; struct binder_ref_death *death = NULL; if (get_user(cookie, (binder_uintptr_t __user *)ptr)) if (get_user_preempt_disabled(cookie, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(cookie); Loading Loading @@ -2611,7 +2683,8 @@ static int binder_thread_write(struct binder_proc *proc, wake_up_interruptible(&proc->wait); } } } break; } break; default: pr_err("%d:%d unknown command %d\n", Loading Loading @@ -2660,7 +2733,7 @@ static int binder_thread_read(struct binder_proc *proc, int wait_for_proc_work; if (*consumed == 0) { if (put_user(BR_NOOP, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(BR_NOOP, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); } Loading @@ -2671,7 +2744,7 @@ static int binder_thread_read(struct binder_proc *proc, if (thread->return_error != BR_OK && ptr < end) { if (thread->return_error2 != BR_OK) { if (put_user(thread->return_error2, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(thread->return_error2, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); binder_stat_br(proc, thread, thread->return_error2); Loading @@ -2679,7 +2752,7 @@ static int binder_thread_read(struct binder_proc *proc, goto done; thread->return_error2 = BR_OK; } if (put_user(thread->return_error, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(thread->return_error, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); binder_stat_br(proc, thread, thread->return_error); Loading Loading @@ -2757,7 +2830,7 @@ static int binder_thread_read(struct binder_proc *proc, } break; case BINDER_WORK_TRANSACTION_COMPLETE: { cmd = BR_TRANSACTION_COMPLETE; if (put_user(cmd, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(cmd, (uint32_t __user *) ptr)) return -EFAULT; ptr += sizeof(uint32_t); Loading Loading @@ -2799,14 +2872,14 @@ static int binder_thread_read(struct binder_proc *proc, node->has_weak_ref = 0; } if (cmd != BR_NOOP) { if (put_user(cmd, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(cmd, (uint32_t __user *) ptr)) return -EFAULT; ptr += sizeof(uint32_t); if (put_user(node->ptr, if (put_user_preempt_disabled(node->ptr, (binder_uintptr_t __user *) (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); if (put_user(node->cookie, if (put_user_preempt_disabled(node->cookie, (binder_uintptr_t __user *) (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); Loading Loading @@ -2850,11 +2923,10 @@ static int binder_thread_read(struct binder_proc *proc, cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE; else cmd = BR_DEAD_BINDER; if (put_user(cmd, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(cmd, (uint32_t __user *) ptr)) return -EFAULT; ptr += sizeof(uint32_t); if (put_user(death->cookie, (binder_uintptr_t __user *)ptr)) if (put_user_preempt_disabled(death->cookie, (binder_uintptr_t __user *) ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); binder_stat_br(proc, thread, cmd); Loading Loading @@ -2921,10 +2993,10 @@ static int binder_thread_read(struct binder_proc *proc, ALIGN(t->buffer->data_size, sizeof(void *)); if (put_user(cmd, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(cmd, (uint32_t __user *) ptr)) return -EFAULT; ptr += sizeof(uint32_t); if (copy_to_user(ptr, &tr, sizeof(tr))) if (copy_to_user_preempt_disabled(ptr, &tr, sizeof(tr))) return -EFAULT; ptr += sizeof(tr); Loading Loading @@ -2966,7 +3038,7 @@ static int binder_thread_read(struct binder_proc *proc, binder_debug(BINDER_DEBUG_THREADS, "%d:%d BR_SPAWN_LOOPER\n", proc->pid, thread->pid); if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer)) if (put_user_preempt_disabled(BR_SPAWN_LOOPER, (uint32_t __user *) buffer)) return -EFAULT; binder_stat_br(proc, thread, BR_SPAWN_LOOPER); } Loading Loading @@ -3041,7 +3113,7 @@ static struct binder_thread *binder_get_thread(struct binder_proc *proc) break; } if (*p == NULL) { thread = kzalloc(sizeof(*thread), GFP_KERNEL); thread = kzalloc_preempt_disabled(sizeof(*thread)); if (thread == NULL) return NULL; binder_stats_created(BINDER_STAT_THREAD); Loading Loading @@ -3145,7 +3217,7 @@ static int binder_ioctl_write_read(struct file *filp, ret = -EINVAL; goto out; } if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { if (copy_from_user_preempt_disabled(&bwr, ubuf, sizeof(bwr))) { ret = -EFAULT; goto out; } Loading @@ -3163,7 +3235,7 @@ static int binder_ioctl_write_read(struct file *filp, trace_binder_write_done(ret); if (ret < 0) { bwr.read_consumed = 0; if (copy_to_user(ubuf, &bwr, sizeof(bwr))) if (copy_to_user_preempt_disabled(ubuf, &bwr, sizeof(bwr))) ret = -EFAULT; goto out; } Loading @@ -3177,7 +3249,7 @@ static int binder_ioctl_write_read(struct file *filp, if (!list_empty(&proc->todo)) wake_up_interruptible(&proc->wait); if (ret < 0) { if (copy_to_user(ubuf, &bwr, sizeof(bwr))) if (copy_to_user_preempt_disabled(ubuf, &bwr, sizeof(bwr))) ret = -EFAULT; goto out; } Loading @@ -3187,7 +3259,7 @@ static int binder_ioctl_write_read(struct file *filp, proc->pid, thread->pid, (u64)bwr.write_consumed, (u64)bwr.write_size, (u64)bwr.read_consumed, (u64)bwr.read_size); if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { if (copy_to_user_preempt_disabled(ubuf, &bwr, sizeof(bwr))) { ret = -EFAULT; goto out; } Loading Loading @@ -3271,7 +3343,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto err; break; case BINDER_SET_MAX_THREADS: if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) { if (copy_from_user_preempt_disabled(&proc->max_threads, ubuf, sizeof(proc->max_threads))) { ret = -EINVAL; goto err; } Loading @@ -3294,8 +3366,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = -EINVAL; goto err; } if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &ver->protocol_version)) { if (put_user_preempt_disabled(BINDER_CURRENT_PROTOCOL_VERSION, &ver->protocol_version)) { ret = -EINVAL; goto err; } Loading Loading @@ -3357,6 +3428,7 @@ static const struct vm_operations_struct binder_vm_ops = { static int binder_mmap(struct file *filp, struct vm_area_struct *vma) { int ret; struct vm_struct *area; struct binder_proc *proc = filp->private_data; const char *failure_string; Loading Loading @@ -3417,7 +3489,11 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_ops = &binder_vm_ops; vma->vm_private_data = proc; if (binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma)) { /* binder_update_page_range assumes preemption is disabled */ preempt_disable(); ret = binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma); preempt_enable_no_resched(); if (ret) { ret = -ENOMEM; failure_string = "alloc small buf"; goto err_alloc_small_buf_failed; Loading Loading @@ -3703,8 +3779,12 @@ static void binder_deferred_func(struct work_struct *work) int defer; do { binder_lock(__func__); trace_binder_lock(__func__); mutex_lock(&binder_main_lock); trace_binder_locked(__func__); mutex_lock(&binder_deferred_lock); preempt_disable(); if (!hlist_empty(&binder_deferred_list)) { proc = hlist_entry(binder_deferred_list.first, struct binder_proc, deferred_work_node); Loading @@ -3730,7 +3810,9 @@ static void binder_deferred_func(struct work_struct *work) if (defer & BINDER_DEFERRED_RELEASE) binder_deferred_release(proc); /* frees proc */ binder_unlock(__func__); trace_binder_unlock(__func__); mutex_unlock(&binder_main_lock); preempt_enable_no_resched(); if (files) put_files_struct(files); } while (proc); Loading Loading
drivers/android/binder.c +131 −49 Original line number Diff line number Diff line Loading @@ -406,6 +406,7 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) struct files_struct *files = proc->files; unsigned long rlim_cur; unsigned long irqs; int ret; if (files == NULL) return -ESRCH; Loading @@ -416,7 +417,11 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE); unlock_task_sighand(proc->tsk, &irqs); return __alloc_fd(files, 0, rlim_cur, flags); preempt_enable_no_resched(); ret = __alloc_fd(files, 0, rlim_cur, flags); preempt_disable(); return ret; } /* Loading @@ -425,8 +430,11 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) static void task_fd_install( struct binder_proc *proc, unsigned int fd, struct file *file) { if (proc->files) if (proc->files) { preempt_enable_no_resched(); __fd_install(proc->files, fd, file); preempt_disable(); } } /* Loading Loading @@ -454,6 +462,7 @@ static inline void binder_lock(const char *tag) { trace_binder_lock(tag); mutex_lock(&binder_main_lock); preempt_disable(); trace_binder_locked(tag); } Loading @@ -461,8 +470,62 @@ static inline void binder_unlock(const char *tag) { trace_binder_unlock(tag); mutex_unlock(&binder_main_lock); preempt_enable(); } static inline void *kzalloc_preempt_disabled(size_t size) { void *ptr; ptr = kzalloc(size, GFP_NOWAIT); if (ptr) return ptr; preempt_enable_no_resched(); ptr = kzalloc(size, GFP_KERNEL); preempt_disable(); return ptr; } static inline long copy_to_user_preempt_disabled(void __user *to, const void *from, long n) { long ret; preempt_enable_no_resched(); ret = copy_to_user(to, from, n); preempt_disable(); return ret; } static inline long copy_from_user_preempt_disabled(void *to, const void __user *from, long n) { long ret; preempt_enable_no_resched(); ret = copy_from_user(to, from, n); preempt_disable(); return ret; } #define get_user_preempt_disabled(x, ptr) \ ({ \ int __ret; \ preempt_enable_no_resched(); \ __ret = get_user(x, ptr); \ preempt_disable(); \ __ret; \ }) #define put_user_preempt_disabled(x, ptr) \ ({ \ int __ret; \ preempt_enable_no_resched(); \ __ret = put_user(x, ptr); \ preempt_disable(); \ __ret; \ }) static void binder_set_nice(long nice) { long min_nice; Loading Loading @@ -595,6 +658,8 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, else mm = get_task_mm(proc->tsk); preempt_enable_no_resched(); if (mm) { down_write(&mm->mmap_sem); vma = proc->vma; Loading Loading @@ -649,6 +714,9 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, up_write(&mm->mmap_sem); mmput(mm); } preempt_disable(); return 0; free_range: Loading @@ -671,6 +739,9 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, up_write(&mm->mmap_sem); mmput(mm); } preempt_disable(); return -ENOMEM; } Loading Loading @@ -939,7 +1010,7 @@ static struct binder_node *binder_new_node(struct binder_proc *proc, return NULL; } node = kzalloc(sizeof(*node), GFP_KERNEL); node = kzalloc_preempt_disabled(sizeof(*node)); if (node == NULL) return NULL; binder_stats_created(BINDER_STAT_NODE); Loading Loading @@ -1083,7 +1154,7 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, else return ref; } new_ref = kzalloc(sizeof(*ref), GFP_KERNEL); new_ref = kzalloc_preempt_disabled(sizeof(*ref)); if (new_ref == NULL) return NULL; binder_stats_created(BINDER_STAT_REF); Loading Loading @@ -1955,14 +2026,14 @@ static void binder_transaction(struct binder_proc *proc, e->to_proc = target_proc->pid; /* TODO: reuse incoming transaction for reply */ t = kzalloc(sizeof(*t), GFP_KERNEL); t = kzalloc_preempt_disabled(sizeof(*t)); if (t == NULL) { return_error = BR_FAILED_REPLY; goto err_alloc_t_failed; } binder_stats_created(BINDER_STAT_TRANSACTION); tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL); tcomplete = kzalloc_preempt_disabled(sizeof(*tcomplete)); if (tcomplete == NULL) { return_error = BR_FAILED_REPLY; goto err_alloc_tcomplete_failed; Loading Loading @@ -2023,14 +2094,14 @@ static void binder_transaction(struct binder_proc *proc, ALIGN(tr->data_size, sizeof(void *))); offp = off_start; if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t) if (copy_from_user_preempt_disabled(t->buffer->data, (const void __user *)(uintptr_t) tr->data.ptr.buffer, tr->data_size)) { binder_user_error("%d:%d got transaction with invalid data ptr\n", proc->pid, thread->pid); return_error = BR_FAILED_REPLY; goto err_copy_data_failed; } if (copy_from_user(offp, (const void __user *)(uintptr_t) if (copy_from_user_preempt_disabled(offp, (const void __user *)(uintptr_t) tr->data.ptr.offsets, tr->offsets_size)) { binder_user_error("%d:%d got transaction with invalid offsets ptr\n", proc->pid, thread->pid); Loading Loading @@ -2148,7 +2219,8 @@ static void binder_transaction(struct binder_proc *proc, return_error = BR_FAILED_REPLY; goto err_bad_offset; } if (copy_from_user(sg_bufp, if (copy_from_user_preempt_disabled( sg_bufp, (const void __user *)(uintptr_t) bp->buffer, bp->length)) { binder_user_error("%d:%d got transaction with invalid offsets ptr\n", Loading Loading @@ -2257,7 +2329,7 @@ static int binder_thread_write(struct binder_proc *proc, void __user *end = buffer + size; while (ptr < end && thread->return_error == BR_OK) { if (get_user(cmd, (uint32_t __user *)ptr)) if (get_user_preempt_disabled(cmd, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); trace_binder_command(cmd); Loading @@ -2275,7 +2347,7 @@ static int binder_thread_write(struct binder_proc *proc, struct binder_ref *ref; const char *debug_string; if (get_user(target, (uint32_t __user *)ptr)) if (get_user_preempt_disabled(target, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); if (target == 0 && context->binder_context_mgr_node && Loading Loading @@ -2327,10 +2399,10 @@ static int binder_thread_write(struct binder_proc *proc, binder_uintptr_t cookie; struct binder_node *node; if (get_user(node_ptr, (binder_uintptr_t __user *)ptr)) if (get_user_preempt_disabled(node_ptr, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); if (get_user(cookie, (binder_uintptr_t __user *)ptr)) if (get_user_preempt_disabled(cookie, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); node = binder_get_node(proc, node_ptr); Loading Loading @@ -2388,7 +2460,7 @@ static int binder_thread_write(struct binder_proc *proc, binder_uintptr_t data_ptr; struct binder_buffer *buffer; if (get_user(data_ptr, (binder_uintptr_t __user *)ptr)) if (get_user_preempt_disabled(data_ptr, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); Loading Loading @@ -2430,7 +2502,8 @@ static int binder_thread_write(struct binder_proc *proc, case BC_REPLY_SG: { struct binder_transaction_data_sg tr; if (copy_from_user(&tr, ptr, sizeof(tr))) if (copy_from_user_preempt_disabled(&tr, ptr, sizeof(tr))) return -EFAULT; ptr += sizeof(tr); binder_transaction(proc, thread, &tr.transaction_data, Loading @@ -2441,7 +2514,7 @@ static int binder_thread_write(struct binder_proc *proc, case BC_REPLY: { struct binder_transaction_data tr; if (copy_from_user(&tr, ptr, sizeof(tr))) if (copy_from_user_preempt_disabled(&tr, ptr, sizeof(tr))) return -EFAULT; ptr += sizeof(tr); binder_transaction(proc, thread, &tr, Loading Loading @@ -2492,10 +2565,10 @@ static int binder_thread_write(struct binder_proc *proc, struct binder_ref *ref; struct binder_ref_death *death; if (get_user(target, (uint32_t __user *)ptr)) if (get_user_preempt_disabled(target, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); if (get_user(cookie, (binder_uintptr_t __user *)ptr)) if (get_user_preempt_disabled(cookie, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); ref = binder_get_ref(proc, target, false); Loading Loading @@ -2524,7 +2597,7 @@ static int binder_thread_write(struct binder_proc *proc, proc->pid, thread->pid); break; } death = kzalloc(sizeof(*death), GFP_KERNEL); death = kzalloc_preempt_disabled(sizeof(*death)); if (death == NULL) { thread->return_error = BR_ERROR; binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, Loading Loading @@ -2578,8 +2651,7 @@ static int binder_thread_write(struct binder_proc *proc, struct binder_work *w; binder_uintptr_t cookie; struct binder_ref_death *death = NULL; if (get_user(cookie, (binder_uintptr_t __user *)ptr)) if (get_user_preempt_disabled(cookie, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(cookie); Loading Loading @@ -2611,7 +2683,8 @@ static int binder_thread_write(struct binder_proc *proc, wake_up_interruptible(&proc->wait); } } } break; } break; default: pr_err("%d:%d unknown command %d\n", Loading Loading @@ -2660,7 +2733,7 @@ static int binder_thread_read(struct binder_proc *proc, int wait_for_proc_work; if (*consumed == 0) { if (put_user(BR_NOOP, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(BR_NOOP, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); } Loading @@ -2671,7 +2744,7 @@ static int binder_thread_read(struct binder_proc *proc, if (thread->return_error != BR_OK && ptr < end) { if (thread->return_error2 != BR_OK) { if (put_user(thread->return_error2, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(thread->return_error2, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); binder_stat_br(proc, thread, thread->return_error2); Loading @@ -2679,7 +2752,7 @@ static int binder_thread_read(struct binder_proc *proc, goto done; thread->return_error2 = BR_OK; } if (put_user(thread->return_error, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(thread->return_error, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); binder_stat_br(proc, thread, thread->return_error); Loading Loading @@ -2757,7 +2830,7 @@ static int binder_thread_read(struct binder_proc *proc, } break; case BINDER_WORK_TRANSACTION_COMPLETE: { cmd = BR_TRANSACTION_COMPLETE; if (put_user(cmd, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(cmd, (uint32_t __user *) ptr)) return -EFAULT; ptr += sizeof(uint32_t); Loading Loading @@ -2799,14 +2872,14 @@ static int binder_thread_read(struct binder_proc *proc, node->has_weak_ref = 0; } if (cmd != BR_NOOP) { if (put_user(cmd, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(cmd, (uint32_t __user *) ptr)) return -EFAULT; ptr += sizeof(uint32_t); if (put_user(node->ptr, if (put_user_preempt_disabled(node->ptr, (binder_uintptr_t __user *) (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); if (put_user(node->cookie, if (put_user_preempt_disabled(node->cookie, (binder_uintptr_t __user *) (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); Loading Loading @@ -2850,11 +2923,10 @@ static int binder_thread_read(struct binder_proc *proc, cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE; else cmd = BR_DEAD_BINDER; if (put_user(cmd, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(cmd, (uint32_t __user *) ptr)) return -EFAULT; ptr += sizeof(uint32_t); if (put_user(death->cookie, (binder_uintptr_t __user *)ptr)) if (put_user_preempt_disabled(death->cookie, (binder_uintptr_t __user *) ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); binder_stat_br(proc, thread, cmd); Loading Loading @@ -2921,10 +2993,10 @@ static int binder_thread_read(struct binder_proc *proc, ALIGN(t->buffer->data_size, sizeof(void *)); if (put_user(cmd, (uint32_t __user *)ptr)) if (put_user_preempt_disabled(cmd, (uint32_t __user *) ptr)) return -EFAULT; ptr += sizeof(uint32_t); if (copy_to_user(ptr, &tr, sizeof(tr))) if (copy_to_user_preempt_disabled(ptr, &tr, sizeof(tr))) return -EFAULT; ptr += sizeof(tr); Loading Loading @@ -2966,7 +3038,7 @@ static int binder_thread_read(struct binder_proc *proc, binder_debug(BINDER_DEBUG_THREADS, "%d:%d BR_SPAWN_LOOPER\n", proc->pid, thread->pid); if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer)) if (put_user_preempt_disabled(BR_SPAWN_LOOPER, (uint32_t __user *) buffer)) return -EFAULT; binder_stat_br(proc, thread, BR_SPAWN_LOOPER); } Loading Loading @@ -3041,7 +3113,7 @@ static struct binder_thread *binder_get_thread(struct binder_proc *proc) break; } if (*p == NULL) { thread = kzalloc(sizeof(*thread), GFP_KERNEL); thread = kzalloc_preempt_disabled(sizeof(*thread)); if (thread == NULL) return NULL; binder_stats_created(BINDER_STAT_THREAD); Loading Loading @@ -3145,7 +3217,7 @@ static int binder_ioctl_write_read(struct file *filp, ret = -EINVAL; goto out; } if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { if (copy_from_user_preempt_disabled(&bwr, ubuf, sizeof(bwr))) { ret = -EFAULT; goto out; } Loading @@ -3163,7 +3235,7 @@ static int binder_ioctl_write_read(struct file *filp, trace_binder_write_done(ret); if (ret < 0) { bwr.read_consumed = 0; if (copy_to_user(ubuf, &bwr, sizeof(bwr))) if (copy_to_user_preempt_disabled(ubuf, &bwr, sizeof(bwr))) ret = -EFAULT; goto out; } Loading @@ -3177,7 +3249,7 @@ static int binder_ioctl_write_read(struct file *filp, if (!list_empty(&proc->todo)) wake_up_interruptible(&proc->wait); if (ret < 0) { if (copy_to_user(ubuf, &bwr, sizeof(bwr))) if (copy_to_user_preempt_disabled(ubuf, &bwr, sizeof(bwr))) ret = -EFAULT; goto out; } Loading @@ -3187,7 +3259,7 @@ static int binder_ioctl_write_read(struct file *filp, proc->pid, thread->pid, (u64)bwr.write_consumed, (u64)bwr.write_size, (u64)bwr.read_consumed, (u64)bwr.read_size); if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { if (copy_to_user_preempt_disabled(ubuf, &bwr, sizeof(bwr))) { ret = -EFAULT; goto out; } Loading Loading @@ -3271,7 +3343,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto err; break; case BINDER_SET_MAX_THREADS: if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) { if (copy_from_user_preempt_disabled(&proc->max_threads, ubuf, sizeof(proc->max_threads))) { ret = -EINVAL; goto err; } Loading @@ -3294,8 +3366,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = -EINVAL; goto err; } if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &ver->protocol_version)) { if (put_user_preempt_disabled(BINDER_CURRENT_PROTOCOL_VERSION, &ver->protocol_version)) { ret = -EINVAL; goto err; } Loading Loading @@ -3357,6 +3428,7 @@ static const struct vm_operations_struct binder_vm_ops = { static int binder_mmap(struct file *filp, struct vm_area_struct *vma) { int ret; struct vm_struct *area; struct binder_proc *proc = filp->private_data; const char *failure_string; Loading Loading @@ -3417,7 +3489,11 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_ops = &binder_vm_ops; vma->vm_private_data = proc; if (binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma)) { /* binder_update_page_range assumes preemption is disabled */ preempt_disable(); ret = binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma); preempt_enable_no_resched(); if (ret) { ret = -ENOMEM; failure_string = "alloc small buf"; goto err_alloc_small_buf_failed; Loading Loading @@ -3703,8 +3779,12 @@ static void binder_deferred_func(struct work_struct *work) int defer; do { binder_lock(__func__); trace_binder_lock(__func__); mutex_lock(&binder_main_lock); trace_binder_locked(__func__); mutex_lock(&binder_deferred_lock); preempt_disable(); if (!hlist_empty(&binder_deferred_list)) { proc = hlist_entry(binder_deferred_list.first, struct binder_proc, deferred_work_node); Loading @@ -3730,7 +3810,9 @@ static void binder_deferred_func(struct work_struct *work) if (defer & BINDER_DEFERRED_RELEASE) binder_deferred_release(proc); /* frees proc */ binder_unlock(__func__); trace_binder_unlock(__func__); mutex_unlock(&binder_main_lock); preempt_enable_no_resched(); if (files) put_files_struct(files); } while (proc); Loading