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

Reply via email to