diff options
author | Blagovest Kolenichev <bkolenichev@codeaurora.org> | 2017-10-19 16:55:17 -0700 |
---|---|---|
committer | Blagovest Kolenichev <bkolenichev@codeaurora.org> | 2017-10-20 02:11:57 -0700 |
commit | b2465235ad43e26e351e3b437a7f90f927cf11a4 (patch) | |
tree | 6339f0e9b8778e98d9664f8570403ad93d7313cb /drivers/android/binder.c | |
parent | 709d3a4e3edcb0963185f9481b178c9cfb9aab55 (diff) | |
parent | 73a2b70bdf78f3ad747dd740c9e55c062c71b86c (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.c | 142 |
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( |