summaryrefslogtreecommitdiff
path: root/drivers/android/binder.c
diff options
context:
space:
mode:
authorBlagovest Kolenichev <bkolenichev@codeaurora.org>2017-10-19 16:55:17 -0700
committerBlagovest Kolenichev <bkolenichev@codeaurora.org>2017-10-20 02:11:57 -0700
commitb2465235ad43e26e351e3b437a7f90f927cf11a4 (patch)
tree6339f0e9b8778e98d9664f8570403ad93d7313cb /drivers/android/binder.c
parent709d3a4e3edcb0963185f9481b178c9cfb9aab55 (diff)
parent73a2b70bdf78f3ad747dd740c9e55c062c71b86c (diff)
Merge android-4.4@73a2b70 (v4.4.92) into msm-4.4
* refs/heads/tmp-73a2b70 Linux 4.4.92 ext4: don't allow encrypted operations without keys ext4: Don't clear SGID when inheriting ACLs ext4: fix data corruption for mmap writes sched/cpuset/pm: Fix cpuset vs. suspend-resume bugs nvme: protect against simultaneous shutdown invocations drm/i915/bios: ignore HDMI on port A brcmfmac: setup passive scan if requested by user-space uwb: ensure that endpoint is interrupt uwb: properly check kthread_run return value iio: adc: mcp320x: Fix oops on module unload iio: adc: mcp320x: Fix readout of negative voltages iio: ad7793: Fix the serial interface reset iio: core: Return error for failed read_reg staging: iio: ad7192: Fix - use the dedicated reset function avoiding dma from stack. iio: ad_sigma_delta: Implement a dedicated reset function iio: adc: twl4030: Disable the vusb3v1 rugulator in the error handling path of 'twl4030_madc_probe()' iio: adc: twl4030: Fix an error handling path in 'twl4030_madc_probe()' xhci: fix finding correct bus_state structure for USB 3.1 hosts USB: fix out-of-bounds in usb_set_configuration usb: Increase quirk delay for USB devices USB: core: harden cdc_parse_cdc_header USB: uas: fix bug in handling of alternate settings scsi: sd: Do not override max_sectors_kb sysfs setting iwlwifi: add workaround to disable wide channels in 5GHz HID: i2c-hid: allocate hid buffers for real worst case ftrace: Fix kmemleak in unregister_ftrace_graph stm class: Fix a use-after-free Drivers: hv: fcopy: restore correct transfer length driver core: platform: Don't read past the end of "driver_override" buffer ALSA: usx2y: Suppress kernel warning at page allocation failures ALSA: compress: Remove unused variable lsm: fix smack_inode_removexattr and xattr_getsecurity memleak USB: g_mass_storage: Fix deadlock when driver is unbound usb: gadget: mass_storage: set msg_registered after msg registered USB: devio: Don't corrupt user memory USB: dummy-hcd: Fix erroneous synchronization change USB: dummy-hcd: fix infinite-loop resubmission bug USB: dummy-hcd: fix connection failures (wrong speed) usb: pci-quirks.c: Corrected timeout values used in handshake ALSA: usb-audio: Check out-of-bounds access by corrupted buffer descriptor usb: renesas_usbhs: fix usbhsf_fifo_clear() for RX direction usb: renesas_usbhs: fix the BCLR setting condition for non-DCP pipe usb-storage: unusual_devs entry to fix write-access regression for Seagate external drives usb: gadget: udc: atmel: set vbus irqflags explicitly USB: gadgetfs: fix copy_to_user while holding spinlock USB: gadgetfs: Fix crash caused by inadequate synchronization usb: gadget: inode.c: fix unbalanced spin_lock in ep0_write ANDROID: binder: init desired_prio.sched_policy before use it BACKPORT: net: xfrm: support setting an output mark. UPSTREAM: xfrm: Only add l3mdev oif to dst lookups UPSTREAM: net: l3mdev: Add master device lookup by index Linux 4.4.91 ttpci: address stringop overflow warning ALSA: au88x0: avoid theoretical uninitialized access ARM: remove duplicate 'const' annotations' IB/qib: fix false-postive maybe-uninitialized warning drivers: firmware: psci: drop duplicate const from psci_of_match libata: transport: Remove circular dependency at free time xfs: remove kmem_zalloc_greedy i2c: meson: fix wrong variable usage in meson_i2c_put_data md/raid10: submit bio directly to replacement disk rds: ib: add error handle iommu/io-pgtable-arm: Check for leaf entry before dereferencing it parisc: perf: Fix potential NULL pointer dereference netfilter: nfnl_cthelper: fix incorrect helper->expect_class_max exynos-gsc: Do not swap cb/cr for semi planar formats MIPS: IRQ Stack: Unwind IRQ stack onto task stack netfilter: invoke synchronize_rcu after set the _hook_ to NULL bridge: netlink: register netdevice before executing changelink mmc: sdio: fix alignment issue in struct sdio_func usb: plusb: Add support for PL-27A1 team: fix memory leaks net/packet: check length in getsockopt() called with PACKET_HDRLEN net: core: Prevent from dereferencing null pointer when releasing SKB MIPS: Lantiq: Fix another request_mem_region() return code check ASoC: dapm: fix some pointer error handling usb: chipidea: vbus event may exist before starting gadget audit: log 32-bit socketcalls ASoC: dapm: handle probe deferrals partitions/efi: Fix integer overflow in GPT size calculation USB: serial: mos7840: fix control-message error handling USB: serial: mos7720: fix control-message error handling drm/amdkfd: fix improper return value on error IB/ipoib: Replace list_del of the neigh->list with list_del_init IB/ipoib: rtnl_unlock can not come after free_netdev IB/ipoib: Fix deadlock over vlan_mutex tty: goldfish: Fix a parameter of a call to free_irq ARM: 8635/1: nommu: allow enabling REMAP_VECTORS_TO_RAM iio: adc: hx711: Add DT binding for avia,hx711 iio: adc: axp288: Drop bogus AXP288_ADC_TS_PIN_CTRL register modifications hwmon: (gl520sm) Fix overflows and crash seen when writing into limit attributes sh_eth: use correct name for ECMR_MPDE bit extcon: axp288: Use vbus-valid instead of -present to determine cable presence igb: re-assign hw address pointer on reset after PCI error MIPS: ralink: Fix incorrect assignment on ralink_soc MIPS: Ensure bss section ends on a long-aligned address ARM: dts: r8a7790: Use R-Car Gen 2 fallback binding for msiof nodes RDS: RDMA: Fix the composite message user notification GFS2: Fix reference to ERR_PTR in gfs2_glock_iter_next drm: bridge: add DT bindings for TI ths8135 drm_fourcc: Fix DRM_FORMAT_MOD_LINEAR #define FROMLIST: tracing: Add support for preempt and irq enable/disable events FROMLIST: tracing: Prepare to add preempt and irq trace events ANDROID: binder: fix transaction leak. ANDROID: binder: Add tracing for binder priority inheritance. Linux 4.4.90 fix xen_swiotlb_dma_mmap prototype swiotlb-xen: implement xen_swiotlb_dma_mmap callback video: fbdev: aty: do not leak uninitialized padding in clk to userspace KVM: VMX: use cmpxchg64 ARM: pxa: fix the number of DMA requestor lines ARM: pxa: add the number of DMA requestor lines dmaengine: mmp-pdma: add number of requestors cxl: Fix driver use count KVM: VMX: remove WARN_ON_ONCE in kvm_vcpu_trigger_posted_interrupt KVM: VMX: do not change SN bit in vmx_update_pi_irte() timer/sysclt: Restrict timer migration sysctl values to 0 and 1 gfs2: Fix debugfs glocks dump x86/fpu: Don't let userspace set bogus xcomp_bv btrfs: prevent to set invalid default subvolid btrfs: propagate error to btrfs_cmp_data_prepare caller btrfs: fix NULL pointer dereference from free_reloc_roots() PCI: Fix race condition with driver_override kvm: nVMX: Don't allow L2 to access the hardware CR8 KVM: VMX: Do not BUG() on out-of-bounds guest IRQ arm64: fault: Route pte translation faults via do_translation_fault arm64: Make sure SPsel is always set seccomp: fix the usage of get/put_seccomp_filter() in seccomp_get_filter() bsg-lib: don't free job in bsg_prepare_job nl80211: check for the required netlink attributes presence vfs: Return -ENXIO for negative SEEK_HOLE / SEEK_DATA offsets SMB3: Don't ignore O_SYNC/O_DSYNC and O_DIRECT flags SMB: Validate negotiate (to protect against downgrade) even if signing off Fix SMB3.1.1 guest authentication to Samba powerpc/pseries: Fix parent_dn reference leak in add_dt_node() KEYS: prevent KEYCTL_READ on negative key KEYS: prevent creating a different user's keyrings KEYS: fix writing past end of user-supplied buffer in keyring_read() crypto: talitos - fix sha224 crypto: talitos - Don't provide setkey for non hmac hashing algs. scsi: scsi_transport_iscsi: fix the issue that iscsi_if_rx doesn't parse nlmsg properly md/raid5: preserve STRIPE_ON_UNPLUG_LIST in break_stripe_batch_list md/raid5: fix a race condition in stripe batch tracing: Erase irqsoff trace with empty write tracing: Fix trace_pipe behavior for instance traces KVM: PPC: Book3S: Fix race and leak in kvm_vm_ioctl_create_spapr_tce() mac80211: flush hw_roc_start work before cancelling the ROC cifs: release auth_key.response for reconnect. f2fs: catch up to v4.14-rc1 UPSTREAM: cpufreq: schedutil: use now as reference when aggregating shared policy requests ANDROID: add script to fetch android kernel config fragments f2fs: reorganize stat information f2fs: clean up flush/discard command namings f2fs: check in-memory sit version bitmap f2fs: check in-memory nat version bitmap f2fs: check in-memory block bitmap f2fs: introduce FI_ATOMIC_COMMIT f2fs: clean up with list_{first, last}_entry f2fs: return fs_trim if there is no candidate f2fs: avoid needless checkpoint in f2fs_trim_fs f2fs: relax async discard commands more f2fs: drop exist_data for inline_data when truncated to 0 f2fs: don't allow encrypted operations without keys f2fs: show the max number of atomic operations f2fs: get io size bit from mount option f2fs: support IO alignment for DATA and NODE writes f2fs: add submit_bio tracepoint f2fs: reassign new segment for mode=lfs f2fs: fix a missing discard prefree segments f2fs: use rb_entry_safe f2fs: add a case of no need to read a page in write begin f2fs: fix a problem of using memory after free f2fs: remove unneeded condition f2fs: don't cache nat entry if out of memory f2fs: remove unused values in recover_fsync_data f2fs: support async discard based on v4.9 f2fs: resolve op and op_flags confilcts f2fs: remove wrong backported codes FROMLIST: binder: fix use-after-free in binder_transaction() UPSTREAM: ipv6: fib: Unlink replaced routes from their nodes Signed-off-by: Blagovest Kolenichev <bkolenichev@codeaurora.org> Conflicts: fs/f2fs/crypto_key.c fs/f2fs/f2fs_crypto.h net/wireless/nl80211.c sound/usb/card.c Change-Id: I742aeaec84c7892165976b7bea3e07bdd6881d93 Signed-off-by: Blagovest Kolenichev <bkolenichev@codeaurora.org>
Diffstat (limited to 'drivers/android/binder.c')
-rw-r--r--drivers/android/binder.c142
1 files changed, 102 insertions, 40 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 3419cb0b4447..667bcef5055a 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -1154,6 +1154,10 @@ static void binder_do_set_priority(struct task_struct *task,
task->pid, desired.prio,
to_kernel_prio(policy, priority));
+ trace_binder_set_priority(task->tgid, task->pid, task->normal_prio,
+ to_kernel_prio(policy, priority),
+ desired.prio);
+
/* Set the actual priority */
if (task->policy != policy || is_rt_policy(policy)) {
struct sched_param params;
@@ -1185,7 +1189,7 @@ static void binder_transaction_priority(struct task_struct *task,
struct binder_priority node_prio,
bool inherit_rt)
{
- struct binder_priority desired_prio;
+ struct binder_priority desired_prio = t->priority;
if (t->set_priority_called)
return;
@@ -1197,9 +1201,6 @@ static void binder_transaction_priority(struct task_struct *task,
if (!inherit_rt && is_rt_policy(desired_prio.sched_policy)) {
desired_prio.prio = NICE_TO_PRIO(0);
desired_prio.sched_policy = SCHED_NORMAL;
- } else {
- desired_prio.prio = t->priority.prio;
- desired_prio.sched_policy = t->priority.sched_policy;
}
if (node_prio.prio < t->priority.prio ||
@@ -2103,6 +2104,26 @@ static void binder_send_failed_reply(struct binder_transaction *t,
}
/**
+ * binder_cleanup_transaction() - cleans up undelivered transaction
+ * @t: transaction that needs to be cleaned up
+ * @reason: reason the transaction wasn't delivered
+ * @error_code: error to return to caller (if synchronous call)
+ */
+static void binder_cleanup_transaction(struct binder_transaction *t,
+ const char *reason,
+ uint32_t error_code)
+{
+ if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) {
+ binder_send_failed_reply(t, error_code);
+ } else {
+ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+ "undelivered transaction %d, %s\n",
+ t->debug_id, reason);
+ binder_free_transaction(t);
+ }
+}
+
+/**
* binder_validate_object() - checks for a valid metadata object in a buffer.
* @buffer: binder_buffer that we're parsing.
* @offset: offset in the buffer at which to validate an object.
@@ -2744,6 +2765,48 @@ static bool binder_proc_transaction(struct binder_transaction *t,
return true;
}
+/**
+ * binder_get_node_refs_for_txn() - Get required refs on node for txn
+ * @node: struct binder_node for which to get refs
+ * @proc: returns @node->proc if valid
+ * @error: if no @proc then returns BR_DEAD_REPLY
+ *
+ * User-space normally keeps the node alive when creating a transaction
+ * since it has a reference to the target. The local strong ref keeps it
+ * alive if the sending process dies before the target process processes
+ * the transaction. If the source process is malicious or has a reference
+ * counting bug, relying on the local strong ref can fail.
+ *
+ * Since user-space can cause the local strong ref to go away, we also take
+ * a tmpref on the node to ensure it survives while we are constructing
+ * the transaction. We also need a tmpref on the proc while we are
+ * constructing the transaction, so we take that here as well.
+ *
+ * Return: The target_node with refs taken or NULL if no @node->proc is NULL.
+ * Also sets @proc if valid. If the @node->proc is NULL indicating that the
+ * target proc has died, @error is set to BR_DEAD_REPLY
+ */
+static struct binder_node *binder_get_node_refs_for_txn(
+ struct binder_node *node,
+ struct binder_proc **procp,
+ uint32_t *error)
+{
+ struct binder_node *target_node = NULL;
+
+ binder_node_inner_lock(node);
+ if (node->proc) {
+ target_node = node;
+ binder_inc_node_nilocked(node, 1, 0, NULL);
+ binder_inc_node_tmpref_ilocked(node);
+ node->proc->tmp_ref++;
+ *procp = node->proc;
+ } else
+ *error = BR_DEAD_REPLY;
+ binder_node_inner_unlock(node);
+
+ return target_node;
+}
+
static void binder_transaction(struct binder_proc *proc,
struct binder_thread *thread,
struct binder_transaction_data *tr, int reply,
@@ -2846,43 +2909,35 @@ static void binder_transaction(struct binder_proc *proc,
ref = binder_get_ref_olocked(proc, tr->target.handle,
true);
if (ref) {
- binder_inc_node(ref->node, 1, 0, NULL);
- target_node = ref->node;
- }
- binder_proc_unlock(proc);
- if (target_node == NULL) {
+ target_node = binder_get_node_refs_for_txn(
+ ref->node, &target_proc,
+ &return_error);
+ } else {
binder_user_error("%d:%d got transaction to invalid handle\n",
- proc->pid, thread->pid);
+ proc->pid, thread->pid);
return_error = BR_FAILED_REPLY;
- return_error_param = -EINVAL;
- return_error_line = __LINE__;
- goto err_invalid_target_handle;
}
+ binder_proc_unlock(proc);
} else {
mutex_lock(&context->context_mgr_node_lock);
target_node = context->binder_context_mgr_node;
- if (target_node == NULL) {
+ if (target_node)
+ target_node = binder_get_node_refs_for_txn(
+ target_node, &target_proc,
+ &return_error);
+ else
return_error = BR_DEAD_REPLY;
- mutex_unlock(&context->context_mgr_node_lock);
- return_error_line = __LINE__;
- goto err_no_context_mgr_node;
- }
- binder_inc_node(target_node, 1, 0, NULL);
mutex_unlock(&context->context_mgr_node_lock);
}
- e->to_node = target_node->debug_id;
- binder_node_lock(target_node);
- target_proc = target_node->proc;
- if (target_proc == NULL) {
- binder_node_unlock(target_node);
- return_error = BR_DEAD_REPLY;
+ if (!target_node) {
+ /*
+ * return_error is set above
+ */
+ return_error_param = -EINVAL;
return_error_line = __LINE__;
goto err_dead_binder;
}
- binder_inner_proc_lock(target_proc);
- target_proc->tmp_ref++;
- binder_inner_proc_unlock(target_proc);
- binder_node_unlock(target_node);
+ e->to_node = target_node->debug_id;
if (security_binder_transaction(proc->tsk,
target_proc->tsk) < 0) {
return_error = BR_FAILED_REPLY;
@@ -3241,6 +3296,8 @@ static void binder_transaction(struct binder_proc *proc,
if (target_thread)
binder_thread_dec_tmpref(target_thread);
binder_proc_dec_tmpref(target_proc);
+ if (target_node)
+ binder_dec_node_tmpref(target_node);
/*
* write barrier to synchronize with initialization
* of log entry
@@ -3260,6 +3317,8 @@ err_bad_parent:
err_copy_data_failed:
trace_binder_transaction_failed_buffer_release(t->buffer);
binder_transaction_buffer_release(target_proc, t->buffer, offp);
+ if (target_node)
+ binder_dec_node_tmpref(target_node);
target_node = NULL;
t->buffer->transaction = NULL;
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
@@ -3274,13 +3333,14 @@ err_bad_call_stack:
err_empty_call_stack:
err_dead_binder:
err_invalid_target_handle:
-err_no_context_mgr_node:
if (target_thread)
binder_thread_dec_tmpref(target_thread);
if (target_proc)
binder_proc_dec_tmpref(target_proc);
- if (target_node)
+ if (target_node) {
binder_dec_node(target_node, 1, 0);
+ binder_dec_node_tmpref(target_node);
+ }
binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
"%d:%d transaction failed %d/%d, size %lld-%lld line %d\n",
@@ -4145,12 +4205,20 @@ retry:
if (put_user(cmd, (uint32_t __user *)ptr)) {
if (t_from)
binder_thread_dec_tmpref(t_from);
+
+ binder_cleanup_transaction(t, "put_user failed",
+ BR_FAILED_REPLY);
+
return -EFAULT;
}
ptr += sizeof(uint32_t);
if (copy_to_user(ptr, &tr, sizeof(tr))) {
if (t_from)
binder_thread_dec_tmpref(t_from);
+
+ binder_cleanup_transaction(t, "copy_to_user failed",
+ BR_FAILED_REPLY);
+
return -EFAULT;
}
ptr += sizeof(tr);
@@ -4220,15 +4288,9 @@ static void binder_release_work(struct binder_proc *proc,
struct binder_transaction *t;
t = container_of(w, struct binder_transaction, work);
- if (t->buffer->target_node &&
- !(t->flags & TF_ONE_WAY)) {
- binder_send_failed_reply(t, BR_DEAD_REPLY);
- } else {
- binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
- "undelivered transaction %d\n",
- t->debug_id);
- binder_free_transaction(t);
- }
+
+ binder_cleanup_transaction(t, "process died.",
+ BR_DEAD_REPLY);
} break;
case BINDER_WORK_RETURN_ERROR: {
struct binder_error *e = container_of(