Re: [PATCH] binder: create node flag to request sender's security context
From: kbuild test robot
Date: Thu Jan 10 2019 - 22:09:38 EST
Hi Todd,
I love your patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[also build test WARNING on v5.0-rc1 next-20190110]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Todd-Kjos/binder-create-node-flag-to-request-sender-s-security-context/20190111-095225
config: i386-randconfig-x009-201901 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All warnings (new ones prefixed by >>):
drivers/android/binder.c: In function 'binder_transaction':
>> drivers/android/binder.c:3067:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
t->security_ctx = (binder_uintptr_t)kptr +
^
vim +3067 drivers/android/binder.c
2761
2762 static void binder_transaction(struct binder_proc *proc,
2763 struct binder_thread *thread,
2764 struct binder_transaction_data *tr, int reply,
2765 binder_size_t extra_buffers_size)
2766 {
2767 int ret;
2768 struct binder_transaction *t;
2769 struct binder_work *w;
2770 struct binder_work *tcomplete;
2771 binder_size_t *offp, *off_end, *off_start;
2772 binder_size_t off_min;
2773 u8 *sg_bufp, *sg_buf_end;
2774 struct binder_proc *target_proc = NULL;
2775 struct binder_thread *target_thread = NULL;
2776 struct binder_node *target_node = NULL;
2777 struct binder_transaction *in_reply_to = NULL;
2778 struct binder_transaction_log_entry *e;
2779 uint32_t return_error = 0;
2780 uint32_t return_error_param = 0;
2781 uint32_t return_error_line = 0;
2782 struct binder_buffer_object *last_fixup_obj = NULL;
2783 binder_size_t last_fixup_min_off = 0;
2784 struct binder_context *context = proc->context;
2785 int t_debug_id = atomic_inc_return(&binder_last_id);
2786 char *secctx = NULL;
2787 u32 secctx_sz = 0;
2788
2789 e = binder_transaction_log_add(&binder_transaction_log);
2790 e->debug_id = t_debug_id;
2791 e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
2792 e->from_proc = proc->pid;
2793 e->from_thread = thread->pid;
2794 e->target_handle = tr->target.handle;
2795 e->data_size = tr->data_size;
2796 e->offsets_size = tr->offsets_size;
2797 e->context_name = proc->context->name;
2798
2799 if (reply) {
2800 binder_inner_proc_lock(proc);
2801 in_reply_to = thread->transaction_stack;
2802 if (in_reply_to == NULL) {
2803 binder_inner_proc_unlock(proc);
2804 binder_user_error("%d:%d got reply transaction with no transaction stack\n",
2805 proc->pid, thread->pid);
2806 return_error = BR_FAILED_REPLY;
2807 return_error_param = -EPROTO;
2808 return_error_line = __LINE__;
2809 goto err_empty_call_stack;
2810 }
2811 if (in_reply_to->to_thread != thread) {
2812 spin_lock(&in_reply_to->lock);
2813 binder_user_error("%d:%d got reply transaction with bad transaction stack, transaction %d has target %d:%d\n",
2814 proc->pid, thread->pid, in_reply_to->debug_id,
2815 in_reply_to->to_proc ?
2816 in_reply_to->to_proc->pid : 0,
2817 in_reply_to->to_thread ?
2818 in_reply_to->to_thread->pid : 0);
2819 spin_unlock(&in_reply_to->lock);
2820 binder_inner_proc_unlock(proc);
2821 return_error = BR_FAILED_REPLY;
2822 return_error_param = -EPROTO;
2823 return_error_line = __LINE__;
2824 in_reply_to = NULL;
2825 goto err_bad_call_stack;
2826 }
2827 thread->transaction_stack = in_reply_to->to_parent;
2828 binder_inner_proc_unlock(proc);
2829 binder_set_nice(in_reply_to->saved_priority);
2830 target_thread = binder_get_txn_from_and_acq_inner(in_reply_to);
2831 if (target_thread == NULL) {
2832 /* annotation for sparse */
2833 __release(&target_thread->proc->inner_lock);
2834 return_error = BR_DEAD_REPLY;
2835 return_error_line = __LINE__;
2836 goto err_dead_binder;
2837 }
2838 if (target_thread->transaction_stack != in_reply_to) {
2839 binder_user_error("%d:%d got reply transaction with bad target transaction stack %d, expected %d\n",
2840 proc->pid, thread->pid,
2841 target_thread->transaction_stack ?
2842 target_thread->transaction_stack->debug_id : 0,
2843 in_reply_to->debug_id);
2844 binder_inner_proc_unlock(target_thread->proc);
2845 return_error = BR_FAILED_REPLY;
2846 return_error_param = -EPROTO;
2847 return_error_line = __LINE__;
2848 in_reply_to = NULL;
2849 target_thread = NULL;
2850 goto err_dead_binder;
2851 }
2852 target_proc = target_thread->proc;
2853 target_proc->tmp_ref++;
2854 binder_inner_proc_unlock(target_thread->proc);
2855 } else {
2856 if (tr->target.handle) {
2857 struct binder_ref *ref;
2858
2859 /*
2860 * There must already be a strong ref
2861 * on this node. If so, do a strong
2862 * increment on the node to ensure it
2863 * stays alive until the transaction is
2864 * done.
2865 */
2866 binder_proc_lock(proc);
2867 ref = binder_get_ref_olocked(proc, tr->target.handle,
2868 true);
2869 if (ref) {
2870 target_node = binder_get_node_refs_for_txn(
2871 ref->node, &target_proc,
2872 &return_error);
2873 } else {
2874 binder_user_error("%d:%d got transaction to invalid handle\n",
2875 proc->pid, thread->pid);
2876 return_error = BR_FAILED_REPLY;
2877 }
2878 binder_proc_unlock(proc);
2879 } else {
2880 mutex_lock(&context->context_mgr_node_lock);
2881 target_node = context->binder_context_mgr_node;
2882 if (target_node)
2883 target_node = binder_get_node_refs_for_txn(
2884 target_node, &target_proc,
2885 &return_error);
2886 else
2887 return_error = BR_DEAD_REPLY;
2888 mutex_unlock(&context->context_mgr_node_lock);
2889 if (target_node && target_proc == proc) {
2890 binder_user_error("%d:%d got transaction to context manager from process owning it\n",
2891 proc->pid, thread->pid);
2892 return_error = BR_FAILED_REPLY;
2893 return_error_param = -EINVAL;
2894 return_error_line = __LINE__;
2895 goto err_invalid_target_handle;
2896 }
2897 }
2898 if (!target_node) {
2899 /*
2900 * return_error is set above
2901 */
2902 return_error_param = -EINVAL;
2903 return_error_line = __LINE__;
2904 goto err_dead_binder;
2905 }
2906 e->to_node = target_node->debug_id;
2907 if (security_binder_transaction(proc->tsk,
2908 target_proc->tsk) < 0) {
2909 return_error = BR_FAILED_REPLY;
2910 return_error_param = -EPERM;
2911 return_error_line = __LINE__;
2912 goto err_invalid_target_handle;
2913 }
2914 binder_inner_proc_lock(proc);
2915
2916 w = list_first_entry_or_null(&thread->todo,
2917 struct binder_work, entry);
2918 if (!(tr->flags & TF_ONE_WAY) && w &&
2919 w->type == BINDER_WORK_TRANSACTION) {
2920 /*
2921 * Do not allow new outgoing transaction from a
2922 * thread that has a transaction at the head of
2923 * its todo list. Only need to check the head
2924 * because binder_select_thread_ilocked picks a
2925 * thread from proc->waiting_threads to enqueue
2926 * the transaction, and nothing is queued to the
2927 * todo list while the thread is on waiting_threads.
2928 */
2929 binder_user_error("%d:%d new transaction not allowed when there is a transaction on thread todo\n",
2930 proc->pid, thread->pid);
2931 binder_inner_proc_unlock(proc);
2932 return_error = BR_FAILED_REPLY;
2933 return_error_param = -EPROTO;
2934 return_error_line = __LINE__;
2935 goto err_bad_todo_list;
2936 }
2937
2938 if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {
2939 struct binder_transaction *tmp;
2940
2941 tmp = thread->transaction_stack;
2942 if (tmp->to_thread != thread) {
2943 spin_lock(&tmp->lock);
2944 binder_user_error("%d:%d got new transaction with bad transaction stack, transaction %d has target %d:%d\n",
2945 proc->pid, thread->pid, tmp->debug_id,
2946 tmp->to_proc ? tmp->to_proc->pid : 0,
2947 tmp->to_thread ?
2948 tmp->to_thread->pid : 0);
2949 spin_unlock(&tmp->lock);
2950 binder_inner_proc_unlock(proc);
2951 return_error = BR_FAILED_REPLY;
2952 return_error_param = -EPROTO;
2953 return_error_line = __LINE__;
2954 goto err_bad_call_stack;
2955 }
2956 while (tmp) {
2957 struct binder_thread *from;
2958
2959 spin_lock(&tmp->lock);
2960 from = tmp->from;
2961 if (from && from->proc == target_proc) {
2962 atomic_inc(&from->tmp_ref);
2963 target_thread = from;
2964 spin_unlock(&tmp->lock);
2965 break;
2966 }
2967 spin_unlock(&tmp->lock);
2968 tmp = tmp->from_parent;
2969 }
2970 }
2971 binder_inner_proc_unlock(proc);
2972 }
2973 if (target_thread)
2974 e->to_thread = target_thread->pid;
2975 e->to_proc = target_proc->pid;
2976
2977 /* TODO: reuse incoming transaction for reply */
2978 t = kzalloc(sizeof(*t), GFP_KERNEL);
2979 if (t == NULL) {
2980 return_error = BR_FAILED_REPLY;
2981 return_error_param = -ENOMEM;
2982 return_error_line = __LINE__;
2983 goto err_alloc_t_failed;
2984 }
2985 INIT_LIST_HEAD(&t->fd_fixups);
2986 binder_stats_created(BINDER_STAT_TRANSACTION);
2987 spin_lock_init(&t->lock);
2988
2989 tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
2990 if (tcomplete == NULL) {
2991 return_error = BR_FAILED_REPLY;
2992 return_error_param = -ENOMEM;
2993 return_error_line = __LINE__;
2994 goto err_alloc_tcomplete_failed;
2995 }
2996 binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE);
2997
2998 t->debug_id = t_debug_id;
2999
3000 if (reply)
3001 binder_debug(BINDER_DEBUG_TRANSACTION,
3002 "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld-%lld\n",
3003 proc->pid, thread->pid, t->debug_id,
3004 target_proc->pid, target_thread->pid,
3005 (u64)tr->data.ptr.buffer,
3006 (u64)tr->data.ptr.offsets,
3007 (u64)tr->data_size, (u64)tr->offsets_size,
3008 (u64)extra_buffers_size);
3009 else
3010 binder_debug(BINDER_DEBUG_TRANSACTION,
3011 "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld-%lld\n",
3012 proc->pid, thread->pid, t->debug_id,
3013 target_proc->pid, target_node->debug_id,
3014 (u64)tr->data.ptr.buffer,
3015 (u64)tr->data.ptr.offsets,
3016 (u64)tr->data_size, (u64)tr->offsets_size,
3017 (u64)extra_buffers_size);
3018
3019 if (!reply && !(tr->flags & TF_ONE_WAY))
3020 t->from = thread;
3021 else
3022 t->from = NULL;
3023 t->sender_euid = task_euid(proc->tsk);
3024 t->to_proc = target_proc;
3025 t->to_thread = target_thread;
3026 t->code = tr->code;
3027 t->flags = tr->flags;
3028 t->priority = task_nice(current);
3029
3030 if (target_node && target_node->txn_security_ctx) {
3031 u32 secid;
3032
3033 security_task_getsecid(proc->tsk, &secid);
3034 ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
3035 if (ret) {
3036 return_error = BR_FAILED_REPLY;
3037 return_error_param = ret;
3038 return_error_line = __LINE__;
3039 goto err_get_secctx_failed;
3040 }
3041 extra_buffers_size += ALIGN(secctx_sz, sizeof(u64));
3042 }
3043
3044 trace_binder_transaction(reply, t, target_node);
3045
3046 t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
3047 tr->offsets_size, extra_buffers_size,
3048 !reply && (t->flags & TF_ONE_WAY));
3049 if (IS_ERR(t->buffer)) {
3050 /*
3051 * -ESRCH indicates VMA cleared. The target is dying.
3052 */
3053 return_error_param = PTR_ERR(t->buffer);
3054 return_error = return_error_param == -ESRCH ?
3055 BR_DEAD_REPLY : BR_FAILED_REPLY;
3056 return_error_line = __LINE__;
3057 t->buffer = NULL;
3058 goto err_binder_alloc_buf_failed;
3059 }
3060 if (secctx) {
3061 size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
3062 ALIGN(tr->offsets_size, sizeof(void *)) +
3063 ALIGN(extra_buffers_size, sizeof(void *)) -
3064 ALIGN(secctx_sz, sizeof(u64));
3065 char *kptr = t->buffer->data + buf_offset;
3066
> 3067 t->security_ctx = (binder_uintptr_t)kptr +
3068 binder_alloc_get_user_buffer_offset(&target_proc->alloc);
3069 memcpy(kptr, secctx, secctx_sz);
3070 security_release_secctx(secctx, secctx_sz);
3071 secctx = NULL;
3072 }
3073 t->buffer->debug_id = t->debug_id;
3074 t->buffer->transaction = t;
3075 t->buffer->target_node = target_node;
3076 trace_binder_transaction_alloc_buf(t->buffer);
3077 off_start = (binder_size_t *)(t->buffer->data +
3078 ALIGN(tr->data_size, sizeof(void *)));
3079 offp = off_start;
3080
3081 if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t)
3082 tr->data.ptr.buffer, tr->data_size)) {
3083 binder_user_error("%d:%d got transaction with invalid data ptr\n",
3084 proc->pid, thread->pid);
3085 return_error = BR_FAILED_REPLY;
3086 return_error_param = -EFAULT;
3087 return_error_line = __LINE__;
3088 goto err_copy_data_failed;
3089 }
3090 if (copy_from_user(offp, (const void __user *)(uintptr_t)
3091 tr->data.ptr.offsets, tr->offsets_size)) {
3092 binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
3093 proc->pid, thread->pid);
3094 return_error = BR_FAILED_REPLY;
3095 return_error_param = -EFAULT;
3096 return_error_line = __LINE__;
3097 goto err_copy_data_failed;
3098 }
3099 if (!IS_ALIGNED(tr->offsets_size, sizeof(binder_size_t))) {
3100 binder_user_error("%d:%d got transaction with invalid offsets size, %lld\n",
3101 proc->pid, thread->pid, (u64)tr->offsets_size);
3102 return_error = BR_FAILED_REPLY;
3103 return_error_param = -EINVAL;
3104 return_error_line = __LINE__;
3105 goto err_bad_offset;
3106 }
3107 if (!IS_ALIGNED(extra_buffers_size, sizeof(u64))) {
3108 binder_user_error("%d:%d got transaction with unaligned buffers size, %lld\n",
3109 proc->pid, thread->pid,
3110 (u64)extra_buffers_size);
3111 return_error = BR_FAILED_REPLY;
3112 return_error_param = -EINVAL;
3113 return_error_line = __LINE__;
3114 goto err_bad_offset;
3115 }
3116 off_end = (void *)off_start + tr->offsets_size;
3117 sg_bufp = (u8 *)(PTR_ALIGN(off_end, sizeof(void *)));
3118 sg_buf_end = sg_bufp + extra_buffers_size;
3119 off_min = 0;
3120 for (; offp < off_end; offp++) {
3121 struct binder_object_header *hdr;
3122 size_t object_size = binder_validate_object(t->buffer, *offp);
3123
3124 if (object_size == 0 || *offp < off_min) {
3125 binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n",
3126 proc->pid, thread->pid, (u64)*offp,
3127 (u64)off_min,
3128 (u64)t->buffer->data_size);
3129 return_error = BR_FAILED_REPLY;
3130 return_error_param = -EINVAL;
3131 return_error_line = __LINE__;
3132 goto err_bad_offset;
3133 }
3134
3135 hdr = (struct binder_object_header *)(t->buffer->data + *offp);
3136 off_min = *offp + object_size;
3137 switch (hdr->type) {
3138 case BINDER_TYPE_BINDER:
3139 case BINDER_TYPE_WEAK_BINDER: {
3140 struct flat_binder_object *fp;
3141
3142 fp = to_flat_binder_object(hdr);
3143 ret = binder_translate_binder(fp, t, thread);
3144 if (ret < 0) {
3145 return_error = BR_FAILED_REPLY;
3146 return_error_param = ret;
3147 return_error_line = __LINE__;
3148 goto err_translate_failed;
3149 }
3150 } break;
3151 case BINDER_TYPE_HANDLE:
3152 case BINDER_TYPE_WEAK_HANDLE: {
3153 struct flat_binder_object *fp;
3154
3155 fp = to_flat_binder_object(hdr);
3156 ret = binder_translate_handle(fp, t, thread);
3157 if (ret < 0) {
3158 return_error = BR_FAILED_REPLY;
3159 return_error_param = ret;
3160 return_error_line = __LINE__;
3161 goto err_translate_failed;
3162 }
3163 } break;
3164
3165 case BINDER_TYPE_FD: {
3166 struct binder_fd_object *fp = to_binder_fd_object(hdr);
3167 int ret = binder_translate_fd(&fp->fd, t, thread,
3168 in_reply_to);
3169
3170 if (ret < 0) {
3171 return_error = BR_FAILED_REPLY;
3172 return_error_param = ret;
3173 return_error_line = __LINE__;
3174 goto err_translate_failed;
3175 }
3176 fp->pad_binder = 0;
3177 } break;
3178 case BINDER_TYPE_FDA: {
3179 struct binder_fd_array_object *fda =
3180 to_binder_fd_array_object(hdr);
3181 struct binder_buffer_object *parent =
3182 binder_validate_ptr(t->buffer, fda->parent,
3183 off_start,
3184 offp - off_start);
3185 if (!parent) {
3186 binder_user_error("%d:%d got transaction with invalid parent offset or type\n",
3187 proc->pid, thread->pid);
3188 return_error = BR_FAILED_REPLY;
3189 return_error_param = -EINVAL;
3190 return_error_line = __LINE__;
3191 goto err_bad_parent;
3192 }
3193 if (!binder_validate_fixup(t->buffer, off_start,
3194 parent, fda->parent_offset,
3195 last_fixup_obj,
3196 last_fixup_min_off)) {
3197 binder_user_error("%d:%d got transaction with out-of-order buffer fixup\n",
3198 proc->pid, thread->pid);
3199 return_error = BR_FAILED_REPLY;
3200 return_error_param = -EINVAL;
3201 return_error_line = __LINE__;
3202 goto err_bad_parent;
3203 }
3204 ret = binder_translate_fd_array(fda, parent, t, thread,
3205 in_reply_to);
3206 if (ret < 0) {
3207 return_error = BR_FAILED_REPLY;
3208 return_error_param = ret;
3209 return_error_line = __LINE__;
3210 goto err_translate_failed;
3211 }
3212 last_fixup_obj = parent;
3213 last_fixup_min_off =
3214 fda->parent_offset + sizeof(u32) * fda->num_fds;
3215 } break;
3216 case BINDER_TYPE_PTR: {
3217 struct binder_buffer_object *bp =
3218 to_binder_buffer_object(hdr);
3219 size_t buf_left = sg_buf_end - sg_bufp;
3220
3221 if (bp->length > buf_left) {
3222 binder_user_error("%d:%d got transaction with too large buffer\n",
3223 proc->pid, thread->pid);
3224 return_error = BR_FAILED_REPLY;
3225 return_error_param = -EINVAL;
3226 return_error_line = __LINE__;
3227 goto err_bad_offset;
3228 }
3229 if (copy_from_user(sg_bufp,
3230 (const void __user *)(uintptr_t)
3231 bp->buffer, bp->length)) {
3232 binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
3233 proc->pid, thread->pid);
3234 return_error_param = -EFAULT;
3235 return_error = BR_FAILED_REPLY;
3236 return_error_line = __LINE__;
3237 goto err_copy_data_failed;
3238 }
3239 /* Fixup buffer pointer to target proc address space */
3240 bp->buffer = (uintptr_t)sg_bufp +
3241 binder_alloc_get_user_buffer_offset(
3242 &target_proc->alloc);
3243 sg_bufp += ALIGN(bp->length, sizeof(u64));
3244
3245 ret = binder_fixup_parent(t, thread, bp, off_start,
3246 offp - off_start,
3247 last_fixup_obj,
3248 last_fixup_min_off);
3249 if (ret < 0) {
3250 return_error = BR_FAILED_REPLY;
3251 return_error_param = ret;
3252 return_error_line = __LINE__;
3253 goto err_translate_failed;
3254 }
3255 last_fixup_obj = bp;
3256 last_fixup_min_off = 0;
3257 } break;
3258 default:
3259 binder_user_error("%d:%d got transaction with invalid object type, %x\n",
3260 proc->pid, thread->pid, hdr->type);
3261 return_error = BR_FAILED_REPLY;
3262 return_error_param = -EINVAL;
3263 return_error_line = __LINE__;
3264 goto err_bad_object_type;
3265 }
3266 }
3267 tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
3268 t->work.type = BINDER_WORK_TRANSACTION;
3269
3270 if (reply) {
3271 binder_enqueue_thread_work(thread, tcomplete);
3272 binder_inner_proc_lock(target_proc);
3273 if (target_thread->is_dead) {
3274 binder_inner_proc_unlock(target_proc);
3275 goto err_dead_proc_or_thread;
3276 }
3277 BUG_ON(t->buffer->async_transaction != 0);
3278 binder_pop_transaction_ilocked(target_thread, in_reply_to);
3279 binder_enqueue_thread_work_ilocked(target_thread, &t->work);
3280 binder_inner_proc_unlock(target_proc);
3281 wake_up_interruptible_sync(&target_thread->wait);
3282 binder_free_transaction(in_reply_to);
3283 } else if (!(t->flags & TF_ONE_WAY)) {
3284 BUG_ON(t->buffer->async_transaction != 0);
3285 binder_inner_proc_lock(proc);
3286 /*
3287 * Defer the TRANSACTION_COMPLETE, so we don't return to
3288 * userspace immediately; this allows the target process to
3289 * immediately start processing this transaction, reducing
3290 * latency. We will then return the TRANSACTION_COMPLETE when
3291 * the target replies (or there is an error).
3292 */
3293 binder_enqueue_deferred_thread_work_ilocked(thread, tcomplete);
3294 t->need_reply = 1;
3295 t->from_parent = thread->transaction_stack;
3296 thread->transaction_stack = t;
3297 binder_inner_proc_unlock(proc);
3298 if (!binder_proc_transaction(t, target_proc, target_thread)) {
3299 binder_inner_proc_lock(proc);
3300 binder_pop_transaction_ilocked(thread, t);
3301 binder_inner_proc_unlock(proc);
3302 goto err_dead_proc_or_thread;
3303 }
3304 } else {
3305 BUG_ON(target_node == NULL);
3306 BUG_ON(t->buffer->async_transaction != 1);
3307 binder_enqueue_thread_work(thread, tcomplete);
3308 if (!binder_proc_transaction(t, target_proc, NULL))
3309 goto err_dead_proc_or_thread;
3310 }
3311 if (target_thread)
3312 binder_thread_dec_tmpref(target_thread);
3313 binder_proc_dec_tmpref(target_proc);
3314 if (target_node)
3315 binder_dec_node_tmpref(target_node);
3316 /*
3317 * write barrier to synchronize with initialization
3318 * of log entry
3319 */
3320 smp_wmb();
3321 WRITE_ONCE(e->debug_id_done, t_debug_id);
3322 return;
3323
3324 err_dead_proc_or_thread:
3325 return_error = BR_DEAD_REPLY;
3326 return_error_line = __LINE__;
3327 binder_dequeue_work(proc, tcomplete);
3328 err_translate_failed:
3329 err_bad_object_type:
3330 err_bad_offset:
3331 err_bad_parent:
3332 err_copy_data_failed:
3333 binder_free_txn_fixups(t);
3334 trace_binder_transaction_failed_buffer_release(t->buffer);
3335 binder_transaction_buffer_release(target_proc, t->buffer, offp);
3336 if (target_node)
3337 binder_dec_node_tmpref(target_node);
3338 target_node = NULL;
3339 t->buffer->transaction = NULL;
3340 binder_alloc_free_buf(&target_proc->alloc, t->buffer);
3341 err_binder_alloc_buf_failed:
3342 if (secctx)
3343 security_release_secctx(secctx, secctx_sz);
3344 err_get_secctx_failed:
3345 kfree(tcomplete);
3346 binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
3347 err_alloc_tcomplete_failed:
3348 kfree(t);
3349 binder_stats_deleted(BINDER_STAT_TRANSACTION);
3350 err_alloc_t_failed:
3351 err_bad_todo_list:
3352 err_bad_call_stack:
3353 err_empty_call_stack:
3354 err_dead_binder:
3355 err_invalid_target_handle:
3356 if (target_thread)
3357 binder_thread_dec_tmpref(target_thread);
3358 if (target_proc)
3359 binder_proc_dec_tmpref(target_proc);
3360 if (target_node) {
3361 binder_dec_node(target_node, 1, 0);
3362 binder_dec_node_tmpref(target_node);
3363 }
3364
3365 binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
3366 "%d:%d transaction failed %d/%d, size %lld-%lld line %d\n",
3367 proc->pid, thread->pid, return_error, return_error_param,
3368 (u64)tr->data_size, (u64)tr->offsets_size,
3369 return_error_line);
3370
3371 {
3372 struct binder_transaction_log_entry *fe;
3373
3374 e->return_error = return_error;
3375 e->return_error_param = return_error_param;
3376 e->return_error_line = return_error_line;
3377 fe = binder_transaction_log_add(&binder_transaction_log_failed);
3378 *fe = *e;
3379 /*
3380 * write barrier to synchronize with initialization
3381 * of log entry
3382 */
3383 smp_wmb();
3384 WRITE_ONCE(e->debug_id_done, t_debug_id);
3385 WRITE_ONCE(fe->debug_id_done, t_debug_id);
3386 }
3387
3388 BUG_ON(thread->return_error.cmd != BR_OK);
3389 if (in_reply_to) {
3390 thread->return_error.cmd = BR_TRANSACTION_COMPLETE;
3391 binder_enqueue_thread_work(thread, &thread->return_error.work);
3392 binder_send_failed_reply(in_reply_to, return_error);
3393 } else {
3394 thread->return_error.cmd = return_error;
3395 binder_enqueue_thread_work(thread, &thread->return_error.work);
3396 }
3397 }
3398
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Attachment:
.config.gz
Description: application/gzip