.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* binder.c |
---|
2 | 3 | * |
---|
3 | 4 | * Android IPC Subsystem |
---|
4 | 5 | * |
---|
5 | 6 | * Copyright (C) 2007-2008 Google, Inc. |
---|
6 | | - * |
---|
7 | | - * This software is licensed under the terms of the GNU General Public |
---|
8 | | - * License version 2, as published by the Free Software Foundation, and |
---|
9 | | - * may be copied, distributed, and modified under those terms. |
---|
10 | | - * |
---|
11 | | - * This program is distributed in the hope that it will be useful, |
---|
12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | | - * GNU General Public License for more details. |
---|
15 | | - * |
---|
16 | 7 | */ |
---|
17 | 8 | |
---|
18 | 9 | /* |
---|
.. | .. |
---|
66 | 57 | #include <linux/sched/signal.h> |
---|
67 | 58 | #include <linux/sched/mm.h> |
---|
68 | 59 | #include <linux/seq_file.h> |
---|
| 60 | +#include <linux/string.h> |
---|
69 | 61 | #include <linux/uaccess.h> |
---|
70 | 62 | #include <linux/pid_namespace.h> |
---|
71 | 63 | #include <linux/security.h> |
---|
72 | 64 | #include <linux/spinlock.h> |
---|
73 | 65 | #include <linux/ratelimit.h> |
---|
| 66 | +#include <linux/syscalls.h> |
---|
| 67 | +#include <linux/task_work.h> |
---|
| 68 | +#include <linux/sizes.h> |
---|
| 69 | +#include <linux/android_vendor.h> |
---|
74 | 70 | |
---|
75 | | -#include <uapi/linux/android/binder.h> |
---|
76 | 71 | #include <uapi/linux/sched/types.h> |
---|
| 72 | +#include <uapi/linux/android/binder.h> |
---|
77 | 73 | |
---|
78 | 74 | #include <asm/cacheflush.h> |
---|
79 | 75 | |
---|
80 | | -#include "binder_alloc.h" |
---|
81 | 76 | #include "binder_internal.h" |
---|
82 | 77 | #include "binder_trace.h" |
---|
| 78 | +#include <trace/hooks/binder.h> |
---|
83 | 79 | |
---|
84 | 80 | static HLIST_HEAD(binder_deferred_list); |
---|
85 | 81 | static DEFINE_MUTEX(binder_deferred_lock); |
---|
.. | .. |
---|
97 | 93 | |
---|
98 | 94 | static int proc_show(struct seq_file *m, void *unused); |
---|
99 | 95 | DEFINE_SHOW_ATTRIBUTE(proc); |
---|
100 | | - |
---|
101 | | -/* This is only defined in include/asm-arm/sizes.h */ |
---|
102 | | -#ifndef SZ_1K |
---|
103 | | -#define SZ_1K 0x400 |
---|
104 | | -#endif |
---|
105 | | - |
---|
106 | | -#ifndef SZ_4M |
---|
107 | | -#define SZ_4M 0x400000 |
---|
108 | | -#endif |
---|
109 | 96 | |
---|
110 | 97 | #define FORBIDDEN_MMAP_FLAGS (VM_WRITE) |
---|
111 | 98 | |
---|
.. | .. |
---|
174 | 161 | #define to_binder_fd_array_object(hdr) \ |
---|
175 | 162 | container_of(hdr, struct binder_fd_array_object, hdr) |
---|
176 | 163 | |
---|
177 | | -enum binder_stat_types { |
---|
178 | | - BINDER_STAT_PROC, |
---|
179 | | - BINDER_STAT_THREAD, |
---|
180 | | - BINDER_STAT_NODE, |
---|
181 | | - BINDER_STAT_REF, |
---|
182 | | - BINDER_STAT_DEATH, |
---|
183 | | - BINDER_STAT_TRANSACTION, |
---|
184 | | - BINDER_STAT_TRANSACTION_COMPLETE, |
---|
185 | | - BINDER_STAT_COUNT |
---|
186 | | -}; |
---|
187 | | - |
---|
188 | | -struct binder_stats { |
---|
189 | | - atomic_t br[_IOC_NR(BR_FAILED_REPLY) + 1]; |
---|
190 | | - atomic_t bc[_IOC_NR(BC_REPLY_SG) + 1]; |
---|
191 | | - atomic_t obj_created[BINDER_STAT_COUNT]; |
---|
192 | | - atomic_t obj_deleted[BINDER_STAT_COUNT]; |
---|
193 | | -}; |
---|
194 | | - |
---|
195 | 164 | static struct binder_stats binder_stats; |
---|
196 | 165 | |
---|
197 | 166 | static inline void binder_stats_deleted(enum binder_stat_types type) |
---|
.. | .. |
---|
204 | 173 | atomic_inc(&binder_stats.obj_created[type]); |
---|
205 | 174 | } |
---|
206 | 175 | |
---|
207 | | -struct binder_transaction_log binder_transaction_log; |
---|
208 | | -struct binder_transaction_log binder_transaction_log_failed; |
---|
| 176 | +struct binder_transaction_log_entry { |
---|
| 177 | + int debug_id; |
---|
| 178 | + int debug_id_done; |
---|
| 179 | + int call_type; |
---|
| 180 | + int from_proc; |
---|
| 181 | + int from_thread; |
---|
| 182 | + int target_handle; |
---|
| 183 | + int to_proc; |
---|
| 184 | + int to_thread; |
---|
| 185 | + int to_node; |
---|
| 186 | + int data_size; |
---|
| 187 | + int offsets_size; |
---|
| 188 | + int return_error_line; |
---|
| 189 | + uint32_t return_error; |
---|
| 190 | + uint32_t return_error_param; |
---|
| 191 | + char context_name[BINDERFS_MAX_NAME + 1]; |
---|
| 192 | +}; |
---|
| 193 | + |
---|
| 194 | +struct binder_transaction_log { |
---|
| 195 | + atomic_t cur; |
---|
| 196 | + bool full; |
---|
| 197 | + struct binder_transaction_log_entry entry[32]; |
---|
| 198 | +}; |
---|
| 199 | + |
---|
| 200 | +static struct binder_transaction_log binder_transaction_log; |
---|
| 201 | +static struct binder_transaction_log binder_transaction_log_failed; |
---|
209 | 202 | |
---|
210 | 203 | static struct binder_transaction_log_entry *binder_transaction_log_add( |
---|
211 | 204 | struct binder_transaction_log *log) |
---|
.. | .. |
---|
227 | 220 | return e; |
---|
228 | 221 | } |
---|
229 | 222 | |
---|
230 | | -/** |
---|
231 | | - * struct binder_work - work enqueued on a worklist |
---|
232 | | - * @entry: node enqueued on list |
---|
233 | | - * @type: type of work to be performed |
---|
234 | | - * |
---|
235 | | - * There are separate work lists for proc, thread, and node (async). |
---|
236 | | - */ |
---|
237 | | -struct binder_work { |
---|
238 | | - struct list_head entry; |
---|
239 | | - |
---|
240 | | - enum binder_work_type { |
---|
241 | | - BINDER_WORK_TRANSACTION = 1, |
---|
242 | | - BINDER_WORK_TRANSACTION_COMPLETE, |
---|
243 | | - BINDER_WORK_RETURN_ERROR, |
---|
244 | | - BINDER_WORK_NODE, |
---|
245 | | - BINDER_WORK_DEAD_BINDER, |
---|
246 | | - BINDER_WORK_DEAD_BINDER_AND_CLEAR, |
---|
247 | | - BINDER_WORK_CLEAR_DEATH_NOTIFICATION, |
---|
248 | | - } type; |
---|
249 | | -}; |
---|
250 | | - |
---|
251 | | -struct binder_error { |
---|
252 | | - struct binder_work work; |
---|
253 | | - uint32_t cmd; |
---|
254 | | -}; |
---|
255 | | - |
---|
256 | | -/** |
---|
257 | | - * struct binder_node - binder node bookkeeping |
---|
258 | | - * @debug_id: unique ID for debugging |
---|
259 | | - * (invariant after initialized) |
---|
260 | | - * @lock: lock for node fields |
---|
261 | | - * @work: worklist element for node work |
---|
262 | | - * (protected by @proc->inner_lock) |
---|
263 | | - * @rb_node: element for proc->nodes tree |
---|
264 | | - * (protected by @proc->inner_lock) |
---|
265 | | - * @dead_node: element for binder_dead_nodes list |
---|
266 | | - * (protected by binder_dead_nodes_lock) |
---|
267 | | - * @proc: binder_proc that owns this node |
---|
268 | | - * (invariant after initialized) |
---|
269 | | - * @refs: list of references on this node |
---|
270 | | - * (protected by @lock) |
---|
271 | | - * @internal_strong_refs: used to take strong references when |
---|
272 | | - * initiating a transaction |
---|
273 | | - * (protected by @proc->inner_lock if @proc |
---|
274 | | - * and by @lock) |
---|
275 | | - * @local_weak_refs: weak user refs from local process |
---|
276 | | - * (protected by @proc->inner_lock if @proc |
---|
277 | | - * and by @lock) |
---|
278 | | - * @local_strong_refs: strong user refs from local process |
---|
279 | | - * (protected by @proc->inner_lock if @proc |
---|
280 | | - * and by @lock) |
---|
281 | | - * @tmp_refs: temporary kernel refs |
---|
282 | | - * (protected by @proc->inner_lock while @proc |
---|
283 | | - * is valid, and by binder_dead_nodes_lock |
---|
284 | | - * if @proc is NULL. During inc/dec and node release |
---|
285 | | - * it is also protected by @lock to provide safety |
---|
286 | | - * as the node dies and @proc becomes NULL) |
---|
287 | | - * @ptr: userspace pointer for node |
---|
288 | | - * (invariant, no lock needed) |
---|
289 | | - * @cookie: userspace cookie for node |
---|
290 | | - * (invariant, no lock needed) |
---|
291 | | - * @has_strong_ref: userspace notified of strong ref |
---|
292 | | - * (protected by @proc->inner_lock if @proc |
---|
293 | | - * and by @lock) |
---|
294 | | - * @pending_strong_ref: userspace has acked notification of strong ref |
---|
295 | | - * (protected by @proc->inner_lock if @proc |
---|
296 | | - * and by @lock) |
---|
297 | | - * @has_weak_ref: userspace notified of weak ref |
---|
298 | | - * (protected by @proc->inner_lock if @proc |
---|
299 | | - * and by @lock) |
---|
300 | | - * @pending_weak_ref: userspace has acked notification of weak ref |
---|
301 | | - * (protected by @proc->inner_lock if @proc |
---|
302 | | - * and by @lock) |
---|
303 | | - * @has_async_transaction: async transaction to node in progress |
---|
304 | | - * (protected by @lock) |
---|
305 | | - * @sched_policy: minimum scheduling policy for node |
---|
306 | | - * (invariant after initialized) |
---|
307 | | - * @accept_fds: file descriptor operations supported for node |
---|
308 | | - * (invariant after initialized) |
---|
309 | | - * @min_priority: minimum scheduling priority |
---|
310 | | - * (invariant after initialized) |
---|
311 | | - * @inherit_rt: inherit RT scheduling policy from caller |
---|
312 | | - * @txn_security_ctx: require sender's security context |
---|
313 | | - * (invariant after initialized) |
---|
314 | | - * @async_todo: list of async work items |
---|
315 | | - * (protected by @proc->inner_lock) |
---|
316 | | - * |
---|
317 | | - * Bookkeeping structure for binder nodes. |
---|
318 | | - */ |
---|
319 | | -struct binder_node { |
---|
320 | | - int debug_id; |
---|
321 | | - spinlock_t lock; |
---|
322 | | - struct binder_work work; |
---|
323 | | - union { |
---|
324 | | - struct rb_node rb_node; |
---|
325 | | - struct hlist_node dead_node; |
---|
326 | | - }; |
---|
327 | | - struct binder_proc *proc; |
---|
328 | | - struct hlist_head refs; |
---|
329 | | - int internal_strong_refs; |
---|
330 | | - int local_weak_refs; |
---|
331 | | - int local_strong_refs; |
---|
332 | | - int tmp_refs; |
---|
333 | | - binder_uintptr_t ptr; |
---|
334 | | - binder_uintptr_t cookie; |
---|
335 | | - struct { |
---|
336 | | - /* |
---|
337 | | - * bitfield elements protected by |
---|
338 | | - * proc inner_lock |
---|
339 | | - */ |
---|
340 | | - u8 has_strong_ref:1; |
---|
341 | | - u8 pending_strong_ref:1; |
---|
342 | | - u8 has_weak_ref:1; |
---|
343 | | - u8 pending_weak_ref:1; |
---|
344 | | - }; |
---|
345 | | - struct { |
---|
346 | | - /* |
---|
347 | | - * invariant after initialization |
---|
348 | | - */ |
---|
349 | | - u8 sched_policy:2; |
---|
350 | | - u8 inherit_rt:1; |
---|
351 | | - u8 accept_fds:1; |
---|
352 | | - u8 txn_security_ctx:1; |
---|
353 | | - u8 min_priority; |
---|
354 | | - }; |
---|
355 | | - bool has_async_transaction; |
---|
356 | | - struct list_head async_todo; |
---|
357 | | -}; |
---|
358 | | - |
---|
359 | | -struct binder_ref_death { |
---|
360 | | - /** |
---|
361 | | - * @work: worklist element for death notifications |
---|
362 | | - * (protected by inner_lock of the proc that |
---|
363 | | - * this ref belongs to) |
---|
364 | | - */ |
---|
365 | | - struct binder_work work; |
---|
366 | | - binder_uintptr_t cookie; |
---|
367 | | -}; |
---|
368 | | - |
---|
369 | | -/** |
---|
370 | | - * struct binder_ref_data - binder_ref counts and id |
---|
371 | | - * @debug_id: unique ID for the ref |
---|
372 | | - * @desc: unique userspace handle for ref |
---|
373 | | - * @strong: strong ref count (debugging only if not locked) |
---|
374 | | - * @weak: weak ref count (debugging only if not locked) |
---|
375 | | - * |
---|
376 | | - * Structure to hold ref count and ref id information. Since |
---|
377 | | - * the actual ref can only be accessed with a lock, this structure |
---|
378 | | - * is used to return information about the ref to callers of |
---|
379 | | - * ref inc/dec functions. |
---|
380 | | - */ |
---|
381 | | -struct binder_ref_data { |
---|
382 | | - int debug_id; |
---|
383 | | - uint32_t desc; |
---|
384 | | - int strong; |
---|
385 | | - int weak; |
---|
386 | | -}; |
---|
387 | | - |
---|
388 | | -/** |
---|
389 | | - * struct binder_ref - struct to track references on nodes |
---|
390 | | - * @data: binder_ref_data containing id, handle, and current refcounts |
---|
391 | | - * @rb_node_desc: node for lookup by @data.desc in proc's rb_tree |
---|
392 | | - * @rb_node_node: node for lookup by @node in proc's rb_tree |
---|
393 | | - * @node_entry: list entry for node->refs list in target node |
---|
394 | | - * (protected by @node->lock) |
---|
395 | | - * @proc: binder_proc containing ref |
---|
396 | | - * @node: binder_node of target node. When cleaning up a |
---|
397 | | - * ref for deletion in binder_cleanup_ref, a non-NULL |
---|
398 | | - * @node indicates the node must be freed |
---|
399 | | - * @death: pointer to death notification (ref_death) if requested |
---|
400 | | - * (protected by @node->lock) |
---|
401 | | - * |
---|
402 | | - * Structure to track references from procA to target node (on procB). This |
---|
403 | | - * structure is unsafe to access without holding @proc->outer_lock. |
---|
404 | | - */ |
---|
405 | | -struct binder_ref { |
---|
406 | | - /* Lookups needed: */ |
---|
407 | | - /* node + proc => ref (transaction) */ |
---|
408 | | - /* desc + proc => ref (transaction, inc/dec ref) */ |
---|
409 | | - /* node => refs + procs (proc exit) */ |
---|
410 | | - struct binder_ref_data data; |
---|
411 | | - struct rb_node rb_node_desc; |
---|
412 | | - struct rb_node rb_node_node; |
---|
413 | | - struct hlist_node node_entry; |
---|
414 | | - struct binder_proc *proc; |
---|
415 | | - struct binder_node *node; |
---|
416 | | - struct binder_ref_death *death; |
---|
417 | | -}; |
---|
418 | | - |
---|
419 | 223 | enum binder_deferred_state { |
---|
420 | | - BINDER_DEFERRED_PUT_FILES = 0x01, |
---|
421 | | - BINDER_DEFERRED_FLUSH = 0x02, |
---|
422 | | - BINDER_DEFERRED_RELEASE = 0x04, |
---|
423 | | -}; |
---|
424 | | - |
---|
425 | | -/** |
---|
426 | | - * struct binder_priority - scheduler policy and priority |
---|
427 | | - * @sched_policy scheduler policy |
---|
428 | | - * @prio [100..139] for SCHED_NORMAL, [0..99] for FIFO/RT |
---|
429 | | - * |
---|
430 | | - * The binder driver supports inheriting the following scheduler policies: |
---|
431 | | - * SCHED_NORMAL |
---|
432 | | - * SCHED_BATCH |
---|
433 | | - * SCHED_FIFO |
---|
434 | | - * SCHED_RR |
---|
435 | | - */ |
---|
436 | | -struct binder_priority { |
---|
437 | | - unsigned int sched_policy; |
---|
438 | | - int prio; |
---|
439 | | -}; |
---|
440 | | - |
---|
441 | | -/** |
---|
442 | | - * struct binder_proc - binder process bookkeeping |
---|
443 | | - * @proc_node: element for binder_procs list |
---|
444 | | - * @threads: rbtree of binder_threads in this proc |
---|
445 | | - * (protected by @inner_lock) |
---|
446 | | - * @nodes: rbtree of binder nodes associated with |
---|
447 | | - * this proc ordered by node->ptr |
---|
448 | | - * (protected by @inner_lock) |
---|
449 | | - * @refs_by_desc: rbtree of refs ordered by ref->desc |
---|
450 | | - * (protected by @outer_lock) |
---|
451 | | - * @refs_by_node: rbtree of refs ordered by ref->node |
---|
452 | | - * (protected by @outer_lock) |
---|
453 | | - * @waiting_threads: threads currently waiting for proc work |
---|
454 | | - * (protected by @inner_lock) |
---|
455 | | - * @pid PID of group_leader of process |
---|
456 | | - * (invariant after initialized) |
---|
457 | | - * @tsk task_struct for group_leader of process |
---|
458 | | - * (invariant after initialized) |
---|
459 | | - * @files files_struct for process |
---|
460 | | - * (protected by @files_lock) |
---|
461 | | - * @files_lock mutex to protect @files |
---|
462 | | - * @cred struct cred associated with the `struct file` |
---|
463 | | - * in binder_open() |
---|
464 | | - * (invariant after initialized) |
---|
465 | | - * @deferred_work_node: element for binder_deferred_list |
---|
466 | | - * (protected by binder_deferred_lock) |
---|
467 | | - * @deferred_work: bitmap of deferred work to perform |
---|
468 | | - * (protected by binder_deferred_lock) |
---|
469 | | - * @is_dead: process is dead and awaiting free |
---|
470 | | - * when outstanding transactions are cleaned up |
---|
471 | | - * (protected by @inner_lock) |
---|
472 | | - * @todo: list of work for this process |
---|
473 | | - * (protected by @inner_lock) |
---|
474 | | - * @stats: per-process binder statistics |
---|
475 | | - * (atomics, no lock needed) |
---|
476 | | - * @delivered_death: list of delivered death notification |
---|
477 | | - * (protected by @inner_lock) |
---|
478 | | - * @max_threads: cap on number of binder threads |
---|
479 | | - * (protected by @inner_lock) |
---|
480 | | - * @requested_threads: number of binder threads requested but not |
---|
481 | | - * yet started. In current implementation, can |
---|
482 | | - * only be 0 or 1. |
---|
483 | | - * (protected by @inner_lock) |
---|
484 | | - * @requested_threads_started: number binder threads started |
---|
485 | | - * (protected by @inner_lock) |
---|
486 | | - * @tmp_ref: temporary reference to indicate proc is in use |
---|
487 | | - * (protected by @inner_lock) |
---|
488 | | - * @default_priority: default scheduler priority |
---|
489 | | - * (invariant after initialized) |
---|
490 | | - * @debugfs_entry: debugfs node |
---|
491 | | - * @alloc: binder allocator bookkeeping |
---|
492 | | - * @context: binder_context for this proc |
---|
493 | | - * (invariant after initialized) |
---|
494 | | - * @inner_lock: can nest under outer_lock and/or node lock |
---|
495 | | - * @outer_lock: no nesting under innor or node lock |
---|
496 | | - * Lock order: 1) outer, 2) node, 3) inner |
---|
497 | | - * @binderfs_entry: process-specific binderfs log file |
---|
498 | | - * |
---|
499 | | - * Bookkeeping structure for binder processes |
---|
500 | | - */ |
---|
501 | | -struct binder_proc { |
---|
502 | | - struct hlist_node proc_node; |
---|
503 | | - struct rb_root threads; |
---|
504 | | - struct rb_root nodes; |
---|
505 | | - struct rb_root refs_by_desc; |
---|
506 | | - struct rb_root refs_by_node; |
---|
507 | | - struct list_head waiting_threads; |
---|
508 | | - int pid; |
---|
509 | | - struct task_struct *tsk; |
---|
510 | | - struct files_struct *files; |
---|
511 | | - struct mutex files_lock; |
---|
512 | | - const struct cred *cred; |
---|
513 | | - struct hlist_node deferred_work_node; |
---|
514 | | - int deferred_work; |
---|
515 | | - bool is_dead; |
---|
516 | | - |
---|
517 | | - struct list_head todo; |
---|
518 | | - struct binder_stats stats; |
---|
519 | | - struct list_head delivered_death; |
---|
520 | | - int max_threads; |
---|
521 | | - int requested_threads; |
---|
522 | | - int requested_threads_started; |
---|
523 | | - int tmp_ref; |
---|
524 | | - struct binder_priority default_priority; |
---|
525 | | - struct dentry *debugfs_entry; |
---|
526 | | - struct binder_alloc alloc; |
---|
527 | | - struct binder_context *context; |
---|
528 | | - spinlock_t inner_lock; |
---|
529 | | - spinlock_t outer_lock; |
---|
530 | | - struct dentry *binderfs_entry; |
---|
| 224 | + BINDER_DEFERRED_FLUSH = 0x01, |
---|
| 225 | + BINDER_DEFERRED_RELEASE = 0x02, |
---|
531 | 226 | }; |
---|
532 | 227 | |
---|
533 | 228 | enum { |
---|
.. | .. |
---|
540 | 235 | }; |
---|
541 | 236 | |
---|
542 | 237 | /** |
---|
543 | | - * struct binder_thread - binder thread bookkeeping |
---|
544 | | - * @proc: binder process for this thread |
---|
545 | | - * (invariant after initialization) |
---|
546 | | - * @rb_node: element for proc->threads rbtree |
---|
547 | | - * (protected by @proc->inner_lock) |
---|
548 | | - * @waiting_thread_node: element for @proc->waiting_threads list |
---|
549 | | - * (protected by @proc->inner_lock) |
---|
550 | | - * @pid: PID for this thread |
---|
551 | | - * (invariant after initialization) |
---|
552 | | - * @looper: bitmap of looping state |
---|
553 | | - * (only accessed by this thread) |
---|
554 | | - * @looper_needs_return: looping thread needs to exit driver |
---|
555 | | - * (no lock needed) |
---|
556 | | - * @transaction_stack: stack of in-progress transactions for this thread |
---|
557 | | - * (protected by @proc->inner_lock) |
---|
558 | | - * @todo: list of work to do for this thread |
---|
559 | | - * (protected by @proc->inner_lock) |
---|
560 | | - * @process_todo: whether work in @todo should be processed |
---|
561 | | - * (protected by @proc->inner_lock) |
---|
562 | | - * @return_error: transaction errors reported by this thread |
---|
563 | | - * (only accessed by this thread) |
---|
564 | | - * @reply_error: transaction errors reported by target thread |
---|
565 | | - * (protected by @proc->inner_lock) |
---|
566 | | - * @wait: wait queue for thread work |
---|
567 | | - * @stats: per-thread statistics |
---|
568 | | - * (atomics, no lock needed) |
---|
569 | | - * @tmp_ref: temporary reference to indicate thread is in use |
---|
570 | | - * (atomic since @proc->inner_lock cannot |
---|
571 | | - * always be acquired) |
---|
572 | | - * @is_dead: thread is dead and awaiting free |
---|
573 | | - * when outstanding transactions are cleaned up |
---|
574 | | - * (protected by @proc->inner_lock) |
---|
575 | | - * @task: struct task_struct for this thread |
---|
576 | | - * |
---|
577 | | - * Bookkeeping structure for binder threads. |
---|
578 | | - */ |
---|
579 | | -struct binder_thread { |
---|
580 | | - struct binder_proc *proc; |
---|
581 | | - struct rb_node rb_node; |
---|
582 | | - struct list_head waiting_thread_node; |
---|
583 | | - int pid; |
---|
584 | | - int looper; /* only modified by this thread */ |
---|
585 | | - bool looper_need_return; /* can be written by other thread */ |
---|
586 | | - struct binder_transaction *transaction_stack; |
---|
587 | | - struct list_head todo; |
---|
588 | | - bool process_todo; |
---|
589 | | - struct binder_error return_error; |
---|
590 | | - struct binder_error reply_error; |
---|
591 | | - wait_queue_head_t wait; |
---|
592 | | - struct binder_stats stats; |
---|
593 | | - atomic_t tmp_ref; |
---|
594 | | - bool is_dead; |
---|
595 | | - struct task_struct *task; |
---|
596 | | -}; |
---|
597 | | - |
---|
598 | | -struct binder_transaction { |
---|
599 | | - int debug_id; |
---|
600 | | - struct binder_work work; |
---|
601 | | - struct binder_thread *from; |
---|
602 | | - struct binder_transaction *from_parent; |
---|
603 | | - struct binder_proc *to_proc; |
---|
604 | | - struct binder_thread *to_thread; |
---|
605 | | - struct binder_transaction *to_parent; |
---|
606 | | - unsigned need_reply:1; |
---|
607 | | - /* unsigned is_dead:1; */ /* not used at the moment */ |
---|
608 | | - |
---|
609 | | - struct binder_buffer *buffer; |
---|
610 | | - unsigned int code; |
---|
611 | | - unsigned int flags; |
---|
612 | | - struct binder_priority priority; |
---|
613 | | - struct binder_priority saved_priority; |
---|
614 | | - bool set_priority_called; |
---|
615 | | - kuid_t sender_euid; |
---|
616 | | - binder_uintptr_t security_ctx; |
---|
617 | | - /** |
---|
618 | | - * @lock: protects @from, @to_proc, and @to_thread |
---|
619 | | - * |
---|
620 | | - * @from, @to_proc, and @to_thread can be set to NULL |
---|
621 | | - * during thread teardown |
---|
622 | | - */ |
---|
623 | | - spinlock_t lock; |
---|
624 | | -}; |
---|
625 | | - |
---|
626 | | -/** |
---|
627 | | - * struct binder_object - union of flat binder object types |
---|
628 | | - * @hdr: generic object header |
---|
629 | | - * @fbo: binder object (nodes and refs) |
---|
630 | | - * @fdo: file descriptor object |
---|
631 | | - * @bbo: binder buffer pointer |
---|
632 | | - * @fdao: file descriptor array |
---|
633 | | - * |
---|
634 | | - * Used for type-independent object copies |
---|
635 | | - */ |
---|
636 | | -struct binder_object { |
---|
637 | | - union { |
---|
638 | | - struct binder_object_header hdr; |
---|
639 | | - struct flat_binder_object fbo; |
---|
640 | | - struct binder_fd_object fdo; |
---|
641 | | - struct binder_buffer_object bbo; |
---|
642 | | - struct binder_fd_array_object fdao; |
---|
643 | | - }; |
---|
644 | | -}; |
---|
645 | | - |
---|
646 | | -/** |
---|
647 | 238 | * binder_proc_lock() - Acquire outer lock for given binder_proc |
---|
648 | 239 | * @proc: struct binder_proc to acquire |
---|
649 | 240 | * |
---|
.. | .. |
---|
653 | 244 | #define binder_proc_lock(proc) _binder_proc_lock(proc, __LINE__) |
---|
654 | 245 | static void |
---|
655 | 246 | _binder_proc_lock(struct binder_proc *proc, int line) |
---|
| 247 | + __acquires(&proc->outer_lock) |
---|
656 | 248 | { |
---|
657 | 249 | binder_debug(BINDER_DEBUG_SPINLOCKS, |
---|
658 | 250 | "%s: line=%d\n", __func__, line); |
---|
.. | .. |
---|
668 | 260 | #define binder_proc_unlock(_proc) _binder_proc_unlock(_proc, __LINE__) |
---|
669 | 261 | static void |
---|
670 | 262 | _binder_proc_unlock(struct binder_proc *proc, int line) |
---|
| 263 | + __releases(&proc->outer_lock) |
---|
671 | 264 | { |
---|
672 | 265 | binder_debug(BINDER_DEBUG_SPINLOCKS, |
---|
673 | 266 | "%s: line=%d\n", __func__, line); |
---|
.. | .. |
---|
683 | 276 | #define binder_inner_proc_lock(proc) _binder_inner_proc_lock(proc, __LINE__) |
---|
684 | 277 | static void |
---|
685 | 278 | _binder_inner_proc_lock(struct binder_proc *proc, int line) |
---|
| 279 | + __acquires(&proc->inner_lock) |
---|
686 | 280 | { |
---|
687 | 281 | binder_debug(BINDER_DEBUG_SPINLOCKS, |
---|
688 | 282 | "%s: line=%d\n", __func__, line); |
---|
.. | .. |
---|
698 | 292 | #define binder_inner_proc_unlock(proc) _binder_inner_proc_unlock(proc, __LINE__) |
---|
699 | 293 | static void |
---|
700 | 294 | _binder_inner_proc_unlock(struct binder_proc *proc, int line) |
---|
| 295 | + __releases(&proc->inner_lock) |
---|
701 | 296 | { |
---|
702 | 297 | binder_debug(BINDER_DEBUG_SPINLOCKS, |
---|
703 | 298 | "%s: line=%d\n", __func__, line); |
---|
.. | .. |
---|
713 | 308 | #define binder_node_lock(node) _binder_node_lock(node, __LINE__) |
---|
714 | 309 | static void |
---|
715 | 310 | _binder_node_lock(struct binder_node *node, int line) |
---|
| 311 | + __acquires(&node->lock) |
---|
716 | 312 | { |
---|
717 | 313 | binder_debug(BINDER_DEBUG_SPINLOCKS, |
---|
718 | 314 | "%s: line=%d\n", __func__, line); |
---|
.. | .. |
---|
728 | 324 | #define binder_node_unlock(node) _binder_node_unlock(node, __LINE__) |
---|
729 | 325 | static void |
---|
730 | 326 | _binder_node_unlock(struct binder_node *node, int line) |
---|
| 327 | + __releases(&node->lock) |
---|
731 | 328 | { |
---|
732 | 329 | binder_debug(BINDER_DEBUG_SPINLOCKS, |
---|
733 | 330 | "%s: line=%d\n", __func__, line); |
---|
.. | .. |
---|
744 | 341 | #define binder_node_inner_lock(node) _binder_node_inner_lock(node, __LINE__) |
---|
745 | 342 | static void |
---|
746 | 343 | _binder_node_inner_lock(struct binder_node *node, int line) |
---|
| 344 | + __acquires(&node->lock) __acquires(&node->proc->inner_lock) |
---|
747 | 345 | { |
---|
748 | 346 | binder_debug(BINDER_DEBUG_SPINLOCKS, |
---|
749 | 347 | "%s: line=%d\n", __func__, line); |
---|
750 | 348 | spin_lock(&node->lock); |
---|
751 | 349 | if (node->proc) |
---|
752 | 350 | binder_inner_proc_lock(node->proc); |
---|
| 351 | + else |
---|
| 352 | + /* annotation for sparse */ |
---|
| 353 | + __acquire(&node->proc->inner_lock); |
---|
753 | 354 | } |
---|
754 | 355 | |
---|
755 | 356 | /** |
---|
.. | .. |
---|
761 | 362 | #define binder_node_inner_unlock(node) _binder_node_inner_unlock(node, __LINE__) |
---|
762 | 363 | static void |
---|
763 | 364 | _binder_node_inner_unlock(struct binder_node *node, int line) |
---|
| 365 | + __releases(&node->lock) __releases(&node->proc->inner_lock) |
---|
764 | 366 | { |
---|
765 | 367 | struct binder_proc *proc = node->proc; |
---|
766 | 368 | |
---|
.. | .. |
---|
768 | 370 | "%s: line=%d\n", __func__, line); |
---|
769 | 371 | if (proc) |
---|
770 | 372 | binder_inner_proc_unlock(proc); |
---|
| 373 | + else |
---|
| 374 | + /* annotation for sparse */ |
---|
| 375 | + __release(&node->proc->inner_lock); |
---|
771 | 376 | spin_unlock(&node->lock); |
---|
772 | 377 | } |
---|
773 | 378 | |
---|
.. | .. |
---|
907 | 512 | static void binder_free_proc(struct binder_proc *proc); |
---|
908 | 513 | static void binder_inc_node_tmpref_ilocked(struct binder_node *node); |
---|
909 | 514 | |
---|
910 | | -static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) |
---|
911 | | -{ |
---|
912 | | - unsigned long rlim_cur; |
---|
913 | | - unsigned long irqs; |
---|
914 | | - int ret; |
---|
915 | | - |
---|
916 | | - mutex_lock(&proc->files_lock); |
---|
917 | | - if (proc->files == NULL) { |
---|
918 | | - ret = -ESRCH; |
---|
919 | | - goto err; |
---|
920 | | - } |
---|
921 | | - if (!lock_task_sighand(proc->tsk, &irqs)) { |
---|
922 | | - ret = -EMFILE; |
---|
923 | | - goto err; |
---|
924 | | - } |
---|
925 | | - rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE); |
---|
926 | | - unlock_task_sighand(proc->tsk, &irqs); |
---|
927 | | - |
---|
928 | | - ret = __alloc_fd(proc->files, 0, rlim_cur, flags); |
---|
929 | | -err: |
---|
930 | | - mutex_unlock(&proc->files_lock); |
---|
931 | | - return ret; |
---|
932 | | -} |
---|
933 | | - |
---|
934 | | -/* |
---|
935 | | - * copied from fd_install |
---|
936 | | - */ |
---|
937 | | -static void task_fd_install( |
---|
938 | | - struct binder_proc *proc, unsigned int fd, struct file *file) |
---|
939 | | -{ |
---|
940 | | - mutex_lock(&proc->files_lock); |
---|
941 | | - if (proc->files) |
---|
942 | | - __fd_install(proc->files, fd, file); |
---|
943 | | - mutex_unlock(&proc->files_lock); |
---|
944 | | -} |
---|
945 | | - |
---|
946 | | -/* |
---|
947 | | - * copied from sys_close |
---|
948 | | - */ |
---|
949 | | -static long task_close_fd(struct binder_proc *proc, unsigned int fd) |
---|
950 | | -{ |
---|
951 | | - int retval; |
---|
952 | | - |
---|
953 | | - mutex_lock(&proc->files_lock); |
---|
954 | | - if (proc->files == NULL) { |
---|
955 | | - retval = -ESRCH; |
---|
956 | | - goto err; |
---|
957 | | - } |
---|
958 | | - retval = __close_fd(proc->files, fd); |
---|
959 | | - /* can't restart close syscall because file table entry was cleared */ |
---|
960 | | - if (unlikely(retval == -ERESTARTSYS || |
---|
961 | | - retval == -ERESTARTNOINTR || |
---|
962 | | - retval == -ERESTARTNOHAND || |
---|
963 | | - retval == -ERESTART_RESTARTBLOCK)) |
---|
964 | | - retval = -EINTR; |
---|
965 | | -err: |
---|
966 | | - mutex_unlock(&proc->files_lock); |
---|
967 | | - return retval; |
---|
968 | | -} |
---|
969 | | - |
---|
970 | 515 | static bool binder_has_work_ilocked(struct binder_thread *thread, |
---|
971 | 516 | bool do_proc_work) |
---|
972 | 517 | { |
---|
| 518 | + int ret = 0; |
---|
| 519 | + |
---|
| 520 | + trace_android_vh_binder_has_work_ilocked(thread, do_proc_work, &ret); |
---|
| 521 | + if (ret) |
---|
| 522 | + return true; |
---|
973 | 523 | return thread->process_todo || |
---|
974 | 524 | thread->looper_need_return || |
---|
975 | 525 | (do_proc_work && |
---|
.. | .. |
---|
1005 | 555 | thread = rb_entry(n, struct binder_thread, rb_node); |
---|
1006 | 556 | if (thread->looper & BINDER_LOOPER_STATE_POLL && |
---|
1007 | 557 | binder_available_for_proc_work_ilocked(thread)) { |
---|
| 558 | + trace_android_vh_binder_wakeup_ilocked(thread->task, sync, proc); |
---|
1008 | 559 | if (sync) |
---|
1009 | 560 | wake_up_interruptible_sync(&thread->wait); |
---|
1010 | 561 | else |
---|
.. | .. |
---|
1064 | 615 | assert_spin_locked(&proc->inner_lock); |
---|
1065 | 616 | |
---|
1066 | 617 | if (thread) { |
---|
| 618 | + trace_android_vh_binder_wakeup_ilocked(thread->task, sync, proc); |
---|
1067 | 619 | if (sync) |
---|
1068 | 620 | wake_up_interruptible_sync(&thread->wait); |
---|
1069 | 621 | else |
---|
.. | .. |
---|
1206 | 758 | bool inherit_rt) |
---|
1207 | 759 | { |
---|
1208 | 760 | struct binder_priority desired_prio = t->priority; |
---|
| 761 | + bool skip = false; |
---|
1209 | 762 | |
---|
1210 | 763 | if (t->set_priority_called) |
---|
1211 | 764 | return; |
---|
.. | .. |
---|
1213 | 766 | t->set_priority_called = true; |
---|
1214 | 767 | t->saved_priority.sched_policy = task->policy; |
---|
1215 | 768 | t->saved_priority.prio = task->normal_prio; |
---|
| 769 | + |
---|
| 770 | + trace_android_vh_binder_priority_skip(task, &skip); |
---|
| 771 | + if (skip) |
---|
| 772 | + return; |
---|
1216 | 773 | |
---|
1217 | 774 | if (!inherit_rt && is_rt_policy(desired_prio.sched_policy)) { |
---|
1218 | 775 | desired_prio.prio = NICE_TO_PRIO(0); |
---|
.. | .. |
---|
1233 | 790 | } |
---|
1234 | 791 | |
---|
1235 | 792 | binder_set_priority(task, desired_prio); |
---|
| 793 | + trace_android_vh_binder_set_priority(t, task); |
---|
1236 | 794 | } |
---|
1237 | 795 | |
---|
1238 | 796 | static struct binder_node *binder_get_node_ilocked(struct binder_proc *proc, |
---|
.. | .. |
---|
1545 | 1103 | binder_node_inner_lock(node); |
---|
1546 | 1104 | if (!node->proc) |
---|
1547 | 1105 | spin_lock(&binder_dead_nodes_lock); |
---|
| 1106 | + else |
---|
| 1107 | + __acquire(&binder_dead_nodes_lock); |
---|
1548 | 1108 | node->tmp_refs--; |
---|
1549 | 1109 | BUG_ON(node->tmp_refs < 0); |
---|
1550 | 1110 | if (!node->proc) |
---|
1551 | 1111 | spin_unlock(&binder_dead_nodes_lock); |
---|
| 1112 | + else |
---|
| 1113 | + __release(&binder_dead_nodes_lock); |
---|
1552 | 1114 | /* |
---|
1553 | 1115 | * Call binder_dec_node() to check if all refcounts are 0 |
---|
1554 | 1116 | * and cleanup is needed. Calling with strong=0 and internal=1 |
---|
.. | .. |
---|
1669 | 1231 | "%d new ref %d desc %d for node %d\n", |
---|
1670 | 1232 | proc->pid, new_ref->data.debug_id, new_ref->data.desc, |
---|
1671 | 1233 | node->debug_id); |
---|
| 1234 | + trace_android_vh_binder_new_ref(proc->tsk, new_ref->data.desc, new_ref->node->debug_id); |
---|
1672 | 1235 | binder_node_unlock(node); |
---|
1673 | 1236 | return new_ref; |
---|
1674 | 1237 | } |
---|
.. | .. |
---|
1836 | 1399 | */ |
---|
1837 | 1400 | static void binder_free_ref(struct binder_ref *ref) |
---|
1838 | 1401 | { |
---|
| 1402 | + trace_android_vh_binder_del_ref(ref->proc ? ref->proc->tsk : NULL, |
---|
| 1403 | + ref->data.desc); |
---|
1839 | 1404 | if (ref->node) |
---|
1840 | 1405 | binder_free_node(ref->node); |
---|
1841 | 1406 | kfree(ref->death); |
---|
.. | .. |
---|
1940 | 1505 | } |
---|
1941 | 1506 | ret = binder_inc_ref_olocked(ref, strong, target_list); |
---|
1942 | 1507 | *rdata = ref->data; |
---|
| 1508 | + if (ret && ref == new_ref) { |
---|
| 1509 | + /* |
---|
| 1510 | + * Cleanup the failed reference here as the target |
---|
| 1511 | + * could now be dead and have already released its |
---|
| 1512 | + * references by now. Calling on the new reference |
---|
| 1513 | + * with strong=0 and a tmp_refs will not decrement |
---|
| 1514 | + * the node. The new_ref gets kfree'd below. |
---|
| 1515 | + */ |
---|
| 1516 | + binder_cleanup_ref_olocked(new_ref); |
---|
| 1517 | + ref = NULL; |
---|
| 1518 | + } |
---|
| 1519 | + |
---|
1943 | 1520 | binder_proc_unlock(proc); |
---|
1944 | 1521 | if (new_ref && ref != new_ref) |
---|
1945 | 1522 | /* |
---|
.. | .. |
---|
2051 | 1628 | */ |
---|
2052 | 1629 | static struct binder_thread *binder_get_txn_from_and_acq_inner( |
---|
2053 | 1630 | struct binder_transaction *t) |
---|
| 1631 | + __acquires(&t->from->proc->inner_lock) |
---|
2054 | 1632 | { |
---|
2055 | 1633 | struct binder_thread *from; |
---|
2056 | 1634 | |
---|
2057 | 1635 | from = binder_get_txn_from(t); |
---|
2058 | | - if (!from) |
---|
| 1636 | + if (!from) { |
---|
| 1637 | + __acquire(&from->proc->inner_lock); |
---|
2059 | 1638 | return NULL; |
---|
| 1639 | + } |
---|
2060 | 1640 | binder_inner_proc_lock(from->proc); |
---|
2061 | 1641 | if (t->from) { |
---|
2062 | 1642 | BUG_ON(from != t->from); |
---|
2063 | 1643 | return from; |
---|
2064 | 1644 | } |
---|
2065 | 1645 | binder_inner_proc_unlock(from->proc); |
---|
| 1646 | + __acquire(&from->proc->inner_lock); |
---|
2066 | 1647 | binder_thread_dec_tmpref(from); |
---|
2067 | 1648 | return NULL; |
---|
| 1649 | +} |
---|
| 1650 | + |
---|
| 1651 | +/** |
---|
| 1652 | + * binder_free_txn_fixups() - free unprocessed fd fixups |
---|
| 1653 | + * @t: binder transaction for t->from |
---|
| 1654 | + * |
---|
| 1655 | + * If the transaction is being torn down prior to being |
---|
| 1656 | + * processed by the target process, free all of the |
---|
| 1657 | + * fd fixups and fput the file structs. It is safe to |
---|
| 1658 | + * call this function after the fixups have been |
---|
| 1659 | + * processed -- in that case, the list will be empty. |
---|
| 1660 | + */ |
---|
| 1661 | +static void binder_free_txn_fixups(struct binder_transaction *t) |
---|
| 1662 | +{ |
---|
| 1663 | + struct binder_txn_fd_fixup *fixup, *tmp; |
---|
| 1664 | + |
---|
| 1665 | + list_for_each_entry_safe(fixup, tmp, &t->fd_fixups, fixup_entry) { |
---|
| 1666 | + fput(fixup->file); |
---|
| 1667 | + list_del(&fixup->fixup_entry); |
---|
| 1668 | + kfree(fixup); |
---|
| 1669 | + } |
---|
2068 | 1670 | } |
---|
2069 | 1671 | |
---|
2070 | 1672 | static void binder_free_transaction(struct binder_transaction *t) |
---|
.. | .. |
---|
2073 | 1675 | |
---|
2074 | 1676 | if (target_proc) { |
---|
2075 | 1677 | binder_inner_proc_lock(target_proc); |
---|
| 1678 | + target_proc->outstanding_txns--; |
---|
| 1679 | + if (target_proc->outstanding_txns < 0) |
---|
| 1680 | + pr_warn("%s: Unexpected outstanding_txns %d\n", |
---|
| 1681 | + __func__, target_proc->outstanding_txns); |
---|
| 1682 | + if (!target_proc->outstanding_txns && target_proc->is_frozen) |
---|
| 1683 | + wake_up_interruptible_all(&target_proc->freeze_wait); |
---|
2076 | 1684 | if (t->buffer) |
---|
2077 | 1685 | t->buffer->transaction = NULL; |
---|
2078 | 1686 | binder_inner_proc_unlock(target_proc); |
---|
.. | .. |
---|
2081 | 1689 | * If the transaction has no target_proc, then |
---|
2082 | 1690 | * t->buffer->transaction has already been cleared. |
---|
2083 | 1691 | */ |
---|
| 1692 | + binder_free_txn_fixups(t); |
---|
2084 | 1693 | kfree(t); |
---|
2085 | 1694 | binder_stats_deleted(BINDER_STAT_TRANSACTION); |
---|
2086 | 1695 | } |
---|
.. | .. |
---|
2123 | 1732 | binder_free_transaction(t); |
---|
2124 | 1733 | return; |
---|
2125 | 1734 | } |
---|
| 1735 | + __release(&target_thread->proc->inner_lock); |
---|
2126 | 1736 | next = t->from_parent; |
---|
2127 | 1737 | |
---|
2128 | 1738 | binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, |
---|
.. | .. |
---|
2165 | 1775 | /** |
---|
2166 | 1776 | * binder_get_object() - gets object and checks for valid metadata |
---|
2167 | 1777 | * @proc: binder_proc owning the buffer |
---|
| 1778 | + * @u: sender's user pointer to base of buffer |
---|
2168 | 1779 | * @buffer: binder_buffer that we're parsing. |
---|
2169 | 1780 | * @offset: offset in the @buffer at which to validate an object. |
---|
2170 | 1781 | * @object: struct binder_object to read into |
---|
2171 | 1782 | * |
---|
2172 | | - * Return: If there's a valid metadata object at @offset in @buffer, the |
---|
| 1783 | + * Copy the binder object at the given offset into @object. If @u is |
---|
| 1784 | + * provided then the copy is from the sender's buffer. If not, then |
---|
| 1785 | + * it is copied from the target's @buffer. |
---|
| 1786 | + * |
---|
| 1787 | + * Return: If there's a valid metadata object at @offset, the |
---|
2173 | 1788 | * size of that object. Otherwise, it returns zero. The object |
---|
2174 | 1789 | * is read into the struct binder_object pointed to by @object. |
---|
2175 | 1790 | */ |
---|
2176 | 1791 | static size_t binder_get_object(struct binder_proc *proc, |
---|
| 1792 | + const void __user *u, |
---|
2177 | 1793 | struct binder_buffer *buffer, |
---|
2178 | 1794 | unsigned long offset, |
---|
2179 | 1795 | struct binder_object *object) |
---|
.. | .. |
---|
2183 | 1799 | size_t object_size = 0; |
---|
2184 | 1800 | |
---|
2185 | 1801 | read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset); |
---|
2186 | | - if (offset > buffer->data_size || read_size < sizeof(*hdr) || |
---|
2187 | | - !IS_ALIGNED(offset, sizeof(u32))) |
---|
| 1802 | + if (offset > buffer->data_size || read_size < sizeof(*hdr)) |
---|
2188 | 1803 | return 0; |
---|
2189 | | - binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, |
---|
2190 | | - offset, read_size); |
---|
| 1804 | + if (u) { |
---|
| 1805 | + if (copy_from_user(object, u + offset, read_size)) |
---|
| 1806 | + return 0; |
---|
| 1807 | + } else { |
---|
| 1808 | + if (binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, |
---|
| 1809 | + offset, read_size)) |
---|
| 1810 | + return 0; |
---|
| 1811 | + } |
---|
2191 | 1812 | |
---|
2192 | 1813 | /* Ok, now see if we read a complete object. */ |
---|
2193 | 1814 | hdr = &object->hdr; |
---|
.. | .. |
---|
2256 | 1877 | return NULL; |
---|
2257 | 1878 | |
---|
2258 | 1879 | buffer_offset = start_offset + sizeof(binder_size_t) * index; |
---|
2259 | | - binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, |
---|
2260 | | - b, buffer_offset, sizeof(object_offset)); |
---|
2261 | | - object_size = binder_get_object(proc, b, object_offset, object); |
---|
| 1880 | + if (binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, |
---|
| 1881 | + b, buffer_offset, |
---|
| 1882 | + sizeof(object_offset))) |
---|
| 1883 | + return NULL; |
---|
| 1884 | + object_size = binder_get_object(proc, NULL, b, object_offset, object); |
---|
2262 | 1885 | if (!object_size || object->hdr.type != BINDER_TYPE_PTR) |
---|
2263 | 1886 | return NULL; |
---|
2264 | 1887 | if (object_offsetp) |
---|
.. | .. |
---|
2323 | 1946 | unsigned long buffer_offset; |
---|
2324 | 1947 | struct binder_object last_object; |
---|
2325 | 1948 | struct binder_buffer_object *last_bbo; |
---|
2326 | | - size_t object_size = binder_get_object(proc, b, last_obj_offset, |
---|
| 1949 | + size_t object_size = binder_get_object(proc, NULL, b, |
---|
| 1950 | + last_obj_offset, |
---|
2327 | 1951 | &last_object); |
---|
2328 | 1952 | if (object_size != sizeof(*last_bbo)) |
---|
2329 | 1953 | return false; |
---|
.. | .. |
---|
2337 | 1961 | return false; |
---|
2338 | 1962 | last_min_offset = last_bbo->parent_offset + sizeof(uintptr_t); |
---|
2339 | 1963 | buffer_offset = objects_start_offset + |
---|
2340 | | - sizeof(binder_size_t) * last_bbo->parent, |
---|
2341 | | - binder_alloc_copy_from_buffer(&proc->alloc, &last_obj_offset, |
---|
2342 | | - b, buffer_offset, |
---|
2343 | | - sizeof(last_obj_offset)); |
---|
| 1964 | + sizeof(binder_size_t) * last_bbo->parent; |
---|
| 1965 | + if (binder_alloc_copy_from_buffer(&proc->alloc, |
---|
| 1966 | + &last_obj_offset, |
---|
| 1967 | + b, buffer_offset, |
---|
| 1968 | + sizeof(last_obj_offset))) |
---|
| 1969 | + return false; |
---|
2344 | 1970 | } |
---|
2345 | 1971 | return (fixup_offset >= last_min_offset); |
---|
2346 | 1972 | } |
---|
2347 | 1973 | |
---|
| 1974 | +/** |
---|
| 1975 | + * struct binder_task_work_cb - for deferred close |
---|
| 1976 | + * |
---|
| 1977 | + * @twork: callback_head for task work |
---|
| 1978 | + * @fd: fd to close |
---|
| 1979 | + * |
---|
| 1980 | + * Structure to pass task work to be handled after |
---|
| 1981 | + * returning from binder_ioctl() via task_work_add(). |
---|
| 1982 | + */ |
---|
| 1983 | +struct binder_task_work_cb { |
---|
| 1984 | + struct callback_head twork; |
---|
| 1985 | + struct file *file; |
---|
| 1986 | +}; |
---|
| 1987 | + |
---|
| 1988 | +/** |
---|
| 1989 | + * binder_do_fd_close() - close list of file descriptors |
---|
| 1990 | + * @twork: callback head for task work |
---|
| 1991 | + * |
---|
| 1992 | + * It is not safe to call ksys_close() during the binder_ioctl() |
---|
| 1993 | + * function if there is a chance that binder's own file descriptor |
---|
| 1994 | + * might be closed. This is to meet the requirements for using |
---|
| 1995 | + * fdget() (see comments for __fget_light()). Therefore use |
---|
| 1996 | + * task_work_add() to schedule the close operation once we have |
---|
| 1997 | + * returned from binder_ioctl(). This function is a callback |
---|
| 1998 | + * for that mechanism and does the actual ksys_close() on the |
---|
| 1999 | + * given file descriptor. |
---|
| 2000 | + */ |
---|
| 2001 | +static void binder_do_fd_close(struct callback_head *twork) |
---|
| 2002 | +{ |
---|
| 2003 | + struct binder_task_work_cb *twcb = container_of(twork, |
---|
| 2004 | + struct binder_task_work_cb, twork); |
---|
| 2005 | + |
---|
| 2006 | + fput(twcb->file); |
---|
| 2007 | + kfree(twcb); |
---|
| 2008 | +} |
---|
| 2009 | + |
---|
| 2010 | +/** |
---|
| 2011 | + * binder_deferred_fd_close() - schedule a close for the given file-descriptor |
---|
| 2012 | + * @fd: file-descriptor to close |
---|
| 2013 | + * |
---|
| 2014 | + * See comments in binder_do_fd_close(). This function is used to schedule |
---|
| 2015 | + * a file-descriptor to be closed after returning from binder_ioctl(). |
---|
| 2016 | + */ |
---|
| 2017 | +static void binder_deferred_fd_close(int fd) |
---|
| 2018 | +{ |
---|
| 2019 | + struct binder_task_work_cb *twcb; |
---|
| 2020 | + |
---|
| 2021 | + twcb = kzalloc(sizeof(*twcb), GFP_KERNEL); |
---|
| 2022 | + if (!twcb) |
---|
| 2023 | + return; |
---|
| 2024 | + init_task_work(&twcb->twork, binder_do_fd_close); |
---|
| 2025 | + close_fd_get_file(fd, &twcb->file); |
---|
| 2026 | + if (twcb->file) { |
---|
| 2027 | + filp_close(twcb->file, current->files); |
---|
| 2028 | + task_work_add(current, &twcb->twork, TWA_RESUME); |
---|
| 2029 | + } else { |
---|
| 2030 | + kfree(twcb); |
---|
| 2031 | + } |
---|
| 2032 | +} |
---|
| 2033 | + |
---|
2348 | 2034 | static void binder_transaction_buffer_release(struct binder_proc *proc, |
---|
| 2035 | + struct binder_thread *thread, |
---|
2349 | 2036 | struct binder_buffer *buffer, |
---|
2350 | | - binder_size_t failed_at, |
---|
| 2037 | + binder_size_t off_end_offset, |
---|
2351 | 2038 | bool is_failure) |
---|
2352 | 2039 | { |
---|
2353 | 2040 | int debug_id = buffer->debug_id; |
---|
2354 | | - binder_size_t off_start_offset, buffer_offset, off_end_offset; |
---|
| 2041 | + binder_size_t off_start_offset, buffer_offset; |
---|
2355 | 2042 | |
---|
2356 | 2043 | binder_debug(BINDER_DEBUG_TRANSACTION, |
---|
2357 | 2044 | "%d buffer release %d, size %zd-%zd, failed at %llx\n", |
---|
2358 | 2045 | proc->pid, buffer->debug_id, |
---|
2359 | 2046 | buffer->data_size, buffer->offsets_size, |
---|
2360 | | - (unsigned long long)failed_at); |
---|
| 2047 | + (unsigned long long)off_end_offset); |
---|
2361 | 2048 | |
---|
2362 | 2049 | if (buffer->target_node) |
---|
2363 | 2050 | binder_dec_node(buffer->target_node, 1, 0); |
---|
2364 | 2051 | |
---|
2365 | 2052 | off_start_offset = ALIGN(buffer->data_size, sizeof(void *)); |
---|
2366 | | - off_end_offset = is_failure ? failed_at : |
---|
2367 | | - off_start_offset + buffer->offsets_size; |
---|
| 2053 | + |
---|
2368 | 2054 | for (buffer_offset = off_start_offset; buffer_offset < off_end_offset; |
---|
2369 | 2055 | buffer_offset += sizeof(binder_size_t)) { |
---|
2370 | 2056 | struct binder_object_header *hdr; |
---|
2371 | | - size_t object_size; |
---|
| 2057 | + size_t object_size = 0; |
---|
2372 | 2058 | struct binder_object object; |
---|
2373 | 2059 | binder_size_t object_offset; |
---|
2374 | 2060 | |
---|
2375 | | - binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, |
---|
2376 | | - buffer, buffer_offset, |
---|
2377 | | - sizeof(object_offset)); |
---|
2378 | | - object_size = binder_get_object(proc, buffer, |
---|
2379 | | - object_offset, &object); |
---|
| 2061 | + if (!binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, |
---|
| 2062 | + buffer, buffer_offset, |
---|
| 2063 | + sizeof(object_offset))) |
---|
| 2064 | + object_size = binder_get_object(proc, NULL, buffer, |
---|
| 2065 | + object_offset, &object); |
---|
2380 | 2066 | if (object_size == 0) { |
---|
2381 | 2067 | pr_err("transaction release %d bad object at offset %lld, size %zd\n", |
---|
2382 | 2068 | debug_id, (u64)object_offset, buffer->data_size); |
---|
.. | .. |
---|
2424 | 2110 | } break; |
---|
2425 | 2111 | |
---|
2426 | 2112 | case BINDER_TYPE_FD: { |
---|
2427 | | - struct binder_fd_object *fp = to_binder_fd_object(hdr); |
---|
2428 | | - |
---|
2429 | | - binder_debug(BINDER_DEBUG_TRANSACTION, |
---|
2430 | | - " fd %d\n", fp->fd); |
---|
2431 | | - if (failed_at) |
---|
2432 | | - task_close_fd(proc, fp->fd); |
---|
| 2113 | + /* |
---|
| 2114 | + * No need to close the file here since user-space |
---|
| 2115 | + * closes it for for successfully delivered |
---|
| 2116 | + * transactions. For transactions that weren't |
---|
| 2117 | + * delivered, the new fd was never allocated so |
---|
| 2118 | + * there is no need to close and the fput on the |
---|
| 2119 | + * file is done when the transaction is torn |
---|
| 2120 | + * down. |
---|
| 2121 | + */ |
---|
2433 | 2122 | } break; |
---|
2434 | 2123 | case BINDER_TYPE_PTR: |
---|
2435 | 2124 | /* |
---|
.. | .. |
---|
2445 | 2134 | size_t fd_index; |
---|
2446 | 2135 | binder_size_t fd_buf_size; |
---|
2447 | 2136 | binder_size_t num_valid; |
---|
| 2137 | + |
---|
| 2138 | + if (is_failure) { |
---|
| 2139 | + /* |
---|
| 2140 | + * The fd fixups have not been applied so no |
---|
| 2141 | + * fds need to be closed. |
---|
| 2142 | + */ |
---|
| 2143 | + continue; |
---|
| 2144 | + } |
---|
2448 | 2145 | |
---|
2449 | 2146 | num_valid = (buffer_offset - off_start_offset) / |
---|
2450 | 2147 | sizeof(binder_size_t); |
---|
.. | .. |
---|
2485 | 2182 | for (fd_index = 0; fd_index < fda->num_fds; |
---|
2486 | 2183 | fd_index++) { |
---|
2487 | 2184 | u32 fd; |
---|
| 2185 | + int err; |
---|
2488 | 2186 | binder_size_t offset = fda_offset + |
---|
2489 | 2187 | fd_index * sizeof(fd); |
---|
2490 | 2188 | |
---|
2491 | | - binder_alloc_copy_from_buffer(&proc->alloc, |
---|
2492 | | - &fd, |
---|
2493 | | - buffer, |
---|
2494 | | - offset, |
---|
2495 | | - sizeof(fd)); |
---|
2496 | | - task_close_fd(proc, fd); |
---|
| 2189 | + err = binder_alloc_copy_from_buffer( |
---|
| 2190 | + &proc->alloc, &fd, buffer, |
---|
| 2191 | + offset, sizeof(fd)); |
---|
| 2192 | + WARN_ON(err); |
---|
| 2193 | + if (!err) { |
---|
| 2194 | + binder_deferred_fd_close(fd); |
---|
| 2195 | + /* |
---|
| 2196 | + * Need to make sure the thread goes |
---|
| 2197 | + * back to userspace to complete the |
---|
| 2198 | + * deferred close |
---|
| 2199 | + */ |
---|
| 2200 | + if (thread) |
---|
| 2201 | + thread->looper_need_return = true; |
---|
| 2202 | + } |
---|
2497 | 2203 | } |
---|
2498 | 2204 | } break; |
---|
2499 | 2205 | default: |
---|
.. | .. |
---|
2502 | 2208 | break; |
---|
2503 | 2209 | } |
---|
2504 | 2210 | } |
---|
| 2211 | +} |
---|
| 2212 | + |
---|
| 2213 | +/* Clean up all the objects in the buffer */ |
---|
| 2214 | +static inline void binder_release_entire_buffer(struct binder_proc *proc, |
---|
| 2215 | + struct binder_thread *thread, |
---|
| 2216 | + struct binder_buffer *buffer, |
---|
| 2217 | + bool is_failure) |
---|
| 2218 | +{ |
---|
| 2219 | + binder_size_t off_end_offset; |
---|
| 2220 | + |
---|
| 2221 | + off_end_offset = ALIGN(buffer->data_size, sizeof(void *)); |
---|
| 2222 | + off_end_offset += buffer->offsets_size; |
---|
| 2223 | + |
---|
| 2224 | + binder_transaction_buffer_release(proc, thread, buffer, |
---|
| 2225 | + off_end_offset, is_failure); |
---|
2505 | 2226 | } |
---|
2506 | 2227 | |
---|
2507 | 2228 | static int binder_translate_binder(struct flat_binder_object *fp, |
---|
.. | .. |
---|
2528 | 2249 | ret = -EINVAL; |
---|
2529 | 2250 | goto done; |
---|
2530 | 2251 | } |
---|
2531 | | - if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { |
---|
| 2252 | + if (security_binder_transfer_binder(binder_get_cred(proc), |
---|
| 2253 | + binder_get_cred(target_proc))) { |
---|
2532 | 2254 | ret = -EPERM; |
---|
2533 | 2255 | goto done; |
---|
2534 | 2256 | } |
---|
.. | .. |
---|
2574 | 2296 | proc->pid, thread->pid, fp->handle); |
---|
2575 | 2297 | return -EINVAL; |
---|
2576 | 2298 | } |
---|
2577 | | - if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { |
---|
| 2299 | + if (security_binder_transfer_binder(binder_get_cred(proc), |
---|
| 2300 | + binder_get_cred(target_proc))) { |
---|
2578 | 2301 | ret = -EPERM; |
---|
2579 | 2302 | goto done; |
---|
2580 | 2303 | } |
---|
.. | .. |
---|
2589 | 2312 | fp->cookie = node->cookie; |
---|
2590 | 2313 | if (node->proc) |
---|
2591 | 2314 | binder_inner_proc_lock(node->proc); |
---|
| 2315 | + else |
---|
| 2316 | + __acquire(&node->proc->inner_lock); |
---|
2592 | 2317 | binder_inc_node_nilocked(node, |
---|
2593 | 2318 | fp->hdr.type == BINDER_TYPE_BINDER, |
---|
2594 | 2319 | 0, NULL); |
---|
2595 | 2320 | if (node->proc) |
---|
2596 | 2321 | binder_inner_proc_unlock(node->proc); |
---|
| 2322 | + else |
---|
| 2323 | + __release(&node->proc->inner_lock); |
---|
2597 | 2324 | trace_binder_transaction_ref_to_node(t, node, &src_rdata); |
---|
2598 | 2325 | binder_debug(BINDER_DEBUG_TRANSACTION, |
---|
2599 | 2326 | " ref %d desc %d -> node %d u%016llx\n", |
---|
.. | .. |
---|
2626 | 2353 | return ret; |
---|
2627 | 2354 | } |
---|
2628 | 2355 | |
---|
2629 | | -static int binder_translate_fd(int fd, |
---|
| 2356 | +static int binder_translate_fd(u32 fd, binder_size_t fd_offset, |
---|
2630 | 2357 | struct binder_transaction *t, |
---|
2631 | 2358 | struct binder_thread *thread, |
---|
2632 | 2359 | struct binder_transaction *in_reply_to) |
---|
2633 | 2360 | { |
---|
2634 | 2361 | struct binder_proc *proc = thread->proc; |
---|
2635 | 2362 | struct binder_proc *target_proc = t->to_proc; |
---|
2636 | | - int target_fd; |
---|
| 2363 | + struct binder_txn_fd_fixup *fixup; |
---|
2637 | 2364 | struct file *file; |
---|
2638 | | - int ret; |
---|
| 2365 | + int ret = 0; |
---|
2639 | 2366 | bool target_allows_fd; |
---|
2640 | 2367 | |
---|
2641 | 2368 | if (in_reply_to) |
---|
.. | .. |
---|
2658 | 2385 | ret = -EBADF; |
---|
2659 | 2386 | goto err_fget; |
---|
2660 | 2387 | } |
---|
2661 | | - ret = security_binder_transfer_file(proc->cred, target_proc->cred, file); |
---|
| 2388 | + ret = security_binder_transfer_file(binder_get_cred(proc), |
---|
| 2389 | + binder_get_cred(target_proc), file); |
---|
2662 | 2390 | if (ret < 0) { |
---|
2663 | 2391 | ret = -EPERM; |
---|
2664 | 2392 | goto err_security; |
---|
2665 | 2393 | } |
---|
2666 | 2394 | |
---|
2667 | | - target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC); |
---|
2668 | | - if (target_fd < 0) { |
---|
| 2395 | + /* |
---|
| 2396 | + * Add fixup record for this transaction. The allocation |
---|
| 2397 | + * of the fd in the target needs to be done from a |
---|
| 2398 | + * target thread. |
---|
| 2399 | + */ |
---|
| 2400 | + fixup = kzalloc(sizeof(*fixup), GFP_KERNEL); |
---|
| 2401 | + if (!fixup) { |
---|
2669 | 2402 | ret = -ENOMEM; |
---|
2670 | | - goto err_get_unused_fd; |
---|
| 2403 | + goto err_alloc; |
---|
2671 | 2404 | } |
---|
2672 | | - task_fd_install(target_proc, target_fd, file); |
---|
2673 | | - trace_binder_transaction_fd(t, fd, target_fd); |
---|
2674 | | - binder_debug(BINDER_DEBUG_TRANSACTION, " fd %d -> %d\n", |
---|
2675 | | - fd, target_fd); |
---|
| 2405 | + fixup->file = file; |
---|
| 2406 | + fixup->offset = fd_offset; |
---|
| 2407 | + trace_binder_transaction_fd_send(t, fd, fixup->offset); |
---|
| 2408 | + list_add_tail(&fixup->fixup_entry, &t->fd_fixups); |
---|
2676 | 2409 | |
---|
2677 | | - return target_fd; |
---|
| 2410 | + return ret; |
---|
2678 | 2411 | |
---|
2679 | | -err_get_unused_fd: |
---|
| 2412 | +err_alloc: |
---|
2680 | 2413 | err_security: |
---|
2681 | 2414 | fput(file); |
---|
2682 | 2415 | err_fget: |
---|
.. | .. |
---|
2684 | 2417 | return ret; |
---|
2685 | 2418 | } |
---|
2686 | 2419 | |
---|
2687 | | -static int binder_translate_fd_array(struct binder_fd_array_object *fda, |
---|
| 2420 | +/** |
---|
| 2421 | + * struct binder_ptr_fixup - data to be fixed-up in target buffer |
---|
| 2422 | + * @offset offset in target buffer to fixup |
---|
| 2423 | + * @skip_size bytes to skip in copy (fixup will be written later) |
---|
| 2424 | + * @fixup_data data to write at fixup offset |
---|
| 2425 | + * @node list node |
---|
| 2426 | + * |
---|
| 2427 | + * This is used for the pointer fixup list (pf) which is created and consumed |
---|
| 2428 | + * during binder_transaction() and is only accessed locally. No |
---|
| 2429 | + * locking is necessary. |
---|
| 2430 | + * |
---|
| 2431 | + * The list is ordered by @offset. |
---|
| 2432 | + */ |
---|
| 2433 | +struct binder_ptr_fixup { |
---|
| 2434 | + binder_size_t offset; |
---|
| 2435 | + size_t skip_size; |
---|
| 2436 | + binder_uintptr_t fixup_data; |
---|
| 2437 | + struct list_head node; |
---|
| 2438 | +}; |
---|
| 2439 | + |
---|
| 2440 | +/** |
---|
| 2441 | + * struct binder_sg_copy - scatter-gather data to be copied |
---|
| 2442 | + * @offset offset in target buffer |
---|
| 2443 | + * @sender_uaddr user address in source buffer |
---|
| 2444 | + * @length bytes to copy |
---|
| 2445 | + * @node list node |
---|
| 2446 | + * |
---|
| 2447 | + * This is used for the sg copy list (sgc) which is created and consumed |
---|
| 2448 | + * during binder_transaction() and is only accessed locally. No |
---|
| 2449 | + * locking is necessary. |
---|
| 2450 | + * |
---|
| 2451 | + * The list is ordered by @offset. |
---|
| 2452 | + */ |
---|
| 2453 | +struct binder_sg_copy { |
---|
| 2454 | + binder_size_t offset; |
---|
| 2455 | + const void __user *sender_uaddr; |
---|
| 2456 | + size_t length; |
---|
| 2457 | + struct list_head node; |
---|
| 2458 | +}; |
---|
| 2459 | + |
---|
| 2460 | +/** |
---|
| 2461 | + * binder_do_deferred_txn_copies() - copy and fixup scatter-gather data |
---|
| 2462 | + * @alloc: binder_alloc associated with @buffer |
---|
| 2463 | + * @buffer: binder buffer in target process |
---|
| 2464 | + * @sgc_head: list_head of scatter-gather copy list |
---|
| 2465 | + * @pf_head: list_head of pointer fixup list |
---|
| 2466 | + * |
---|
| 2467 | + * Processes all elements of @sgc_head, applying fixups from @pf_head |
---|
| 2468 | + * and copying the scatter-gather data from the source process' user |
---|
| 2469 | + * buffer to the target's buffer. It is expected that the list creation |
---|
| 2470 | + * and processing all occurs during binder_transaction() so these lists |
---|
| 2471 | + * are only accessed in local context. |
---|
| 2472 | + * |
---|
| 2473 | + * Return: 0=success, else -errno |
---|
| 2474 | + */ |
---|
| 2475 | +static int binder_do_deferred_txn_copies(struct binder_alloc *alloc, |
---|
| 2476 | + struct binder_buffer *buffer, |
---|
| 2477 | + struct list_head *sgc_head, |
---|
| 2478 | + struct list_head *pf_head) |
---|
| 2479 | +{ |
---|
| 2480 | + int ret = 0; |
---|
| 2481 | + struct binder_sg_copy *sgc, *tmpsgc; |
---|
| 2482 | + struct binder_ptr_fixup *tmppf; |
---|
| 2483 | + struct binder_ptr_fixup *pf = |
---|
| 2484 | + list_first_entry_or_null(pf_head, struct binder_ptr_fixup, |
---|
| 2485 | + node); |
---|
| 2486 | + |
---|
| 2487 | + list_for_each_entry_safe(sgc, tmpsgc, sgc_head, node) { |
---|
| 2488 | + size_t bytes_copied = 0; |
---|
| 2489 | + |
---|
| 2490 | + while (bytes_copied < sgc->length) { |
---|
| 2491 | + size_t copy_size; |
---|
| 2492 | + size_t bytes_left = sgc->length - bytes_copied; |
---|
| 2493 | + size_t offset = sgc->offset + bytes_copied; |
---|
| 2494 | + |
---|
| 2495 | + /* |
---|
| 2496 | + * We copy up to the fixup (pointed to by pf) |
---|
| 2497 | + */ |
---|
| 2498 | + copy_size = pf ? min(bytes_left, (size_t)pf->offset - offset) |
---|
| 2499 | + : bytes_left; |
---|
| 2500 | + if (!ret && copy_size) |
---|
| 2501 | + ret = binder_alloc_copy_user_to_buffer( |
---|
| 2502 | + alloc, buffer, |
---|
| 2503 | + offset, |
---|
| 2504 | + sgc->sender_uaddr + bytes_copied, |
---|
| 2505 | + copy_size); |
---|
| 2506 | + bytes_copied += copy_size; |
---|
| 2507 | + if (copy_size != bytes_left) { |
---|
| 2508 | + BUG_ON(!pf); |
---|
| 2509 | + /* we stopped at a fixup offset */ |
---|
| 2510 | + if (pf->skip_size) { |
---|
| 2511 | + /* |
---|
| 2512 | + * we are just skipping. This is for |
---|
| 2513 | + * BINDER_TYPE_FDA where the translated |
---|
| 2514 | + * fds will be fixed up when we get |
---|
| 2515 | + * to target context. |
---|
| 2516 | + */ |
---|
| 2517 | + bytes_copied += pf->skip_size; |
---|
| 2518 | + } else { |
---|
| 2519 | + /* apply the fixup indicated by pf */ |
---|
| 2520 | + if (!ret) |
---|
| 2521 | + ret = binder_alloc_copy_to_buffer( |
---|
| 2522 | + alloc, buffer, |
---|
| 2523 | + pf->offset, |
---|
| 2524 | + &pf->fixup_data, |
---|
| 2525 | + sizeof(pf->fixup_data)); |
---|
| 2526 | + bytes_copied += sizeof(pf->fixup_data); |
---|
| 2527 | + } |
---|
| 2528 | + list_del(&pf->node); |
---|
| 2529 | + kfree(pf); |
---|
| 2530 | + pf = list_first_entry_or_null(pf_head, |
---|
| 2531 | + struct binder_ptr_fixup, node); |
---|
| 2532 | + } |
---|
| 2533 | + } |
---|
| 2534 | + list_del(&sgc->node); |
---|
| 2535 | + kfree(sgc); |
---|
| 2536 | + } |
---|
| 2537 | + list_for_each_entry_safe(pf, tmppf, pf_head, node) { |
---|
| 2538 | + BUG_ON(pf->skip_size == 0); |
---|
| 2539 | + list_del(&pf->node); |
---|
| 2540 | + kfree(pf); |
---|
| 2541 | + } |
---|
| 2542 | + BUG_ON(!list_empty(sgc_head)); |
---|
| 2543 | + |
---|
| 2544 | + return ret > 0 ? -EINVAL : ret; |
---|
| 2545 | +} |
---|
| 2546 | + |
---|
| 2547 | +/** |
---|
| 2548 | + * binder_cleanup_deferred_txn_lists() - free specified lists |
---|
| 2549 | + * @sgc_head: list_head of scatter-gather copy list |
---|
| 2550 | + * @pf_head: list_head of pointer fixup list |
---|
| 2551 | + * |
---|
| 2552 | + * Called to clean up @sgc_head and @pf_head if there is an |
---|
| 2553 | + * error. |
---|
| 2554 | + */ |
---|
| 2555 | +static void binder_cleanup_deferred_txn_lists(struct list_head *sgc_head, |
---|
| 2556 | + struct list_head *pf_head) |
---|
| 2557 | +{ |
---|
| 2558 | + struct binder_sg_copy *sgc, *tmpsgc; |
---|
| 2559 | + struct binder_ptr_fixup *pf, *tmppf; |
---|
| 2560 | + |
---|
| 2561 | + list_for_each_entry_safe(sgc, tmpsgc, sgc_head, node) { |
---|
| 2562 | + list_del(&sgc->node); |
---|
| 2563 | + kfree(sgc); |
---|
| 2564 | + } |
---|
| 2565 | + list_for_each_entry_safe(pf, tmppf, pf_head, node) { |
---|
| 2566 | + list_del(&pf->node); |
---|
| 2567 | + kfree(pf); |
---|
| 2568 | + } |
---|
| 2569 | +} |
---|
| 2570 | + |
---|
| 2571 | +/** |
---|
| 2572 | + * binder_defer_copy() - queue a scatter-gather buffer for copy |
---|
| 2573 | + * @sgc_head: list_head of scatter-gather copy list |
---|
| 2574 | + * @offset: binder buffer offset in target process |
---|
| 2575 | + * @sender_uaddr: user address in source process |
---|
| 2576 | + * @length: bytes to copy |
---|
| 2577 | + * |
---|
| 2578 | + * Specify a scatter-gather block to be copied. The actual copy must |
---|
| 2579 | + * be deferred until all the needed fixups are identified and queued. |
---|
| 2580 | + * Then the copy and fixups are done together so un-translated values |
---|
| 2581 | + * from the source are never visible in the target buffer. |
---|
| 2582 | + * |
---|
| 2583 | + * We are guaranteed that repeated calls to this function will have |
---|
| 2584 | + * monotonically increasing @offset values so the list will naturally |
---|
| 2585 | + * be ordered. |
---|
| 2586 | + * |
---|
| 2587 | + * Return: 0=success, else -errno |
---|
| 2588 | + */ |
---|
| 2589 | +static int binder_defer_copy(struct list_head *sgc_head, binder_size_t offset, |
---|
| 2590 | + const void __user *sender_uaddr, size_t length) |
---|
| 2591 | +{ |
---|
| 2592 | + struct binder_sg_copy *bc = kzalloc(sizeof(*bc), GFP_KERNEL); |
---|
| 2593 | + |
---|
| 2594 | + if (!bc) |
---|
| 2595 | + return -ENOMEM; |
---|
| 2596 | + |
---|
| 2597 | + bc->offset = offset; |
---|
| 2598 | + bc->sender_uaddr = sender_uaddr; |
---|
| 2599 | + bc->length = length; |
---|
| 2600 | + INIT_LIST_HEAD(&bc->node); |
---|
| 2601 | + |
---|
| 2602 | + /* |
---|
| 2603 | + * We are guaranteed that the deferred copies are in-order |
---|
| 2604 | + * so just add to the tail. |
---|
| 2605 | + */ |
---|
| 2606 | + list_add_tail(&bc->node, sgc_head); |
---|
| 2607 | + |
---|
| 2608 | + return 0; |
---|
| 2609 | +} |
---|
| 2610 | + |
---|
| 2611 | +/** |
---|
| 2612 | + * binder_add_fixup() - queue a fixup to be applied to sg copy |
---|
| 2613 | + * @pf_head: list_head of binder ptr fixup list |
---|
| 2614 | + * @offset: binder buffer offset in target process |
---|
| 2615 | + * @fixup: bytes to be copied for fixup |
---|
| 2616 | + * @skip_size: bytes to skip when copying (fixup will be applied later) |
---|
| 2617 | + * |
---|
| 2618 | + * Add the specified fixup to a list ordered by @offset. When copying |
---|
| 2619 | + * the scatter-gather buffers, the fixup will be copied instead of |
---|
| 2620 | + * data from the source buffer. For BINDER_TYPE_FDA fixups, the fixup |
---|
| 2621 | + * will be applied later (in target process context), so we just skip |
---|
| 2622 | + * the bytes specified by @skip_size. If @skip_size is 0, we copy the |
---|
| 2623 | + * value in @fixup. |
---|
| 2624 | + * |
---|
| 2625 | + * This function is called *mostly* in @offset order, but there are |
---|
| 2626 | + * exceptions. Since out-of-order inserts are relatively uncommon, |
---|
| 2627 | + * we insert the new element by searching backward from the tail of |
---|
| 2628 | + * the list. |
---|
| 2629 | + * |
---|
| 2630 | + * Return: 0=success, else -errno |
---|
| 2631 | + */ |
---|
| 2632 | +static int binder_add_fixup(struct list_head *pf_head, binder_size_t offset, |
---|
| 2633 | + binder_uintptr_t fixup, size_t skip_size) |
---|
| 2634 | +{ |
---|
| 2635 | + struct binder_ptr_fixup *pf = kzalloc(sizeof(*pf), GFP_KERNEL); |
---|
| 2636 | + struct binder_ptr_fixup *tmppf; |
---|
| 2637 | + |
---|
| 2638 | + if (!pf) |
---|
| 2639 | + return -ENOMEM; |
---|
| 2640 | + |
---|
| 2641 | + pf->offset = offset; |
---|
| 2642 | + pf->fixup_data = fixup; |
---|
| 2643 | + pf->skip_size = skip_size; |
---|
| 2644 | + INIT_LIST_HEAD(&pf->node); |
---|
| 2645 | + |
---|
| 2646 | + /* Fixups are *mostly* added in-order, but there are some |
---|
| 2647 | + * exceptions. Look backwards through list for insertion point. |
---|
| 2648 | + */ |
---|
| 2649 | + list_for_each_entry_reverse(tmppf, pf_head, node) { |
---|
| 2650 | + if (tmppf->offset < pf->offset) { |
---|
| 2651 | + list_add(&pf->node, &tmppf->node); |
---|
| 2652 | + return 0; |
---|
| 2653 | + } |
---|
| 2654 | + } |
---|
| 2655 | + /* |
---|
| 2656 | + * if we get here, then the new offset is the lowest so |
---|
| 2657 | + * insert at the head |
---|
| 2658 | + */ |
---|
| 2659 | + list_add(&pf->node, pf_head); |
---|
| 2660 | + return 0; |
---|
| 2661 | +} |
---|
| 2662 | + |
---|
| 2663 | +static int binder_translate_fd_array(struct list_head *pf_head, |
---|
| 2664 | + struct binder_fd_array_object *fda, |
---|
| 2665 | + const void __user *sender_ubuffer, |
---|
2688 | 2666 | struct binder_buffer_object *parent, |
---|
| 2667 | + struct binder_buffer_object *sender_uparent, |
---|
2689 | 2668 | struct binder_transaction *t, |
---|
2690 | 2669 | struct binder_thread *thread, |
---|
2691 | 2670 | struct binder_transaction *in_reply_to) |
---|
2692 | 2671 | { |
---|
2693 | | - binder_size_t fdi, fd_buf_size, num_installed_fds; |
---|
| 2672 | + binder_size_t fdi, fd_buf_size; |
---|
2694 | 2673 | binder_size_t fda_offset; |
---|
2695 | | - int target_fd; |
---|
| 2674 | + const void __user *sender_ufda_base; |
---|
2696 | 2675 | struct binder_proc *proc = thread->proc; |
---|
2697 | | - struct binder_proc *target_proc = t->to_proc; |
---|
| 2676 | + int ret; |
---|
| 2677 | + |
---|
| 2678 | + if (fda->num_fds == 0) |
---|
| 2679 | + return 0; |
---|
2698 | 2680 | |
---|
2699 | 2681 | fd_buf_size = sizeof(u32) * fda->num_fds; |
---|
2700 | 2682 | if (fda->num_fds >= SIZE_MAX / sizeof(u32)) { |
---|
.. | .. |
---|
2718 | 2700 | */ |
---|
2719 | 2701 | fda_offset = (parent->buffer - (uintptr_t)t->buffer->user_data) + |
---|
2720 | 2702 | fda->parent_offset; |
---|
2721 | | - if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32))) { |
---|
| 2703 | + sender_ufda_base = (void __user *)(uintptr_t)sender_uparent->buffer + |
---|
| 2704 | + fda->parent_offset; |
---|
| 2705 | + |
---|
| 2706 | + if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32)) || |
---|
| 2707 | + !IS_ALIGNED((unsigned long)sender_ufda_base, sizeof(u32))) { |
---|
2722 | 2708 | binder_user_error("%d:%d parent offset not aligned correctly.\n", |
---|
2723 | 2709 | proc->pid, thread->pid); |
---|
2724 | 2710 | return -EINVAL; |
---|
2725 | 2711 | } |
---|
| 2712 | + ret = binder_add_fixup(pf_head, fda_offset, 0, fda->num_fds * sizeof(u32)); |
---|
| 2713 | + if (ret) |
---|
| 2714 | + return ret; |
---|
| 2715 | + |
---|
2726 | 2716 | for (fdi = 0; fdi < fda->num_fds; fdi++) { |
---|
2727 | 2717 | u32 fd; |
---|
2728 | | - |
---|
2729 | 2718 | binder_size_t offset = fda_offset + fdi * sizeof(fd); |
---|
| 2719 | + binder_size_t sender_uoffset = fdi * sizeof(fd); |
---|
2730 | 2720 | |
---|
2731 | | - binder_alloc_copy_from_buffer(&target_proc->alloc, |
---|
2732 | | - &fd, t->buffer, |
---|
2733 | | - offset, sizeof(fd)); |
---|
2734 | | - target_fd = binder_translate_fd(fd, t, thread, in_reply_to); |
---|
2735 | | - if (target_fd < 0) |
---|
2736 | | - goto err_translate_fd_failed; |
---|
2737 | | - binder_alloc_copy_to_buffer(&target_proc->alloc, |
---|
2738 | | - t->buffer, offset, |
---|
2739 | | - &target_fd, sizeof(fd)); |
---|
| 2721 | + ret = copy_from_user(&fd, sender_ufda_base + sender_uoffset, sizeof(fd)); |
---|
| 2722 | + if (!ret) |
---|
| 2723 | + ret = binder_translate_fd(fd, offset, t, thread, |
---|
| 2724 | + in_reply_to); |
---|
| 2725 | + if (ret) |
---|
| 2726 | + return ret > 0 ? -EINVAL : ret; |
---|
2740 | 2727 | } |
---|
2741 | 2728 | return 0; |
---|
2742 | | - |
---|
2743 | | -err_translate_fd_failed: |
---|
2744 | | - /* |
---|
2745 | | - * Failed to allocate fd or security error, free fds |
---|
2746 | | - * installed so far. |
---|
2747 | | - */ |
---|
2748 | | - num_installed_fds = fdi; |
---|
2749 | | - for (fdi = 0; fdi < num_installed_fds; fdi++) { |
---|
2750 | | - u32 fd; |
---|
2751 | | - binder_size_t offset = fda_offset + fdi * sizeof(fd); |
---|
2752 | | - binder_alloc_copy_from_buffer(&target_proc->alloc, |
---|
2753 | | - &fd, t->buffer, |
---|
2754 | | - offset, sizeof(fd)); |
---|
2755 | | - task_close_fd(target_proc, fd); |
---|
2756 | | - } |
---|
2757 | | - return target_fd; |
---|
2758 | 2729 | } |
---|
2759 | 2730 | |
---|
2760 | | -static int binder_fixup_parent(struct binder_transaction *t, |
---|
| 2731 | +static int binder_fixup_parent(struct list_head *pf_head, |
---|
| 2732 | + struct binder_transaction *t, |
---|
2761 | 2733 | struct binder_thread *thread, |
---|
2762 | 2734 | struct binder_buffer_object *bp, |
---|
2763 | 2735 | binder_size_t off_start_offset, |
---|
.. | .. |
---|
2803 | 2775 | } |
---|
2804 | 2776 | buffer_offset = bp->parent_offset + |
---|
2805 | 2777 | (uintptr_t)parent->buffer - (uintptr_t)b->user_data; |
---|
2806 | | - binder_alloc_copy_to_buffer(&target_proc->alloc, b, buffer_offset, |
---|
2807 | | - &bp->buffer, sizeof(bp->buffer)); |
---|
| 2778 | + return binder_add_fixup(pf_head, buffer_offset, bp->buffer, 0); |
---|
| 2779 | +} |
---|
2808 | 2780 | |
---|
2809 | | - return 0; |
---|
| 2781 | +/** |
---|
| 2782 | + * binder_can_update_transaction() - Can a txn be superseded by an updated one? |
---|
| 2783 | + * @t1: the pending async txn in the frozen process |
---|
| 2784 | + * @t2: the new async txn to supersede the outdated pending one |
---|
| 2785 | + * |
---|
| 2786 | + * Return: true if t2 can supersede t1 |
---|
| 2787 | + * false if t2 can not supersede t1 |
---|
| 2788 | + */ |
---|
| 2789 | +static bool binder_can_update_transaction(struct binder_transaction *t1, |
---|
| 2790 | + struct binder_transaction *t2) |
---|
| 2791 | +{ |
---|
| 2792 | + if ((t1->flags & t2->flags & (TF_ONE_WAY | TF_UPDATE_TXN)) != |
---|
| 2793 | + (TF_ONE_WAY | TF_UPDATE_TXN) || !t1->to_proc || !t2->to_proc) |
---|
| 2794 | + return false; |
---|
| 2795 | + if (t1->to_proc->tsk == t2->to_proc->tsk && t1->code == t2->code && |
---|
| 2796 | + t1->flags == t2->flags && t1->buffer->pid == t2->buffer->pid && |
---|
| 2797 | + t1->buffer->target_node->ptr == t2->buffer->target_node->ptr && |
---|
| 2798 | + t1->buffer->target_node->cookie == t2->buffer->target_node->cookie) |
---|
| 2799 | + return true; |
---|
| 2800 | + return false; |
---|
| 2801 | +} |
---|
| 2802 | + |
---|
| 2803 | +/** |
---|
| 2804 | + * binder_find_outdated_transaction_ilocked() - Find the outdated transaction |
---|
| 2805 | + * @t: new async transaction |
---|
| 2806 | + * @target_list: list to find outdated transaction |
---|
| 2807 | + * |
---|
| 2808 | + * Return: the outdated transaction if found |
---|
| 2809 | + * NULL if no outdated transacton can be found |
---|
| 2810 | + * |
---|
| 2811 | + * Requires the proc->inner_lock to be held. |
---|
| 2812 | + */ |
---|
| 2813 | +static struct binder_transaction * |
---|
| 2814 | +binder_find_outdated_transaction_ilocked(struct binder_transaction *t, |
---|
| 2815 | + struct list_head *target_list) |
---|
| 2816 | +{ |
---|
| 2817 | + struct binder_work *w; |
---|
| 2818 | + |
---|
| 2819 | + list_for_each_entry(w, target_list, entry) { |
---|
| 2820 | + struct binder_transaction *t_queued; |
---|
| 2821 | + |
---|
| 2822 | + if (w->type != BINDER_WORK_TRANSACTION) |
---|
| 2823 | + continue; |
---|
| 2824 | + t_queued = container_of(w, struct binder_transaction, work); |
---|
| 2825 | + if (binder_can_update_transaction(t_queued, t)) |
---|
| 2826 | + return t_queued; |
---|
| 2827 | + } |
---|
| 2828 | + return NULL; |
---|
2810 | 2829 | } |
---|
2811 | 2830 | |
---|
2812 | 2831 | /** |
---|
.. | .. |
---|
2823 | 2842 | * If the @thread parameter is not NULL, the transaction is always queued |
---|
2824 | 2843 | * to the waitlist of that specific thread. |
---|
2825 | 2844 | * |
---|
2826 | | - * Return: true if the transactions was successfully queued |
---|
2827 | | - * false if the target process or thread is dead |
---|
| 2845 | + * Return: 0 if the transaction was successfully queued |
---|
| 2846 | + * BR_DEAD_REPLY if the target process or thread is dead |
---|
| 2847 | + * BR_FROZEN_REPLY if the target process or thread is frozen |
---|
2828 | 2848 | */ |
---|
2829 | | -static bool binder_proc_transaction(struct binder_transaction *t, |
---|
| 2849 | +static int binder_proc_transaction(struct binder_transaction *t, |
---|
2830 | 2850 | struct binder_proc *proc, |
---|
2831 | 2851 | struct binder_thread *thread) |
---|
2832 | 2852 | { |
---|
.. | .. |
---|
2834 | 2854 | struct binder_priority node_prio; |
---|
2835 | 2855 | bool oneway = !!(t->flags & TF_ONE_WAY); |
---|
2836 | 2856 | bool pending_async = false; |
---|
| 2857 | + struct binder_transaction *t_outdated = NULL; |
---|
2837 | 2858 | |
---|
2838 | 2859 | BUG_ON(!node); |
---|
2839 | 2860 | binder_node_lock(node); |
---|
.. | .. |
---|
2842 | 2863 | |
---|
2843 | 2864 | if (oneway) { |
---|
2844 | 2865 | BUG_ON(thread); |
---|
2845 | | - if (node->has_async_transaction) { |
---|
| 2866 | + if (node->has_async_transaction) |
---|
2846 | 2867 | pending_async = true; |
---|
2847 | | - } else { |
---|
| 2868 | + else |
---|
2848 | 2869 | node->has_async_transaction = true; |
---|
2849 | | - } |
---|
2850 | 2870 | } |
---|
2851 | 2871 | |
---|
2852 | 2872 | binder_inner_proc_lock(proc); |
---|
| 2873 | + if (proc->is_frozen) { |
---|
| 2874 | + proc->sync_recv |= !oneway; |
---|
| 2875 | + proc->async_recv |= oneway; |
---|
| 2876 | + } |
---|
2853 | 2877 | |
---|
2854 | | - if (proc->is_dead || (thread && thread->is_dead)) { |
---|
| 2878 | + if ((proc->is_frozen && !oneway) || proc->is_dead || |
---|
| 2879 | + (thread && thread->is_dead)) { |
---|
2855 | 2880 | binder_inner_proc_unlock(proc); |
---|
2856 | 2881 | binder_node_unlock(node); |
---|
2857 | | - return false; |
---|
| 2882 | + return proc->is_frozen ? BR_FROZEN_REPLY : BR_DEAD_REPLY; |
---|
2858 | 2883 | } |
---|
2859 | 2884 | |
---|
2860 | 2885 | if (!thread && !pending_async) |
---|
2861 | 2886 | thread = binder_select_thread_ilocked(proc); |
---|
| 2887 | + |
---|
| 2888 | + trace_android_vh_binder_proc_transaction(current, proc->tsk, |
---|
| 2889 | + thread ? thread->task : NULL, node->debug_id, t->code, |
---|
| 2890 | + pending_async); |
---|
2862 | 2891 | |
---|
2863 | 2892 | if (thread) { |
---|
2864 | 2893 | binder_transaction_priority(thread->task, t, node_prio, |
---|
.. | .. |
---|
2867 | 2896 | } else if (!pending_async) { |
---|
2868 | 2897 | binder_enqueue_work_ilocked(&t->work, &proc->todo); |
---|
2869 | 2898 | } else { |
---|
| 2899 | + if ((t->flags & TF_UPDATE_TXN) && proc->is_frozen) { |
---|
| 2900 | + t_outdated = binder_find_outdated_transaction_ilocked(t, |
---|
| 2901 | + &node->async_todo); |
---|
| 2902 | + if (t_outdated) { |
---|
| 2903 | + binder_debug(BINDER_DEBUG_TRANSACTION, |
---|
| 2904 | + "txn %d supersedes %d\n", |
---|
| 2905 | + t->debug_id, t_outdated->debug_id); |
---|
| 2906 | + list_del_init(&t_outdated->work.entry); |
---|
| 2907 | + proc->outstanding_txns--; |
---|
| 2908 | + } |
---|
| 2909 | + } |
---|
2870 | 2910 | binder_enqueue_work_ilocked(&t->work, &node->async_todo); |
---|
2871 | 2911 | } |
---|
| 2912 | + |
---|
| 2913 | + trace_android_vh_binder_proc_transaction_end(current, proc->tsk, |
---|
| 2914 | + thread ? thread->task : NULL, t->code, pending_async, !oneway); |
---|
2872 | 2915 | |
---|
2873 | 2916 | if (!pending_async) |
---|
2874 | 2917 | binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */); |
---|
2875 | 2918 | |
---|
| 2919 | + proc->outstanding_txns++; |
---|
2876 | 2920 | binder_inner_proc_unlock(proc); |
---|
2877 | 2921 | binder_node_unlock(node); |
---|
2878 | 2922 | |
---|
2879 | | - return true; |
---|
| 2923 | + /* |
---|
| 2924 | + * To reduce potential contention, free the outdated transaction and |
---|
| 2925 | + * buffer after releasing the locks. |
---|
| 2926 | + */ |
---|
| 2927 | + if (t_outdated) { |
---|
| 2928 | + struct binder_buffer *buffer = t_outdated->buffer; |
---|
| 2929 | + |
---|
| 2930 | + t_outdated->buffer = NULL; |
---|
| 2931 | + buffer->transaction = NULL; |
---|
| 2932 | + trace_binder_transaction_update_buffer_release(buffer); |
---|
| 2933 | + binder_release_entire_buffer(proc, NULL, buffer, false); |
---|
| 2934 | + binder_alloc_free_buf(&proc->alloc, buffer); |
---|
| 2935 | + kfree(t_outdated); |
---|
| 2936 | + binder_stats_deleted(BINDER_STAT_TRANSACTION); |
---|
| 2937 | + } |
---|
| 2938 | + |
---|
| 2939 | + return 0; |
---|
2880 | 2940 | } |
---|
2881 | 2941 | |
---|
2882 | 2942 | /** |
---|
.. | .. |
---|
2934 | 2994 | binder_size_t off_start_offset, off_end_offset; |
---|
2935 | 2995 | binder_size_t off_min; |
---|
2936 | 2996 | binder_size_t sg_buf_offset, sg_buf_end_offset; |
---|
| 2997 | + binder_size_t user_offset = 0; |
---|
2937 | 2998 | struct binder_proc *target_proc = NULL; |
---|
2938 | 2999 | struct binder_thread *target_thread = NULL; |
---|
2939 | 3000 | struct binder_node *target_node = NULL; |
---|
.. | .. |
---|
2948 | 3009 | int t_debug_id = atomic_inc_return(&binder_last_id); |
---|
2949 | 3010 | char *secctx = NULL; |
---|
2950 | 3011 | u32 secctx_sz = 0; |
---|
| 3012 | + struct list_head sgc_head; |
---|
| 3013 | + struct list_head pf_head; |
---|
| 3014 | + const void __user *user_buffer = (const void __user *) |
---|
| 3015 | + (uintptr_t)tr->data.ptr.buffer; |
---|
| 3016 | + INIT_LIST_HEAD(&sgc_head); |
---|
| 3017 | + INIT_LIST_HEAD(&pf_head); |
---|
2951 | 3018 | |
---|
2952 | 3019 | e = binder_transaction_log_add(&binder_transaction_log); |
---|
2953 | 3020 | e->debug_id = t_debug_id; |
---|
.. | .. |
---|
2957 | 3024 | e->target_handle = tr->target.handle; |
---|
2958 | 3025 | e->data_size = tr->data_size; |
---|
2959 | 3026 | e->offsets_size = tr->offsets_size; |
---|
2960 | | - e->context_name = proc->context->name; |
---|
| 3027 | + strscpy(e->context_name, proc->context->name, BINDERFS_MAX_NAME); |
---|
2961 | 3028 | |
---|
2962 | 3029 | if (reply) { |
---|
2963 | 3030 | binder_inner_proc_lock(proc); |
---|
.. | .. |
---|
2991 | 3058 | binder_inner_proc_unlock(proc); |
---|
2992 | 3059 | target_thread = binder_get_txn_from_and_acq_inner(in_reply_to); |
---|
2993 | 3060 | if (target_thread == NULL) { |
---|
| 3061 | + /* annotation for sparse */ |
---|
| 3062 | + __release(&target_thread->proc->inner_lock); |
---|
2994 | 3063 | return_error = BR_DEAD_REPLY; |
---|
2995 | 3064 | return_error_line = __LINE__; |
---|
2996 | 3065 | goto err_dead_binder; |
---|
.. | .. |
---|
3012 | 3081 | target_proc = target_thread->proc; |
---|
3013 | 3082 | target_proc->tmp_ref++; |
---|
3014 | 3083 | binder_inner_proc_unlock(target_thread->proc); |
---|
| 3084 | + trace_android_vh_binder_reply(target_proc, proc, thread, tr); |
---|
3015 | 3085 | } else { |
---|
3016 | 3086 | if (tr->target.handle) { |
---|
3017 | 3087 | struct binder_ref *ref; |
---|
.. | .. |
---|
3031 | 3101 | ref->node, &target_proc, |
---|
3032 | 3102 | &return_error); |
---|
3033 | 3103 | } else { |
---|
3034 | | - binder_user_error("%d:%d got transaction to invalid handle\n", |
---|
3035 | | - proc->pid, thread->pid); |
---|
| 3104 | + binder_user_error("%d:%d got transaction to invalid handle, %u\n", |
---|
| 3105 | + proc->pid, thread->pid, tr->target.handle); |
---|
3036 | 3106 | return_error = BR_FAILED_REPLY; |
---|
3037 | 3107 | } |
---|
3038 | 3108 | binder_proc_unlock(proc); |
---|
.. | .. |
---|
3064 | 3134 | goto err_dead_binder; |
---|
3065 | 3135 | } |
---|
3066 | 3136 | e->to_node = target_node->debug_id; |
---|
3067 | | - if (security_binder_transaction(proc->cred, |
---|
3068 | | - target_proc->cred) < 0) { |
---|
| 3137 | + trace_android_vh_binder_trans(target_proc, proc, thread, tr); |
---|
| 3138 | + if (security_binder_transaction(binder_get_cred(proc), |
---|
| 3139 | + binder_get_cred(target_proc)) < 0) { |
---|
3069 | 3140 | return_error = BR_FAILED_REPLY; |
---|
3070 | 3141 | return_error_param = -EPERM; |
---|
3071 | 3142 | return_error_line = __LINE__; |
---|
.. | .. |
---|
3133 | 3204 | if (target_thread) |
---|
3134 | 3205 | e->to_thread = target_thread->pid; |
---|
3135 | 3206 | e->to_proc = target_proc->pid; |
---|
| 3207 | + trace_android_rvh_binder_transaction(target_proc, proc, thread, tr); |
---|
3136 | 3208 | |
---|
3137 | 3209 | /* TODO: reuse incoming transaction for reply */ |
---|
3138 | 3210 | t = kzalloc(sizeof(*t), GFP_KERNEL); |
---|
.. | .. |
---|
3142 | 3214 | return_error_line = __LINE__; |
---|
3143 | 3215 | goto err_alloc_t_failed; |
---|
3144 | 3216 | } |
---|
| 3217 | + INIT_LIST_HEAD(&t->fd_fixups); |
---|
3145 | 3218 | binder_stats_created(BINDER_STAT_TRANSACTION); |
---|
3146 | 3219 | spin_lock_init(&t->lock); |
---|
| 3220 | + trace_android_vh_binder_transaction_init(t); |
---|
3147 | 3221 | |
---|
3148 | 3222 | tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL); |
---|
3149 | 3223 | if (tcomplete == NULL) { |
---|
.. | .. |
---|
3197 | 3271 | if (target_node && target_node->txn_security_ctx) { |
---|
3198 | 3272 | u32 secid; |
---|
3199 | 3273 | size_t added_size; |
---|
| 3274 | + int max_retries = 100; |
---|
3200 | 3275 | |
---|
3201 | | - security_cred_getsecid(proc->cred, &secid); |
---|
| 3276 | + security_cred_getsecid(binder_get_cred(proc), &secid); |
---|
| 3277 | + retry_alloc: |
---|
3202 | 3278 | ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); |
---|
| 3279 | + if (ret == -ENOMEM && max_retries-- > 0) { |
---|
| 3280 | + struct page *dummy_page; |
---|
| 3281 | + |
---|
| 3282 | + /* |
---|
| 3283 | + * security_secid_to_secctx() can fail because of a |
---|
| 3284 | + * GFP_ATOMIC allocation in which case -ENOMEM is |
---|
| 3285 | + * returned. This needs to be retried, but there is |
---|
| 3286 | + * currently no way to tell userspace to retry so we |
---|
| 3287 | + * do it here. We make sure there is still available |
---|
| 3288 | + * memory first and then retry. |
---|
| 3289 | + */ |
---|
| 3290 | + dummy_page = alloc_page(GFP_KERNEL); |
---|
| 3291 | + if (dummy_page) { |
---|
| 3292 | + __free_page(dummy_page); |
---|
| 3293 | + goto retry_alloc; |
---|
| 3294 | + } |
---|
| 3295 | + } |
---|
3203 | 3296 | if (ret) { |
---|
3204 | 3297 | return_error = BR_FAILED_REPLY; |
---|
3205 | 3298 | return_error_param = ret; |
---|
.. | .. |
---|
3234 | 3327 | goto err_binder_alloc_buf_failed; |
---|
3235 | 3328 | } |
---|
3236 | 3329 | if (secctx) { |
---|
| 3330 | + int err; |
---|
3237 | 3331 | size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) + |
---|
3238 | 3332 | ALIGN(tr->offsets_size, sizeof(void *)) + |
---|
3239 | 3333 | ALIGN(extra_buffers_size, sizeof(void *)) - |
---|
3240 | 3334 | ALIGN(secctx_sz, sizeof(u64)); |
---|
3241 | 3335 | |
---|
3242 | 3336 | t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset; |
---|
3243 | | - binder_alloc_copy_to_buffer(&target_proc->alloc, |
---|
3244 | | - t->buffer, buf_offset, |
---|
3245 | | - secctx, secctx_sz); |
---|
| 3337 | + err = binder_alloc_copy_to_buffer(&target_proc->alloc, |
---|
| 3338 | + t->buffer, buf_offset, |
---|
| 3339 | + secctx, secctx_sz); |
---|
| 3340 | + if (err) { |
---|
| 3341 | + t->security_ctx = 0; |
---|
| 3342 | + WARN_ON(1); |
---|
| 3343 | + } |
---|
3246 | 3344 | security_release_secctx(secctx, secctx_sz); |
---|
3247 | 3345 | secctx = NULL; |
---|
3248 | 3346 | } |
---|
3249 | 3347 | t->buffer->debug_id = t->debug_id; |
---|
3250 | 3348 | t->buffer->transaction = t; |
---|
3251 | 3349 | t->buffer->target_node = target_node; |
---|
| 3350 | + t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF); |
---|
3252 | 3351 | trace_binder_transaction_alloc_buf(t->buffer); |
---|
3253 | 3352 | |
---|
3254 | | - if (binder_alloc_copy_user_to_buffer( |
---|
3255 | | - &target_proc->alloc, |
---|
3256 | | - t->buffer, 0, |
---|
3257 | | - (const void __user *) |
---|
3258 | | - (uintptr_t)tr->data.ptr.buffer, |
---|
3259 | | - tr->data_size)) { |
---|
3260 | | - binder_user_error("%d:%d got transaction with invalid data ptr\n", |
---|
3261 | | - proc->pid, thread->pid); |
---|
3262 | | - return_error = BR_FAILED_REPLY; |
---|
3263 | | - return_error_param = -EFAULT; |
---|
3264 | | - return_error_line = __LINE__; |
---|
3265 | | - goto err_copy_data_failed; |
---|
3266 | | - } |
---|
3267 | 3353 | if (binder_alloc_copy_user_to_buffer( |
---|
3268 | 3354 | &target_proc->alloc, |
---|
3269 | 3355 | t->buffer, |
---|
.. | .. |
---|
3308 | 3394 | size_t object_size; |
---|
3309 | 3395 | struct binder_object object; |
---|
3310 | 3396 | binder_size_t object_offset; |
---|
| 3397 | + binder_size_t copy_size; |
---|
3311 | 3398 | |
---|
3312 | | - binder_alloc_copy_from_buffer(&target_proc->alloc, |
---|
3313 | | - &object_offset, |
---|
3314 | | - t->buffer, |
---|
3315 | | - buffer_offset, |
---|
3316 | | - sizeof(object_offset)); |
---|
3317 | | - object_size = binder_get_object(target_proc, t->buffer, |
---|
3318 | | - object_offset, &object); |
---|
| 3399 | + if (binder_alloc_copy_from_buffer(&target_proc->alloc, |
---|
| 3400 | + &object_offset, |
---|
| 3401 | + t->buffer, |
---|
| 3402 | + buffer_offset, |
---|
| 3403 | + sizeof(object_offset))) { |
---|
| 3404 | + return_error = BR_FAILED_REPLY; |
---|
| 3405 | + return_error_param = -EINVAL; |
---|
| 3406 | + return_error_line = __LINE__; |
---|
| 3407 | + goto err_bad_offset; |
---|
| 3408 | + } |
---|
| 3409 | + |
---|
| 3410 | + /* |
---|
| 3411 | + * Copy the source user buffer up to the next object |
---|
| 3412 | + * that will be processed. |
---|
| 3413 | + */ |
---|
| 3414 | + copy_size = object_offset - user_offset; |
---|
| 3415 | + if (copy_size && (user_offset > object_offset || |
---|
| 3416 | + binder_alloc_copy_user_to_buffer( |
---|
| 3417 | + &target_proc->alloc, |
---|
| 3418 | + t->buffer, user_offset, |
---|
| 3419 | + user_buffer + user_offset, |
---|
| 3420 | + copy_size))) { |
---|
| 3421 | + binder_user_error("%d:%d got transaction with invalid data ptr\n", |
---|
| 3422 | + proc->pid, thread->pid); |
---|
| 3423 | + return_error = BR_FAILED_REPLY; |
---|
| 3424 | + return_error_param = -EFAULT; |
---|
| 3425 | + return_error_line = __LINE__; |
---|
| 3426 | + goto err_copy_data_failed; |
---|
| 3427 | + } |
---|
| 3428 | + object_size = binder_get_object(target_proc, user_buffer, |
---|
| 3429 | + t->buffer, object_offset, &object); |
---|
3319 | 3430 | if (object_size == 0 || object_offset < off_min) { |
---|
3320 | 3431 | binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n", |
---|
3321 | 3432 | proc->pid, thread->pid, |
---|
.. | .. |
---|
3327 | 3438 | return_error_line = __LINE__; |
---|
3328 | 3439 | goto err_bad_offset; |
---|
3329 | 3440 | } |
---|
| 3441 | + /* |
---|
| 3442 | + * Set offset to the next buffer fragment to be |
---|
| 3443 | + * copied |
---|
| 3444 | + */ |
---|
| 3445 | + user_offset = object_offset + object_size; |
---|
3330 | 3446 | |
---|
3331 | 3447 | hdr = &object.hdr; |
---|
3332 | 3448 | off_min = object_offset + object_size; |
---|
.. | .. |
---|
3337 | 3453 | |
---|
3338 | 3454 | fp = to_flat_binder_object(hdr); |
---|
3339 | 3455 | ret = binder_translate_binder(fp, t, thread); |
---|
3340 | | - if (ret < 0) { |
---|
| 3456 | + |
---|
| 3457 | + if (ret < 0 || |
---|
| 3458 | + binder_alloc_copy_to_buffer(&target_proc->alloc, |
---|
| 3459 | + t->buffer, |
---|
| 3460 | + object_offset, |
---|
| 3461 | + fp, sizeof(*fp))) { |
---|
3341 | 3462 | return_error = BR_FAILED_REPLY; |
---|
3342 | 3463 | return_error_param = ret; |
---|
3343 | 3464 | return_error_line = __LINE__; |
---|
3344 | 3465 | goto err_translate_failed; |
---|
3345 | 3466 | } |
---|
3346 | | - binder_alloc_copy_to_buffer(&target_proc->alloc, |
---|
3347 | | - t->buffer, object_offset, |
---|
3348 | | - fp, sizeof(*fp)); |
---|
3349 | 3467 | } break; |
---|
3350 | 3468 | case BINDER_TYPE_HANDLE: |
---|
3351 | 3469 | case BINDER_TYPE_WEAK_HANDLE: { |
---|
.. | .. |
---|
3353 | 3471 | |
---|
3354 | 3472 | fp = to_flat_binder_object(hdr); |
---|
3355 | 3473 | ret = binder_translate_handle(fp, t, thread); |
---|
3356 | | - if (ret < 0) { |
---|
| 3474 | + if (ret < 0 || |
---|
| 3475 | + binder_alloc_copy_to_buffer(&target_proc->alloc, |
---|
| 3476 | + t->buffer, |
---|
| 3477 | + object_offset, |
---|
| 3478 | + fp, sizeof(*fp))) { |
---|
3357 | 3479 | return_error = BR_FAILED_REPLY; |
---|
3358 | 3480 | return_error_param = ret; |
---|
3359 | 3481 | return_error_line = __LINE__; |
---|
3360 | 3482 | goto err_translate_failed; |
---|
3361 | 3483 | } |
---|
3362 | | - binder_alloc_copy_to_buffer(&target_proc->alloc, |
---|
3363 | | - t->buffer, object_offset, |
---|
3364 | | - fp, sizeof(*fp)); |
---|
3365 | 3484 | } break; |
---|
3366 | 3485 | |
---|
3367 | 3486 | case BINDER_TYPE_FD: { |
---|
3368 | 3487 | struct binder_fd_object *fp = to_binder_fd_object(hdr); |
---|
3369 | | - int target_fd = binder_translate_fd(fp->fd, t, thread, |
---|
3370 | | - in_reply_to); |
---|
| 3488 | + binder_size_t fd_offset = object_offset + |
---|
| 3489 | + (uintptr_t)&fp->fd - (uintptr_t)fp; |
---|
| 3490 | + int ret = binder_translate_fd(fp->fd, fd_offset, t, |
---|
| 3491 | + thread, in_reply_to); |
---|
3371 | 3492 | |
---|
3372 | | - if (target_fd < 0) { |
---|
| 3493 | + fp->pad_binder = 0; |
---|
| 3494 | + if (ret < 0 || |
---|
| 3495 | + binder_alloc_copy_to_buffer(&target_proc->alloc, |
---|
| 3496 | + t->buffer, |
---|
| 3497 | + object_offset, |
---|
| 3498 | + fp, sizeof(*fp))) { |
---|
3373 | 3499 | return_error = BR_FAILED_REPLY; |
---|
3374 | | - return_error_param = target_fd; |
---|
| 3500 | + return_error_param = ret; |
---|
3375 | 3501 | return_error_line = __LINE__; |
---|
3376 | 3502 | goto err_translate_failed; |
---|
3377 | 3503 | } |
---|
3378 | | - fp->pad_binder = 0; |
---|
3379 | | - fp->fd = target_fd; |
---|
3380 | | - binder_alloc_copy_to_buffer(&target_proc->alloc, |
---|
3381 | | - t->buffer, object_offset, |
---|
3382 | | - fp, sizeof(*fp)); |
---|
3383 | 3504 | } break; |
---|
3384 | 3505 | case BINDER_TYPE_FDA: { |
---|
3385 | 3506 | struct binder_object ptr_object; |
---|
3386 | 3507 | binder_size_t parent_offset; |
---|
| 3508 | + struct binder_object user_object; |
---|
| 3509 | + size_t user_parent_size; |
---|
3387 | 3510 | struct binder_fd_array_object *fda = |
---|
3388 | 3511 | to_binder_fd_array_object(hdr); |
---|
3389 | 3512 | size_t num_valid = (buffer_offset - off_start_offset) / |
---|
.. | .. |
---|
3415 | 3538 | return_error_line = __LINE__; |
---|
3416 | 3539 | goto err_bad_parent; |
---|
3417 | 3540 | } |
---|
3418 | | - ret = binder_translate_fd_array(fda, parent, t, thread, |
---|
3419 | | - in_reply_to); |
---|
3420 | | - if (ret < 0) { |
---|
| 3541 | + /* |
---|
| 3542 | + * We need to read the user version of the parent |
---|
| 3543 | + * object to get the original user offset |
---|
| 3544 | + */ |
---|
| 3545 | + user_parent_size = |
---|
| 3546 | + binder_get_object(proc, user_buffer, t->buffer, |
---|
| 3547 | + parent_offset, &user_object); |
---|
| 3548 | + if (user_parent_size != sizeof(user_object.bbo)) { |
---|
| 3549 | + binder_user_error("%d:%d invalid ptr object size: %zd vs %zd\n", |
---|
| 3550 | + proc->pid, thread->pid, |
---|
| 3551 | + user_parent_size, |
---|
| 3552 | + sizeof(user_object.bbo)); |
---|
3421 | 3553 | return_error = BR_FAILED_REPLY; |
---|
3422 | | - return_error_param = ret; |
---|
| 3554 | + return_error_param = -EINVAL; |
---|
| 3555 | + return_error_line = __LINE__; |
---|
| 3556 | + goto err_bad_parent; |
---|
| 3557 | + } |
---|
| 3558 | + ret = binder_translate_fd_array(&pf_head, fda, |
---|
| 3559 | + user_buffer, parent, |
---|
| 3560 | + &user_object.bbo, t, |
---|
| 3561 | + thread, in_reply_to); |
---|
| 3562 | + if (!ret) |
---|
| 3563 | + ret = binder_alloc_copy_to_buffer(&target_proc->alloc, |
---|
| 3564 | + t->buffer, |
---|
| 3565 | + object_offset, |
---|
| 3566 | + fda, sizeof(*fda)); |
---|
| 3567 | + if (ret) { |
---|
| 3568 | + return_error = BR_FAILED_REPLY; |
---|
| 3569 | + return_error_param = ret > 0 ? -EINVAL : ret; |
---|
3423 | 3570 | return_error_line = __LINE__; |
---|
3424 | 3571 | goto err_translate_failed; |
---|
3425 | 3572 | } |
---|
.. | .. |
---|
3441 | 3588 | return_error_line = __LINE__; |
---|
3442 | 3589 | goto err_bad_offset; |
---|
3443 | 3590 | } |
---|
3444 | | - if (binder_alloc_copy_user_to_buffer( |
---|
3445 | | - &target_proc->alloc, |
---|
3446 | | - t->buffer, |
---|
3447 | | - sg_buf_offset, |
---|
3448 | | - (const void __user *) |
---|
3449 | | - (uintptr_t)bp->buffer, |
---|
3450 | | - bp->length)) { |
---|
3451 | | - binder_user_error("%d:%d got transaction with invalid offsets ptr\n", |
---|
3452 | | - proc->pid, thread->pid); |
---|
3453 | | - return_error_param = -EFAULT; |
---|
| 3591 | + ret = binder_defer_copy(&sgc_head, sg_buf_offset, |
---|
| 3592 | + (const void __user *)(uintptr_t)bp->buffer, |
---|
| 3593 | + bp->length); |
---|
| 3594 | + if (ret) { |
---|
3454 | 3595 | return_error = BR_FAILED_REPLY; |
---|
| 3596 | + return_error_param = ret; |
---|
3455 | 3597 | return_error_line = __LINE__; |
---|
3456 | | - goto err_copy_data_failed; |
---|
| 3598 | + goto err_translate_failed; |
---|
3457 | 3599 | } |
---|
3458 | 3600 | /* Fixup buffer pointer to target proc address space */ |
---|
3459 | 3601 | bp->buffer = (uintptr_t) |
---|
.. | .. |
---|
3462 | 3604 | |
---|
3463 | 3605 | num_valid = (buffer_offset - off_start_offset) / |
---|
3464 | 3606 | sizeof(binder_size_t); |
---|
3465 | | - ret = binder_fixup_parent(t, thread, bp, |
---|
| 3607 | + ret = binder_fixup_parent(&pf_head, t, |
---|
| 3608 | + thread, bp, |
---|
3466 | 3609 | off_start_offset, |
---|
3467 | 3610 | num_valid, |
---|
3468 | 3611 | last_fixup_obj_off, |
---|
3469 | 3612 | last_fixup_min_off); |
---|
3470 | | - if (ret < 0) { |
---|
| 3613 | + if (ret < 0 || |
---|
| 3614 | + binder_alloc_copy_to_buffer(&target_proc->alloc, |
---|
| 3615 | + t->buffer, |
---|
| 3616 | + object_offset, |
---|
| 3617 | + bp, sizeof(*bp))) { |
---|
3471 | 3618 | return_error = BR_FAILED_REPLY; |
---|
3472 | 3619 | return_error_param = ret; |
---|
3473 | 3620 | return_error_line = __LINE__; |
---|
3474 | 3621 | goto err_translate_failed; |
---|
3475 | 3622 | } |
---|
3476 | | - binder_alloc_copy_to_buffer(&target_proc->alloc, |
---|
3477 | | - t->buffer, object_offset, |
---|
3478 | | - bp, sizeof(*bp)); |
---|
3479 | 3623 | last_fixup_obj_off = object_offset; |
---|
3480 | 3624 | last_fixup_min_off = 0; |
---|
3481 | 3625 | } break; |
---|
.. | .. |
---|
3488 | 3632 | goto err_bad_object_type; |
---|
3489 | 3633 | } |
---|
3490 | 3634 | } |
---|
3491 | | - tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; |
---|
| 3635 | + /* Done processing objects, copy the rest of the buffer */ |
---|
| 3636 | + if (binder_alloc_copy_user_to_buffer( |
---|
| 3637 | + &target_proc->alloc, |
---|
| 3638 | + t->buffer, user_offset, |
---|
| 3639 | + user_buffer + user_offset, |
---|
| 3640 | + tr->data_size - user_offset)) { |
---|
| 3641 | + binder_user_error("%d:%d got transaction with invalid data ptr\n", |
---|
| 3642 | + proc->pid, thread->pid); |
---|
| 3643 | + return_error = BR_FAILED_REPLY; |
---|
| 3644 | + return_error_param = -EFAULT; |
---|
| 3645 | + return_error_line = __LINE__; |
---|
| 3646 | + goto err_copy_data_failed; |
---|
| 3647 | + } |
---|
| 3648 | + |
---|
| 3649 | + ret = binder_do_deferred_txn_copies(&target_proc->alloc, t->buffer, |
---|
| 3650 | + &sgc_head, &pf_head); |
---|
| 3651 | + if (ret) { |
---|
| 3652 | + binder_user_error("%d:%d got transaction with invalid offsets ptr\n", |
---|
| 3653 | + proc->pid, thread->pid); |
---|
| 3654 | + return_error = BR_FAILED_REPLY; |
---|
| 3655 | + return_error_param = ret; |
---|
| 3656 | + return_error_line = __LINE__; |
---|
| 3657 | + goto err_copy_data_failed; |
---|
| 3658 | + } |
---|
| 3659 | + if (t->buffer->oneway_spam_suspect) |
---|
| 3660 | + tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT; |
---|
| 3661 | + else |
---|
| 3662 | + tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; |
---|
3492 | 3663 | t->work.type = BINDER_WORK_TRANSACTION; |
---|
3493 | 3664 | |
---|
3494 | 3665 | if (reply) { |
---|
3495 | 3666 | binder_enqueue_thread_work(thread, tcomplete); |
---|
3496 | 3667 | binder_inner_proc_lock(target_proc); |
---|
3497 | 3668 | if (target_thread->is_dead) { |
---|
| 3669 | + return_error = BR_DEAD_REPLY; |
---|
3498 | 3670 | binder_inner_proc_unlock(target_proc); |
---|
3499 | 3671 | goto err_dead_proc_or_thread; |
---|
3500 | 3672 | } |
---|
3501 | 3673 | BUG_ON(t->buffer->async_transaction != 0); |
---|
3502 | 3674 | binder_pop_transaction_ilocked(target_thread, in_reply_to); |
---|
3503 | 3675 | binder_enqueue_thread_work_ilocked(target_thread, &t->work); |
---|
| 3676 | + target_proc->outstanding_txns++; |
---|
3504 | 3677 | binder_inner_proc_unlock(target_proc); |
---|
3505 | 3678 | wake_up_interruptible_sync(&target_thread->wait); |
---|
| 3679 | + trace_android_vh_binder_restore_priority(in_reply_to, current); |
---|
3506 | 3680 | binder_restore_priority(current, in_reply_to->saved_priority); |
---|
3507 | 3681 | binder_free_transaction(in_reply_to); |
---|
3508 | 3682 | } else if (!(t->flags & TF_ONE_WAY)) { |
---|
.. | .. |
---|
3520 | 3694 | t->from_parent = thread->transaction_stack; |
---|
3521 | 3695 | thread->transaction_stack = t; |
---|
3522 | 3696 | binder_inner_proc_unlock(proc); |
---|
3523 | | - if (!binder_proc_transaction(t, target_proc, target_thread)) { |
---|
| 3697 | + return_error = binder_proc_transaction(t, |
---|
| 3698 | + target_proc, target_thread); |
---|
| 3699 | + if (return_error) { |
---|
3524 | 3700 | binder_inner_proc_lock(proc); |
---|
3525 | 3701 | binder_pop_transaction_ilocked(thread, t); |
---|
3526 | 3702 | binder_inner_proc_unlock(proc); |
---|
.. | .. |
---|
3530 | 3706 | BUG_ON(target_node == NULL); |
---|
3531 | 3707 | BUG_ON(t->buffer->async_transaction != 1); |
---|
3532 | 3708 | binder_enqueue_thread_work(thread, tcomplete); |
---|
3533 | | - if (!binder_proc_transaction(t, target_proc, NULL)) |
---|
| 3709 | + return_error = binder_proc_transaction(t, target_proc, NULL); |
---|
| 3710 | + if (return_error) |
---|
3534 | 3711 | goto err_dead_proc_or_thread; |
---|
3535 | 3712 | } |
---|
3536 | 3713 | if (target_thread) |
---|
.. | .. |
---|
3547 | 3724 | return; |
---|
3548 | 3725 | |
---|
3549 | 3726 | err_dead_proc_or_thread: |
---|
3550 | | - return_error = BR_DEAD_REPLY; |
---|
3551 | 3727 | return_error_line = __LINE__; |
---|
3552 | 3728 | binder_dequeue_work(proc, tcomplete); |
---|
3553 | 3729 | err_translate_failed: |
---|
.. | .. |
---|
3555 | 3731 | err_bad_offset: |
---|
3556 | 3732 | err_bad_parent: |
---|
3557 | 3733 | err_copy_data_failed: |
---|
| 3734 | + binder_cleanup_deferred_txn_lists(&sgc_head, &pf_head); |
---|
| 3735 | + binder_free_txn_fixups(t); |
---|
3558 | 3736 | trace_binder_transaction_failed_buffer_release(t->buffer); |
---|
3559 | | - binder_transaction_buffer_release(target_proc, t->buffer, |
---|
| 3737 | + binder_transaction_buffer_release(target_proc, NULL, t->buffer, |
---|
3560 | 3738 | buffer_offset, true); |
---|
3561 | 3739 | if (target_node) |
---|
3562 | 3740 | binder_dec_node_tmpref(target_node); |
---|
.. | .. |
---|
3613 | 3791 | |
---|
3614 | 3792 | BUG_ON(thread->return_error.cmd != BR_OK); |
---|
3615 | 3793 | if (in_reply_to) { |
---|
| 3794 | + trace_android_vh_binder_restore_priority(in_reply_to, current); |
---|
3616 | 3795 | binder_restore_priority(current, in_reply_to->saved_priority); |
---|
3617 | 3796 | thread->return_error.cmd = BR_TRANSACTION_COMPLETE; |
---|
3618 | 3797 | binder_enqueue_thread_work(thread, &thread->return_error.work); |
---|
.. | .. |
---|
3621 | 3800 | thread->return_error.cmd = return_error; |
---|
3622 | 3801 | binder_enqueue_thread_work(thread, &thread->return_error.work); |
---|
3623 | 3802 | } |
---|
| 3803 | +} |
---|
| 3804 | + |
---|
| 3805 | +/** |
---|
| 3806 | + * binder_free_buf() - free the specified buffer |
---|
| 3807 | + * @proc: binder proc that owns buffer |
---|
| 3808 | + * @buffer: buffer to be freed |
---|
| 3809 | + * @is_failure: failed to send transaction |
---|
| 3810 | + * |
---|
| 3811 | + * If buffer for an async transaction, enqueue the next async |
---|
| 3812 | + * transaction from the node. |
---|
| 3813 | + * |
---|
| 3814 | + * Cleanup buffer and free it. |
---|
| 3815 | + */ |
---|
| 3816 | +static void |
---|
| 3817 | +binder_free_buf(struct binder_proc *proc, |
---|
| 3818 | + struct binder_thread *thread, |
---|
| 3819 | + struct binder_buffer *buffer, bool is_failure) |
---|
| 3820 | +{ |
---|
| 3821 | + binder_inner_proc_lock(proc); |
---|
| 3822 | + if (buffer->transaction) { |
---|
| 3823 | + buffer->transaction->buffer = NULL; |
---|
| 3824 | + buffer->transaction = NULL; |
---|
| 3825 | + } |
---|
| 3826 | + binder_inner_proc_unlock(proc); |
---|
| 3827 | + if (buffer->async_transaction && buffer->target_node) { |
---|
| 3828 | + struct binder_node *buf_node; |
---|
| 3829 | + struct binder_work *w; |
---|
| 3830 | + |
---|
| 3831 | + buf_node = buffer->target_node; |
---|
| 3832 | + binder_node_inner_lock(buf_node); |
---|
| 3833 | + BUG_ON(!buf_node->has_async_transaction); |
---|
| 3834 | + BUG_ON(buf_node->proc != proc); |
---|
| 3835 | + w = binder_dequeue_work_head_ilocked( |
---|
| 3836 | + &buf_node->async_todo); |
---|
| 3837 | + if (!w) { |
---|
| 3838 | + buf_node->has_async_transaction = false; |
---|
| 3839 | + } else { |
---|
| 3840 | + binder_enqueue_work_ilocked( |
---|
| 3841 | + w, &proc->todo); |
---|
| 3842 | + binder_wakeup_proc_ilocked(proc); |
---|
| 3843 | + } |
---|
| 3844 | + binder_node_inner_unlock(buf_node); |
---|
| 3845 | + } |
---|
| 3846 | + trace_binder_transaction_buffer_release(buffer); |
---|
| 3847 | + binder_release_entire_buffer(proc, thread, buffer, is_failure); |
---|
| 3848 | + binder_alloc_free_buf(&proc->alloc, buffer); |
---|
3624 | 3849 | } |
---|
3625 | 3850 | |
---|
3626 | 3851 | static int binder_thread_write(struct binder_proc *proc, |
---|
.. | .. |
---|
3813 | 4038 | proc->pid, thread->pid, (u64)data_ptr, |
---|
3814 | 4039 | buffer->debug_id, |
---|
3815 | 4040 | buffer->transaction ? "active" : "finished"); |
---|
3816 | | - |
---|
3817 | | - binder_inner_proc_lock(proc); |
---|
3818 | | - if (buffer->transaction) { |
---|
3819 | | - buffer->transaction->buffer = NULL; |
---|
3820 | | - buffer->transaction = NULL; |
---|
3821 | | - } |
---|
3822 | | - binder_inner_proc_unlock(proc); |
---|
3823 | | - if (buffer->async_transaction && buffer->target_node) { |
---|
3824 | | - struct binder_node *buf_node; |
---|
3825 | | - struct binder_work *w; |
---|
3826 | | - |
---|
3827 | | - buf_node = buffer->target_node; |
---|
3828 | | - binder_node_inner_lock(buf_node); |
---|
3829 | | - BUG_ON(!buf_node->has_async_transaction); |
---|
3830 | | - BUG_ON(buf_node->proc != proc); |
---|
3831 | | - w = binder_dequeue_work_head_ilocked( |
---|
3832 | | - &buf_node->async_todo); |
---|
3833 | | - if (!w) { |
---|
3834 | | - buf_node->has_async_transaction = false; |
---|
3835 | | - } else { |
---|
3836 | | - binder_enqueue_work_ilocked( |
---|
3837 | | - w, &proc->todo); |
---|
3838 | | - binder_wakeup_proc_ilocked(proc); |
---|
3839 | | - } |
---|
3840 | | - binder_node_inner_unlock(buf_node); |
---|
3841 | | - } |
---|
3842 | | - trace_binder_transaction_buffer_release(buffer); |
---|
3843 | | - binder_transaction_buffer_release(proc, buffer, 0, false); |
---|
3844 | | - binder_alloc_free_buf(&proc->alloc, buffer); |
---|
| 4041 | + binder_free_buf(proc, thread, buffer, false); |
---|
3845 | 4042 | break; |
---|
3846 | 4043 | } |
---|
3847 | 4044 | |
---|
.. | .. |
---|
3887 | 4084 | } |
---|
3888 | 4085 | thread->looper |= BINDER_LOOPER_STATE_REGISTERED; |
---|
3889 | 4086 | binder_inner_proc_unlock(proc); |
---|
| 4087 | + trace_android_vh_binder_looper_state_registered(thread, proc); |
---|
3890 | 4088 | break; |
---|
3891 | 4089 | case BC_ENTER_LOOPER: |
---|
3892 | 4090 | binder_debug(BINDER_DEBUG_THREADS, |
---|
.. | .. |
---|
4148 | 4346 | if (do_proc_work) |
---|
4149 | 4347 | list_add(&thread->waiting_thread_node, |
---|
4150 | 4348 | &proc->waiting_threads); |
---|
| 4349 | + trace_android_vh_binder_wait_for_work(do_proc_work, thread, proc); |
---|
4151 | 4350 | binder_inner_proc_unlock(proc); |
---|
4152 | 4351 | schedule(); |
---|
4153 | 4352 | binder_inner_proc_lock(proc); |
---|
4154 | 4353 | list_del_init(&thread->waiting_thread_node); |
---|
4155 | 4354 | if (signal_pending(current)) { |
---|
4156 | | - ret = -ERESTARTSYS; |
---|
| 4355 | + ret = -EINTR; |
---|
4157 | 4356 | break; |
---|
4158 | 4357 | } |
---|
4159 | 4358 | } |
---|
4160 | 4359 | finish_wait(&thread->wait, &wait); |
---|
4161 | 4360 | binder_inner_proc_unlock(proc); |
---|
4162 | 4361 | freezer_count(); |
---|
| 4362 | + |
---|
| 4363 | + return ret; |
---|
| 4364 | +} |
---|
| 4365 | + |
---|
| 4366 | +/** |
---|
| 4367 | + * binder_apply_fd_fixups() - finish fd translation |
---|
| 4368 | + * @proc: binder_proc associated @t->buffer |
---|
| 4369 | + * @t: binder transaction with list of fd fixups |
---|
| 4370 | + * |
---|
| 4371 | + * Now that we are in the context of the transaction target |
---|
| 4372 | + * process, we can allocate and install fds. Process the |
---|
| 4373 | + * list of fds to translate and fixup the buffer with the |
---|
| 4374 | + * new fds. |
---|
| 4375 | + * |
---|
| 4376 | + * If we fail to allocate an fd, then free the resources by |
---|
| 4377 | + * fput'ing files that have not been processed and ksys_close'ing |
---|
| 4378 | + * any fds that have already been allocated. |
---|
| 4379 | + */ |
---|
| 4380 | +static int binder_apply_fd_fixups(struct binder_proc *proc, |
---|
| 4381 | + struct binder_transaction *t) |
---|
| 4382 | +{ |
---|
| 4383 | + struct binder_txn_fd_fixup *fixup, *tmp; |
---|
| 4384 | + int ret = 0; |
---|
| 4385 | + |
---|
| 4386 | + list_for_each_entry(fixup, &t->fd_fixups, fixup_entry) { |
---|
| 4387 | + int fd = get_unused_fd_flags(O_CLOEXEC); |
---|
| 4388 | + |
---|
| 4389 | + if (fd < 0) { |
---|
| 4390 | + binder_debug(BINDER_DEBUG_TRANSACTION, |
---|
| 4391 | + "failed fd fixup txn %d fd %d\n", |
---|
| 4392 | + t->debug_id, fd); |
---|
| 4393 | + ret = -ENOMEM; |
---|
| 4394 | + break; |
---|
| 4395 | + } |
---|
| 4396 | + binder_debug(BINDER_DEBUG_TRANSACTION, |
---|
| 4397 | + "fd fixup txn %d fd %d\n", |
---|
| 4398 | + t->debug_id, fd); |
---|
| 4399 | + trace_binder_transaction_fd_recv(t, fd, fixup->offset); |
---|
| 4400 | + fd_install(fd, fixup->file); |
---|
| 4401 | + fixup->file = NULL; |
---|
| 4402 | + if (binder_alloc_copy_to_buffer(&proc->alloc, t->buffer, |
---|
| 4403 | + fixup->offset, &fd, |
---|
| 4404 | + sizeof(u32))) { |
---|
| 4405 | + ret = -EINVAL; |
---|
| 4406 | + break; |
---|
| 4407 | + } |
---|
| 4408 | + } |
---|
| 4409 | + list_for_each_entry_safe(fixup, tmp, &t->fd_fixups, fixup_entry) { |
---|
| 4410 | + if (fixup->file) { |
---|
| 4411 | + fput(fixup->file); |
---|
| 4412 | + } else if (ret) { |
---|
| 4413 | + u32 fd; |
---|
| 4414 | + int err; |
---|
| 4415 | + |
---|
| 4416 | + err = binder_alloc_copy_from_buffer(&proc->alloc, &fd, |
---|
| 4417 | + t->buffer, |
---|
| 4418 | + fixup->offset, |
---|
| 4419 | + sizeof(fd)); |
---|
| 4420 | + WARN_ON(err); |
---|
| 4421 | + if (!err) |
---|
| 4422 | + binder_deferred_fd_close(fd); |
---|
| 4423 | + } |
---|
| 4424 | + list_del(&fixup->fixup_entry); |
---|
| 4425 | + kfree(fixup); |
---|
| 4426 | + } |
---|
4163 | 4427 | |
---|
4164 | 4428 | return ret; |
---|
4165 | 4429 | } |
---|
.. | .. |
---|
4200 | 4464 | wait_event_interruptible(binder_user_error_wait, |
---|
4201 | 4465 | binder_stop_on_user_error < 2); |
---|
4202 | 4466 | } |
---|
| 4467 | + trace_android_vh_binder_restore_priority(NULL, current); |
---|
4203 | 4468 | binder_restore_priority(current, proc->default_priority); |
---|
4204 | 4469 | } |
---|
4205 | 4470 | |
---|
.. | .. |
---|
4244 | 4509 | binder_inner_proc_unlock(proc); |
---|
4245 | 4510 | break; |
---|
4246 | 4511 | } |
---|
| 4512 | + trace_android_vh_binder_thread_read(&list, proc, thread); |
---|
4247 | 4513 | w = binder_dequeue_work_head_ilocked(list); |
---|
4248 | 4514 | if (binder_worklist_empty_ilocked(&thread->todo)) |
---|
4249 | 4515 | thread->process_todo = false; |
---|
.. | .. |
---|
4267 | 4533 | |
---|
4268 | 4534 | binder_stat_br(proc, thread, cmd); |
---|
4269 | 4535 | } break; |
---|
4270 | | - case BINDER_WORK_TRANSACTION_COMPLETE: { |
---|
| 4536 | + case BINDER_WORK_TRANSACTION_COMPLETE: |
---|
| 4537 | + case BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT: { |
---|
| 4538 | + if (proc->oneway_spam_detection_enabled && |
---|
| 4539 | + w->type == BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT) |
---|
| 4540 | + cmd = BR_ONEWAY_SPAM_SUSPECT; |
---|
| 4541 | + else |
---|
| 4542 | + cmd = BR_TRANSACTION_COMPLETE; |
---|
4271 | 4543 | binder_inner_proc_unlock(proc); |
---|
4272 | | - cmd = BR_TRANSACTION_COMPLETE; |
---|
4273 | 4544 | kfree(w); |
---|
4274 | 4545 | binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); |
---|
4275 | 4546 | if (put_user(cmd, (uint32_t __user *)ptr)) |
---|
.. | .. |
---|
4409 | 4680 | if (cmd == BR_DEAD_BINDER) |
---|
4410 | 4681 | goto done; /* DEAD_BINDER notifications can cause transactions */ |
---|
4411 | 4682 | } break; |
---|
| 4683 | + default: |
---|
| 4684 | + binder_inner_proc_unlock(proc); |
---|
| 4685 | + pr_err("%d:%d: bad work type %d\n", |
---|
| 4686 | + proc->pid, thread->pid, w->type); |
---|
| 4687 | + break; |
---|
4412 | 4688 | } |
---|
4413 | 4689 | |
---|
4414 | 4690 | if (!t) |
---|
.. | .. |
---|
4442 | 4718 | trd->sender_pid = |
---|
4443 | 4719 | task_tgid_nr_ns(sender, |
---|
4444 | 4720 | task_active_pid_ns(current)); |
---|
| 4721 | + trace_android_vh_sync_txn_recvd(thread->task, t_from->task); |
---|
4445 | 4722 | } else { |
---|
4446 | 4723 | trd->sender_pid = 0; |
---|
4447 | 4724 | } |
---|
4448 | 4725 | |
---|
| 4726 | + ret = binder_apply_fd_fixups(proc, t); |
---|
| 4727 | + if (ret) { |
---|
| 4728 | + struct binder_buffer *buffer = t->buffer; |
---|
| 4729 | + bool oneway = !!(t->flags & TF_ONE_WAY); |
---|
| 4730 | + int tid = t->debug_id; |
---|
| 4731 | + |
---|
| 4732 | + if (t_from) |
---|
| 4733 | + binder_thread_dec_tmpref(t_from); |
---|
| 4734 | + buffer->transaction = NULL; |
---|
| 4735 | + binder_cleanup_transaction(t, "fd fixups failed", |
---|
| 4736 | + BR_FAILED_REPLY); |
---|
| 4737 | + binder_free_buf(proc, thread, buffer, true); |
---|
| 4738 | + binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, |
---|
| 4739 | + "%d:%d %stransaction %d fd fixups failed %d/%d, line %d\n", |
---|
| 4740 | + proc->pid, thread->pid, |
---|
| 4741 | + oneway ? "async " : |
---|
| 4742 | + (cmd == BR_REPLY ? "reply " : ""), |
---|
| 4743 | + tid, BR_FAILED_REPLY, ret, __LINE__); |
---|
| 4744 | + if (cmd == BR_REPLY) { |
---|
| 4745 | + cmd = BR_FAILED_REPLY; |
---|
| 4746 | + if (put_user(cmd, (uint32_t __user *)ptr)) |
---|
| 4747 | + return -EFAULT; |
---|
| 4748 | + ptr += sizeof(uint32_t); |
---|
| 4749 | + binder_stat_br(proc, thread, cmd); |
---|
| 4750 | + break; |
---|
| 4751 | + } |
---|
| 4752 | + continue; |
---|
| 4753 | + } |
---|
4449 | 4754 | trd->data_size = t->buffer->data_size; |
---|
4450 | 4755 | trd->offsets_size = t->buffer->offsets_size; |
---|
4451 | 4756 | trd->data.ptr.buffer = (uintptr_t)t->buffer->user_data; |
---|
.. | .. |
---|
4654 | 4959 | static void binder_free_proc(struct binder_proc *proc) |
---|
4655 | 4960 | { |
---|
4656 | 4961 | struct binder_device *device; |
---|
| 4962 | + struct binder_proc_ext *eproc = |
---|
| 4963 | + container_of(proc, struct binder_proc_ext, proc); |
---|
4657 | 4964 | |
---|
4658 | 4965 | BUG_ON(!list_empty(&proc->todo)); |
---|
4659 | 4966 | BUG_ON(!list_empty(&proc->delivered_death)); |
---|
| 4967 | + if (proc->outstanding_txns) |
---|
| 4968 | + pr_warn("%s: Unexpected outstanding_txns %d\n", |
---|
| 4969 | + __func__, proc->outstanding_txns); |
---|
4660 | 4970 | device = container_of(proc->context, struct binder_device, context); |
---|
4661 | 4971 | if (refcount_dec_and_test(&device->ref)) { |
---|
4662 | 4972 | kfree(proc->context->name); |
---|
.. | .. |
---|
4664 | 4974 | } |
---|
4665 | 4975 | binder_alloc_deferred_release(&proc->alloc); |
---|
4666 | 4976 | put_task_struct(proc->tsk); |
---|
4667 | | - put_cred(proc->cred); |
---|
| 4977 | + put_cred(eproc->cred); |
---|
4668 | 4978 | binder_stats_deleted(BINDER_STAT_PROC); |
---|
4669 | | - kfree(proc); |
---|
| 4979 | + trace_android_vh_binder_free_proc(proc); |
---|
| 4980 | + kfree(eproc); |
---|
4670 | 4981 | } |
---|
4671 | 4982 | |
---|
4672 | 4983 | static void binder_free_thread(struct binder_thread *thread) |
---|
.. | .. |
---|
4705 | 5016 | spin_lock(&t->lock); |
---|
4706 | 5017 | if (t->to_thread == thread) |
---|
4707 | 5018 | send_reply = t; |
---|
| 5019 | + } else { |
---|
| 5020 | + __acquire(&t->lock); |
---|
4708 | 5021 | } |
---|
4709 | 5022 | thread->is_dead = true; |
---|
4710 | 5023 | |
---|
.. | .. |
---|
4718 | 5031 | (t->to_thread == thread) ? "in" : "out"); |
---|
4719 | 5032 | |
---|
4720 | 5033 | if (t->to_thread == thread) { |
---|
| 5034 | + thread->proc->outstanding_txns--; |
---|
4721 | 5035 | t->to_proc = NULL; |
---|
4722 | 5036 | t->to_thread = NULL; |
---|
4723 | 5037 | if (t->buffer) { |
---|
.. | .. |
---|
4733 | 5047 | spin_unlock(&last_t->lock); |
---|
4734 | 5048 | if (t) |
---|
4735 | 5049 | spin_lock(&t->lock); |
---|
| 5050 | + else |
---|
| 5051 | + __acquire(&t->lock); |
---|
4736 | 5052 | } |
---|
| 5053 | + /* annotation for sparse, lock not acquired in last iteration above */ |
---|
| 5054 | + __release(&t->lock); |
---|
4737 | 5055 | |
---|
4738 | 5056 | /* |
---|
4739 | 5057 | * If this thread used poll, make sure we remove the waitqueue from any |
---|
.. | .. |
---|
4757 | 5075 | if (send_reply) |
---|
4758 | 5076 | binder_send_failed_reply(send_reply, BR_DEAD_REPLY); |
---|
4759 | 5077 | binder_release_work(proc, &thread->todo); |
---|
| 5078 | + trace_android_vh_binder_thread_release(proc, thread); |
---|
4760 | 5079 | binder_thread_dec_tmpref(thread); |
---|
4761 | 5080 | return active_transactions; |
---|
4762 | 5081 | } |
---|
.. | .. |
---|
4833 | 5152 | if (!binder_worklist_empty_ilocked(&proc->todo)) |
---|
4834 | 5153 | binder_wakeup_proc_ilocked(proc); |
---|
4835 | 5154 | binder_inner_proc_unlock(proc); |
---|
| 5155 | + trace_android_vh_binder_read_done(proc, thread); |
---|
4836 | 5156 | if (ret < 0) { |
---|
4837 | 5157 | if (copy_to_user(ubuf, &bwr, sizeof(bwr))) |
---|
4838 | 5158 | ret = -EFAULT; |
---|
.. | .. |
---|
4867 | 5187 | ret = -EBUSY; |
---|
4868 | 5188 | goto out; |
---|
4869 | 5189 | } |
---|
4870 | | - ret = security_binder_set_context_mgr(proc->cred); |
---|
| 5190 | + ret = security_binder_set_context_mgr(binder_get_cred(proc)); |
---|
4871 | 5191 | if (ret < 0) |
---|
4872 | 5192 | goto out; |
---|
4873 | 5193 | if (uid_valid(context->binder_context_mgr_uid)) { |
---|
.. | .. |
---|
4957 | 5277 | } |
---|
4958 | 5278 | } |
---|
4959 | 5279 | binder_inner_proc_unlock(proc); |
---|
| 5280 | + |
---|
| 5281 | + return 0; |
---|
| 5282 | +} |
---|
| 5283 | + |
---|
| 5284 | +static bool binder_txns_pending_ilocked(struct binder_proc *proc) |
---|
| 5285 | +{ |
---|
| 5286 | + struct rb_node *n; |
---|
| 5287 | + struct binder_thread *thread; |
---|
| 5288 | + |
---|
| 5289 | + if (proc->outstanding_txns > 0) |
---|
| 5290 | + return true; |
---|
| 5291 | + |
---|
| 5292 | + for (n = rb_first(&proc->threads); n; n = rb_next(n)) { |
---|
| 5293 | + thread = rb_entry(n, struct binder_thread, rb_node); |
---|
| 5294 | + if (thread->transaction_stack) |
---|
| 5295 | + return true; |
---|
| 5296 | + } |
---|
| 5297 | + return false; |
---|
| 5298 | +} |
---|
| 5299 | + |
---|
| 5300 | +static int binder_ioctl_freeze(struct binder_freeze_info *info, |
---|
| 5301 | + struct binder_proc *target_proc) |
---|
| 5302 | +{ |
---|
| 5303 | + int ret = 0; |
---|
| 5304 | + |
---|
| 5305 | + if (!info->enable) { |
---|
| 5306 | + binder_inner_proc_lock(target_proc); |
---|
| 5307 | + target_proc->sync_recv = false; |
---|
| 5308 | + target_proc->async_recv = false; |
---|
| 5309 | + target_proc->is_frozen = false; |
---|
| 5310 | + binder_inner_proc_unlock(target_proc); |
---|
| 5311 | + return 0; |
---|
| 5312 | + } |
---|
| 5313 | + |
---|
| 5314 | + /* |
---|
| 5315 | + * Freezing the target. Prevent new transactions by |
---|
| 5316 | + * setting frozen state. If timeout specified, wait |
---|
| 5317 | + * for transactions to drain. |
---|
| 5318 | + */ |
---|
| 5319 | + binder_inner_proc_lock(target_proc); |
---|
| 5320 | + target_proc->sync_recv = false; |
---|
| 5321 | + target_proc->async_recv = false; |
---|
| 5322 | + target_proc->is_frozen = true; |
---|
| 5323 | + binder_inner_proc_unlock(target_proc); |
---|
| 5324 | + |
---|
| 5325 | + if (info->timeout_ms > 0) |
---|
| 5326 | + ret = wait_event_interruptible_timeout( |
---|
| 5327 | + target_proc->freeze_wait, |
---|
| 5328 | + (!target_proc->outstanding_txns), |
---|
| 5329 | + msecs_to_jiffies(info->timeout_ms)); |
---|
| 5330 | + |
---|
| 5331 | + /* Check pending transactions that wait for reply */ |
---|
| 5332 | + if (ret >= 0) { |
---|
| 5333 | + binder_inner_proc_lock(target_proc); |
---|
| 5334 | + if (binder_txns_pending_ilocked(target_proc)) |
---|
| 5335 | + ret = -EAGAIN; |
---|
| 5336 | + binder_inner_proc_unlock(target_proc); |
---|
| 5337 | + } |
---|
| 5338 | + |
---|
| 5339 | + if (ret < 0) { |
---|
| 5340 | + binder_inner_proc_lock(target_proc); |
---|
| 5341 | + target_proc->is_frozen = false; |
---|
| 5342 | + binder_inner_proc_unlock(target_proc); |
---|
| 5343 | + } |
---|
| 5344 | + |
---|
| 5345 | + return ret; |
---|
| 5346 | +} |
---|
| 5347 | + |
---|
| 5348 | +static int binder_ioctl_get_freezer_info( |
---|
| 5349 | + struct binder_frozen_status_info *info) |
---|
| 5350 | +{ |
---|
| 5351 | + struct binder_proc *target_proc; |
---|
| 5352 | + bool found = false; |
---|
| 5353 | + __u32 txns_pending; |
---|
| 5354 | + |
---|
| 5355 | + info->sync_recv = 0; |
---|
| 5356 | + info->async_recv = 0; |
---|
| 5357 | + |
---|
| 5358 | + mutex_lock(&binder_procs_lock); |
---|
| 5359 | + hlist_for_each_entry(target_proc, &binder_procs, proc_node) { |
---|
| 5360 | + if (target_proc->pid == info->pid) { |
---|
| 5361 | + found = true; |
---|
| 5362 | + binder_inner_proc_lock(target_proc); |
---|
| 5363 | + txns_pending = binder_txns_pending_ilocked(target_proc); |
---|
| 5364 | + info->sync_recv |= target_proc->sync_recv | |
---|
| 5365 | + (txns_pending << 1); |
---|
| 5366 | + info->async_recv |= target_proc->async_recv; |
---|
| 5367 | + binder_inner_proc_unlock(target_proc); |
---|
| 5368 | + } |
---|
| 5369 | + } |
---|
| 5370 | + mutex_unlock(&binder_procs_lock); |
---|
| 5371 | + |
---|
| 5372 | + if (!found) |
---|
| 5373 | + return -EINVAL; |
---|
4960 | 5374 | |
---|
4961 | 5375 | return 0; |
---|
4962 | 5376 | } |
---|
.. | .. |
---|
5079 | 5493 | } |
---|
5080 | 5494 | break; |
---|
5081 | 5495 | } |
---|
| 5496 | + case BINDER_FREEZE: { |
---|
| 5497 | + struct binder_freeze_info info; |
---|
| 5498 | + struct binder_proc **target_procs = NULL, *target_proc; |
---|
| 5499 | + int target_procs_count = 0, i = 0; |
---|
| 5500 | + |
---|
| 5501 | + ret = 0; |
---|
| 5502 | + |
---|
| 5503 | + if (copy_from_user(&info, ubuf, sizeof(info))) { |
---|
| 5504 | + ret = -EFAULT; |
---|
| 5505 | + goto err; |
---|
| 5506 | + } |
---|
| 5507 | + |
---|
| 5508 | + mutex_lock(&binder_procs_lock); |
---|
| 5509 | + hlist_for_each_entry(target_proc, &binder_procs, proc_node) { |
---|
| 5510 | + if (target_proc->pid == info.pid) |
---|
| 5511 | + target_procs_count++; |
---|
| 5512 | + } |
---|
| 5513 | + |
---|
| 5514 | + if (target_procs_count == 0) { |
---|
| 5515 | + mutex_unlock(&binder_procs_lock); |
---|
| 5516 | + ret = -EINVAL; |
---|
| 5517 | + goto err; |
---|
| 5518 | + } |
---|
| 5519 | + |
---|
| 5520 | + target_procs = kcalloc(target_procs_count, |
---|
| 5521 | + sizeof(struct binder_proc *), |
---|
| 5522 | + GFP_KERNEL); |
---|
| 5523 | + |
---|
| 5524 | + if (!target_procs) { |
---|
| 5525 | + mutex_unlock(&binder_procs_lock); |
---|
| 5526 | + ret = -ENOMEM; |
---|
| 5527 | + goto err; |
---|
| 5528 | + } |
---|
| 5529 | + |
---|
| 5530 | + hlist_for_each_entry(target_proc, &binder_procs, proc_node) { |
---|
| 5531 | + if (target_proc->pid != info.pid) |
---|
| 5532 | + continue; |
---|
| 5533 | + |
---|
| 5534 | + binder_inner_proc_lock(target_proc); |
---|
| 5535 | + target_proc->tmp_ref++; |
---|
| 5536 | + binder_inner_proc_unlock(target_proc); |
---|
| 5537 | + |
---|
| 5538 | + target_procs[i++] = target_proc; |
---|
| 5539 | + } |
---|
| 5540 | + mutex_unlock(&binder_procs_lock); |
---|
| 5541 | + |
---|
| 5542 | + for (i = 0; i < target_procs_count; i++) { |
---|
| 5543 | + if (ret >= 0) |
---|
| 5544 | + ret = binder_ioctl_freeze(&info, |
---|
| 5545 | + target_procs[i]); |
---|
| 5546 | + |
---|
| 5547 | + binder_proc_dec_tmpref(target_procs[i]); |
---|
| 5548 | + } |
---|
| 5549 | + |
---|
| 5550 | + kfree(target_procs); |
---|
| 5551 | + |
---|
| 5552 | + if (ret < 0) |
---|
| 5553 | + goto err; |
---|
| 5554 | + break; |
---|
| 5555 | + } |
---|
| 5556 | + case BINDER_GET_FROZEN_INFO: { |
---|
| 5557 | + struct binder_frozen_status_info info; |
---|
| 5558 | + |
---|
| 5559 | + if (copy_from_user(&info, ubuf, sizeof(info))) { |
---|
| 5560 | + ret = -EFAULT; |
---|
| 5561 | + goto err; |
---|
| 5562 | + } |
---|
| 5563 | + |
---|
| 5564 | + ret = binder_ioctl_get_freezer_info(&info); |
---|
| 5565 | + if (ret < 0) |
---|
| 5566 | + goto err; |
---|
| 5567 | + |
---|
| 5568 | + if (copy_to_user(ubuf, &info, sizeof(info))) { |
---|
| 5569 | + ret = -EFAULT; |
---|
| 5570 | + goto err; |
---|
| 5571 | + } |
---|
| 5572 | + break; |
---|
| 5573 | + } |
---|
| 5574 | + case BINDER_ENABLE_ONEWAY_SPAM_DETECTION: { |
---|
| 5575 | + uint32_t enable; |
---|
| 5576 | + |
---|
| 5577 | + if (copy_from_user(&enable, ubuf, sizeof(enable))) { |
---|
| 5578 | + ret = -EFAULT; |
---|
| 5579 | + goto err; |
---|
| 5580 | + } |
---|
| 5581 | + binder_inner_proc_lock(proc); |
---|
| 5582 | + proc->oneway_spam_detection_enabled = (bool)enable; |
---|
| 5583 | + binder_inner_proc_unlock(proc); |
---|
| 5584 | + break; |
---|
| 5585 | + } |
---|
5082 | 5586 | default: |
---|
5083 | 5587 | ret = -EINVAL; |
---|
5084 | 5588 | goto err; |
---|
.. | .. |
---|
5088 | 5592 | if (thread) |
---|
5089 | 5593 | thread->looper_need_return = false; |
---|
5090 | 5594 | wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); |
---|
5091 | | - if (ret && ret != -ERESTARTSYS) |
---|
| 5595 | + if (ret && ret != -EINTR) |
---|
5092 | 5596 | pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); |
---|
5093 | 5597 | err_unlocked: |
---|
5094 | 5598 | trace_binder_ioctl_done(ret); |
---|
.. | .. |
---|
5116 | 5620 | (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, |
---|
5117 | 5621 | (unsigned long)pgprot_val(vma->vm_page_prot)); |
---|
5118 | 5622 | binder_alloc_vma_close(&proc->alloc); |
---|
5119 | | - binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); |
---|
5120 | 5623 | } |
---|
5121 | 5624 | |
---|
5122 | 5625 | static vm_fault_t binder_vm_fault(struct vm_fault *vmf) |
---|
.. | .. |
---|
5132 | 5635 | |
---|
5133 | 5636 | static int binder_mmap(struct file *filp, struct vm_area_struct *vma) |
---|
5134 | 5637 | { |
---|
5135 | | - int ret; |
---|
5136 | 5638 | struct binder_proc *proc = filp->private_data; |
---|
5137 | | - const char *failure_string; |
---|
5138 | 5639 | |
---|
5139 | 5640 | if (proc->tsk != current->group_leader) |
---|
5140 | 5641 | return -EINVAL; |
---|
5141 | | - |
---|
5142 | | - if ((vma->vm_end - vma->vm_start) > SZ_4M) |
---|
5143 | | - vma->vm_end = vma->vm_start + SZ_4M; |
---|
5144 | 5642 | |
---|
5145 | 5643 | binder_debug(BINDER_DEBUG_OPEN_CLOSE, |
---|
5146 | 5644 | "%s: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", |
---|
.. | .. |
---|
5149 | 5647 | (unsigned long)pgprot_val(vma->vm_page_prot)); |
---|
5150 | 5648 | |
---|
5151 | 5649 | if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) { |
---|
5152 | | - ret = -EPERM; |
---|
5153 | | - failure_string = "bad vm_flags"; |
---|
5154 | | - goto err_bad_arg; |
---|
| 5650 | + pr_err("%s: %d %lx-%lx %s failed %d\n", __func__, |
---|
| 5651 | + proc->pid, vma->vm_start, vma->vm_end, "bad vm_flags", -EPERM); |
---|
| 5652 | + return -EPERM; |
---|
5155 | 5653 | } |
---|
5156 | 5654 | vma->vm_flags |= VM_DONTCOPY | VM_MIXEDMAP; |
---|
5157 | 5655 | vma->vm_flags &= ~VM_MAYWRITE; |
---|
.. | .. |
---|
5159 | 5657 | vma->vm_ops = &binder_vm_ops; |
---|
5160 | 5658 | vma->vm_private_data = proc; |
---|
5161 | 5659 | |
---|
5162 | | - ret = binder_alloc_mmap_handler(&proc->alloc, vma); |
---|
5163 | | - if (ret) |
---|
5164 | | - return ret; |
---|
5165 | | - mutex_lock(&proc->files_lock); |
---|
5166 | | - proc->files = get_files_struct(current); |
---|
5167 | | - mutex_unlock(&proc->files_lock); |
---|
5168 | | - return 0; |
---|
5169 | | - |
---|
5170 | | -err_bad_arg: |
---|
5171 | | - pr_err("%s: %d %lx-%lx %s failed %d\n", __func__, |
---|
5172 | | - proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); |
---|
5173 | | - return ret; |
---|
| 5660 | + return binder_alloc_mmap_handler(&proc->alloc, vma); |
---|
5174 | 5661 | } |
---|
5175 | 5662 | |
---|
5176 | 5663 | static int binder_open(struct inode *nodp, struct file *filp) |
---|
5177 | 5664 | { |
---|
5178 | | - struct binder_proc *proc; |
---|
| 5665 | + struct binder_proc *proc, *itr; |
---|
| 5666 | + struct binder_proc_ext *eproc; |
---|
5179 | 5667 | struct binder_device *binder_dev; |
---|
5180 | 5668 | struct binderfs_info *info; |
---|
5181 | 5669 | struct dentry *binder_binderfs_dir_entry_proc = NULL; |
---|
| 5670 | + bool existing_pid = false; |
---|
5182 | 5671 | |
---|
5183 | 5672 | binder_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d:%d\n", __func__, |
---|
5184 | 5673 | current->group_leader->pid, current->pid); |
---|
5185 | 5674 | |
---|
5186 | | - proc = kzalloc(sizeof(*proc), GFP_KERNEL); |
---|
| 5675 | + eproc = kzalloc(sizeof(*eproc), GFP_KERNEL); |
---|
| 5676 | + proc = &eproc->proc; |
---|
5187 | 5677 | if (proc == NULL) |
---|
5188 | 5678 | return -ENOMEM; |
---|
5189 | 5679 | spin_lock_init(&proc->inner_lock); |
---|
5190 | 5680 | spin_lock_init(&proc->outer_lock); |
---|
5191 | 5681 | get_task_struct(current->group_leader); |
---|
5192 | 5682 | proc->tsk = current->group_leader; |
---|
5193 | | - mutex_init(&proc->files_lock); |
---|
5194 | | - proc->cred = get_cred(filp->f_cred); |
---|
| 5683 | + eproc->cred = get_cred(filp->f_cred); |
---|
5195 | 5684 | INIT_LIST_HEAD(&proc->todo); |
---|
| 5685 | + init_waitqueue_head(&proc->freeze_wait); |
---|
5196 | 5686 | if (binder_supported_policy(current->policy)) { |
---|
5197 | 5687 | proc->default_priority.sched_policy = current->policy; |
---|
5198 | 5688 | proc->default_priority.prio = current->normal_prio; |
---|
.. | .. |
---|
5221 | 5711 | filp->private_data = proc; |
---|
5222 | 5712 | |
---|
5223 | 5713 | mutex_lock(&binder_procs_lock); |
---|
| 5714 | + hlist_for_each_entry(itr, &binder_procs, proc_node) { |
---|
| 5715 | + if (itr->pid == proc->pid) { |
---|
| 5716 | + existing_pid = true; |
---|
| 5717 | + break; |
---|
| 5718 | + } |
---|
| 5719 | + } |
---|
5224 | 5720 | hlist_add_head(&proc->proc_node, &binder_procs); |
---|
5225 | 5721 | mutex_unlock(&binder_procs_lock); |
---|
5226 | | - |
---|
5227 | | - if (binder_debugfs_dir_entry_proc) { |
---|
| 5722 | + trace_android_vh_binder_preset(&binder_procs, &binder_procs_lock); |
---|
| 5723 | + if (binder_debugfs_dir_entry_proc && !existing_pid) { |
---|
5228 | 5724 | char strbuf[11]; |
---|
5229 | 5725 | |
---|
5230 | 5726 | snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); |
---|
5231 | 5727 | /* |
---|
5232 | | - * proc debug entries are shared between contexts, so |
---|
5233 | | - * this will fail if the process tries to open the driver |
---|
5234 | | - * again with a different context. The priting code will |
---|
5235 | | - * anyway print all contexts that a given PID has, so this |
---|
5236 | | - * is not a problem. |
---|
| 5728 | + * proc debug entries are shared between contexts. |
---|
| 5729 | + * Only create for the first PID to avoid debugfs log spamming |
---|
| 5730 | + * The printing code will anyway print all contexts for a given |
---|
| 5731 | + * PID so this is not a problem. |
---|
5237 | 5732 | */ |
---|
5238 | 5733 | proc->debugfs_entry = debugfs_create_file(strbuf, 0444, |
---|
5239 | 5734 | binder_debugfs_dir_entry_proc, |
---|
.. | .. |
---|
5241 | 5736 | &proc_fops); |
---|
5242 | 5737 | } |
---|
5243 | 5738 | |
---|
5244 | | - if (binder_binderfs_dir_entry_proc) { |
---|
| 5739 | + if (binder_binderfs_dir_entry_proc && !existing_pid) { |
---|
5245 | 5740 | char strbuf[11]; |
---|
5246 | 5741 | struct dentry *binderfs_entry; |
---|
5247 | 5742 | |
---|
5248 | 5743 | snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); |
---|
5249 | 5744 | /* |
---|
5250 | 5745 | * Similar to debugfs, the process specific log file is shared |
---|
5251 | | - * between contexts. If the file has already been created for a |
---|
5252 | | - * process, the following binderfs_create_file() call will |
---|
5253 | | - * fail with error code EEXIST if another context of the same |
---|
5254 | | - * process invoked binder_open(). This is ok since same as |
---|
5255 | | - * debugfs, the log file will contain information on all |
---|
5256 | | - * contexts of a given PID. |
---|
| 5746 | + * between contexts. Only create for the first PID. |
---|
| 5747 | + * This is ok since same as debugfs, the log file will contain |
---|
| 5748 | + * information on all contexts of a given PID. |
---|
5257 | 5749 | */ |
---|
5258 | 5750 | binderfs_entry = binderfs_create_file(binder_binderfs_dir_entry_proc, |
---|
5259 | 5751 | strbuf, &proc_fops, (void *)(unsigned long)proc->pid); |
---|
.. | .. |
---|
5263 | 5755 | int error; |
---|
5264 | 5756 | |
---|
5265 | 5757 | error = PTR_ERR(binderfs_entry); |
---|
5266 | | - if (error != -EEXIST) { |
---|
5267 | | - pr_warn("Unable to create file %s in binderfs (error %d)\n", |
---|
5268 | | - strbuf, error); |
---|
5269 | | - } |
---|
| 5758 | + pr_warn("Unable to create file %s in binderfs (error %d)\n", |
---|
| 5759 | + strbuf, error); |
---|
5270 | 5760 | } |
---|
5271 | 5761 | } |
---|
5272 | 5762 | |
---|
.. | .. |
---|
5391 | 5881 | struct rb_node *n; |
---|
5392 | 5882 | int threads, nodes, incoming_refs, outgoing_refs, active_transactions; |
---|
5393 | 5883 | |
---|
5394 | | - BUG_ON(proc->files); |
---|
5395 | | - |
---|
5396 | 5884 | mutex_lock(&binder_procs_lock); |
---|
5397 | 5885 | hlist_del(&proc->proc_node); |
---|
5398 | 5886 | mutex_unlock(&binder_procs_lock); |
---|
.. | .. |
---|
5414 | 5902 | proc->tmp_ref++; |
---|
5415 | 5903 | |
---|
5416 | 5904 | proc->is_dead = true; |
---|
| 5905 | + proc->is_frozen = false; |
---|
| 5906 | + proc->sync_recv = false; |
---|
| 5907 | + proc->async_recv = false; |
---|
5417 | 5908 | threads = 0; |
---|
5418 | 5909 | active_transactions = 0; |
---|
5419 | 5910 | while ((n = rb_first(&proc->threads))) { |
---|
.. | .. |
---|
5474 | 5965 | static void binder_deferred_func(struct work_struct *work) |
---|
5475 | 5966 | { |
---|
5476 | 5967 | struct binder_proc *proc; |
---|
5477 | | - struct files_struct *files; |
---|
5478 | 5968 | |
---|
5479 | 5969 | int defer; |
---|
5480 | 5970 | |
---|
.. | .. |
---|
5492 | 5982 | } |
---|
5493 | 5983 | mutex_unlock(&binder_deferred_lock); |
---|
5494 | 5984 | |
---|
5495 | | - files = NULL; |
---|
5496 | | - if (defer & BINDER_DEFERRED_PUT_FILES) { |
---|
5497 | | - mutex_lock(&proc->files_lock); |
---|
5498 | | - files = proc->files; |
---|
5499 | | - if (files) |
---|
5500 | | - proc->files = NULL; |
---|
5501 | | - mutex_unlock(&proc->files_lock); |
---|
5502 | | - } |
---|
5503 | | - |
---|
5504 | 5985 | if (defer & BINDER_DEFERRED_FLUSH) |
---|
5505 | 5986 | binder_deferred_flush(proc); |
---|
5506 | 5987 | |
---|
5507 | 5988 | if (defer & BINDER_DEFERRED_RELEASE) |
---|
5508 | 5989 | binder_deferred_release(proc); /* frees proc */ |
---|
5509 | | - |
---|
5510 | | - if (files) |
---|
5511 | | - put_files_struct(files); |
---|
5512 | 5990 | } while (proc); |
---|
5513 | 5991 | } |
---|
5514 | 5992 | static DECLARE_WORK(binder_deferred_work, binder_deferred_func); |
---|
.. | .. |
---|
5535 | 6013 | struct binder_buffer *buffer = t->buffer; |
---|
5536 | 6014 | |
---|
5537 | 6015 | spin_lock(&t->lock); |
---|
| 6016 | + trace_android_vh_binder_print_transaction_info(m, proc, prefix, t); |
---|
5538 | 6017 | to_proc = t->to_proc; |
---|
5539 | 6018 | seq_printf(m, |
---|
5540 | 6019 | "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %d:%d r%d", |
---|
.. | .. |
---|
5779 | 6258 | "BR_FINISHED", |
---|
5780 | 6259 | "BR_DEAD_BINDER", |
---|
5781 | 6260 | "BR_CLEAR_DEATH_NOTIFICATION_DONE", |
---|
5782 | | - "BR_FAILED_REPLY" |
---|
| 6261 | + "BR_FAILED_REPLY", |
---|
| 6262 | + "BR_FROZEN_REPLY", |
---|
| 6263 | + "BR_ONEWAY_SPAM_SUSPECT", |
---|
5783 | 6264 | }; |
---|
5784 | 6265 | |
---|
5785 | 6266 | static const char * const binder_command_strings[] = { |
---|
.. | .. |
---|
5920 | 6401 | print_binder_stats(m, " ", &proc->stats); |
---|
5921 | 6402 | } |
---|
5922 | 6403 | |
---|
5923 | | - |
---|
5924 | | -int binder_state_show(struct seq_file *m, void *unused) |
---|
| 6404 | +static int state_show(struct seq_file *m, void *unused) |
---|
5925 | 6405 | { |
---|
5926 | 6406 | struct binder_proc *proc; |
---|
5927 | 6407 | struct binder_node *node; |
---|
.. | .. |
---|
5960 | 6440 | return 0; |
---|
5961 | 6441 | } |
---|
5962 | 6442 | |
---|
5963 | | -int binder_stats_show(struct seq_file *m, void *unused) |
---|
| 6443 | +static int stats_show(struct seq_file *m, void *unused) |
---|
5964 | 6444 | { |
---|
5965 | 6445 | struct binder_proc *proc; |
---|
5966 | 6446 | |
---|
.. | .. |
---|
5976 | 6456 | return 0; |
---|
5977 | 6457 | } |
---|
5978 | 6458 | |
---|
5979 | | -int binder_transactions_show(struct seq_file *m, void *unused) |
---|
| 6459 | +static int transactions_show(struct seq_file *m, void *unused) |
---|
5980 | 6460 | { |
---|
5981 | 6461 | struct binder_proc *proc; |
---|
5982 | 6462 | |
---|
.. | .. |
---|
6032 | 6512 | "\n" : " (incomplete)\n"); |
---|
6033 | 6513 | } |
---|
6034 | 6514 | |
---|
6035 | | -int binder_transaction_log_show(struct seq_file *m, void *unused) |
---|
| 6515 | +static int transaction_log_show(struct seq_file *m, void *unused) |
---|
6036 | 6516 | { |
---|
6037 | 6517 | struct binder_transaction_log *log = m->private; |
---|
6038 | 6518 | unsigned int log_cur = atomic_read(&log->cur); |
---|
.. | .. |
---|
6057 | 6537 | .owner = THIS_MODULE, |
---|
6058 | 6538 | .poll = binder_poll, |
---|
6059 | 6539 | .unlocked_ioctl = binder_ioctl, |
---|
6060 | | - .compat_ioctl = binder_ioctl, |
---|
| 6540 | + .compat_ioctl = compat_ptr_ioctl, |
---|
6061 | 6541 | .mmap = binder_mmap, |
---|
6062 | 6542 | .open = binder_open, |
---|
6063 | 6543 | .flush = binder_flush, |
---|
6064 | 6544 | .release = binder_release, |
---|
| 6545 | +}; |
---|
| 6546 | + |
---|
| 6547 | +DEFINE_SHOW_ATTRIBUTE(state); |
---|
| 6548 | +DEFINE_SHOW_ATTRIBUTE(stats); |
---|
| 6549 | +DEFINE_SHOW_ATTRIBUTE(transactions); |
---|
| 6550 | +DEFINE_SHOW_ATTRIBUTE(transaction_log); |
---|
| 6551 | + |
---|
| 6552 | +const struct binder_debugfs_entry binder_debugfs_entries[] = { |
---|
| 6553 | + { |
---|
| 6554 | + .name = "state", |
---|
| 6555 | + .mode = 0444, |
---|
| 6556 | + .fops = &state_fops, |
---|
| 6557 | + .data = NULL, |
---|
| 6558 | + }, |
---|
| 6559 | + { |
---|
| 6560 | + .name = "stats", |
---|
| 6561 | + .mode = 0444, |
---|
| 6562 | + .fops = &stats_fops, |
---|
| 6563 | + .data = NULL, |
---|
| 6564 | + }, |
---|
| 6565 | + { |
---|
| 6566 | + .name = "transactions", |
---|
| 6567 | + .mode = 0444, |
---|
| 6568 | + .fops = &transactions_fops, |
---|
| 6569 | + .data = NULL, |
---|
| 6570 | + }, |
---|
| 6571 | + { |
---|
| 6572 | + .name = "transaction_log", |
---|
| 6573 | + .mode = 0444, |
---|
| 6574 | + .fops = &transaction_log_fops, |
---|
| 6575 | + .data = &binder_transaction_log, |
---|
| 6576 | + }, |
---|
| 6577 | + { |
---|
| 6578 | + .name = "failed_transaction_log", |
---|
| 6579 | + .mode = 0444, |
---|
| 6580 | + .fops = &transaction_log_fops, |
---|
| 6581 | + .data = &binder_transaction_log_failed, |
---|
| 6582 | + }, |
---|
| 6583 | + {} /* terminator */ |
---|
6065 | 6584 | }; |
---|
6066 | 6585 | |
---|
6067 | 6586 | static int __init init_binder_device(const char *name) |
---|
.. | .. |
---|
6109 | 6628 | atomic_set(&binder_transaction_log_failed.cur, ~0U); |
---|
6110 | 6629 | |
---|
6111 | 6630 | binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL); |
---|
6112 | | - if (binder_debugfs_dir_entry_root) |
---|
| 6631 | + if (binder_debugfs_dir_entry_root) { |
---|
| 6632 | + const struct binder_debugfs_entry *db_entry; |
---|
| 6633 | + |
---|
| 6634 | + binder_for_each_debugfs_entry(db_entry) |
---|
| 6635 | + debugfs_create_file(db_entry->name, |
---|
| 6636 | + db_entry->mode, |
---|
| 6637 | + binder_debugfs_dir_entry_root, |
---|
| 6638 | + db_entry->data, |
---|
| 6639 | + db_entry->fops); |
---|
| 6640 | + |
---|
6113 | 6641 | binder_debugfs_dir_entry_proc = debugfs_create_dir("proc", |
---|
6114 | 6642 | binder_debugfs_dir_entry_root); |
---|
6115 | | - |
---|
6116 | | - if (binder_debugfs_dir_entry_root) { |
---|
6117 | | - debugfs_create_file("state", |
---|
6118 | | - 0444, |
---|
6119 | | - binder_debugfs_dir_entry_root, |
---|
6120 | | - NULL, |
---|
6121 | | - &binder_state_fops); |
---|
6122 | | - debugfs_create_file("stats", |
---|
6123 | | - 0444, |
---|
6124 | | - binder_debugfs_dir_entry_root, |
---|
6125 | | - NULL, |
---|
6126 | | - &binder_stats_fops); |
---|
6127 | | - debugfs_create_file("transactions", |
---|
6128 | | - 0444, |
---|
6129 | | - binder_debugfs_dir_entry_root, |
---|
6130 | | - NULL, |
---|
6131 | | - &binder_transactions_fops); |
---|
6132 | | - debugfs_create_file("transaction_log", |
---|
6133 | | - 0444, |
---|
6134 | | - binder_debugfs_dir_entry_root, |
---|
6135 | | - &binder_transaction_log, |
---|
6136 | | - &binder_transaction_log_fops); |
---|
6137 | | - debugfs_create_file("failed_transaction_log", |
---|
6138 | | - 0444, |
---|
6139 | | - binder_debugfs_dir_entry_root, |
---|
6140 | | - &binder_transaction_log_failed, |
---|
6141 | | - &binder_transaction_log_fops); |
---|
6142 | 6643 | } |
---|
6143 | 6644 | |
---|
6144 | 6645 | if (!IS_ENABLED(CONFIG_ANDROID_BINDERFS) && |
---|
.. | .. |
---|
6178 | 6679 | |
---|
6179 | 6680 | err_alloc_device_names_failed: |
---|
6180 | 6681 | debugfs_remove_recursive(binder_debugfs_dir_entry_root); |
---|
| 6682 | + binder_alloc_shrinker_exit(); |
---|
6181 | 6683 | |
---|
6182 | 6684 | return ret; |
---|
6183 | 6685 | } |
---|
.. | .. |
---|
6186 | 6688 | |
---|
6187 | 6689 | #define CREATE_TRACE_POINTS |
---|
6188 | 6690 | #include "binder_trace.h" |
---|
| 6691 | +EXPORT_TRACEPOINT_SYMBOL_GPL(binder_transaction_received); |
---|
6189 | 6692 | |
---|
6190 | 6693 | MODULE_LICENSE("GPL v2"); |
---|