diff options
author | Miguel de Dios <migueldedios@google.com> | 2019-01-10 17:52:17 -0800 |
---|---|---|
committer | Miguel de Dios <migueldedios@google.com> | 2019-01-10 17:52:17 -0800 |
commit | 665c9a1d4de133b320772698066d8ec060a218f6 (patch) | |
tree | 80b15288d909c1081465a0e4266d224813c9e7a8 | |
parent | 8cf5239d58fd34dd0a80f9549d01aa8187126ecc (diff) | |
parent | c31e2d78b3f29bdf18b1044c1509ba55d5202e4f (diff) |
Merge branch 'android-msm-marlin-3.18-pi-qpr1' into android-msm-marlin-3.18-pi-qpr2android-9.0.0_r0.71android-9.0.0_r0.64
MAR 2019.1
Bug: 122351661
Change-Id: I626a3e70984a1e6066fa28a7dc3401488ccb9795
Signed-off-by: Miguel de Dios <migueldedios@google.com>
-rw-r--r-- | drivers/media/platform/msm/vidc/venus_hfi.c | 16 | ||||
-rw-r--r-- | drivers/staging/android/binder.c | 127 | ||||
-rw-r--r-- | drivers/staging/android/binder_alloc.c | 14 | ||||
-rw-r--r-- | drivers/staging/android/binder_alloc.h | 3 | ||||
-rw-r--r-- | drivers/staging/android/uapi/binder.h | 19 | ||||
-rw-r--r-- | drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c | 26 | ||||
-rw-r--r-- | drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c | 35 | ||||
-rw-r--r-- | drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma_nan_datapath.c | 18 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 3 | ||||
-rw-r--r-- | fs/ext4/inline.c | 38 | ||||
-rw-r--r-- | fs/ext4/xattr.c | 18 | ||||
-rw-r--r-- | fs/jbd2/transaction.c | 2 | ||||
-rw-r--r-- | net/key/af_key.c | 42 |
13 files changed, 222 insertions, 139 deletions
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index b0235d813e35..1854026e2b93 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -1553,7 +1553,7 @@ static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device, __strict_check(device); if (!__core_in_valid_state(device)) { - dprintk(VIDC_DBG, "%s - fw not in init state\n", __func__); + dprintk(VIDC_ERR, "%s - fw not in init state\n", __func__); result = -EINVAL; goto err_q_null; } @@ -3302,8 +3302,6 @@ static void __process_sys_error(struct venus_hfi_device *device) { struct hfi_sfr_struct *vsfr = NULL; - __set_state(device, VENUS_STATE_DEINIT); - /* Once SYS_ERROR received from HW, it is safe to halt the AXI. * With SYS_ERROR, Venus FW may have crashed and HW might be * active and causing unnecessary transactions. Hence it is @@ -3539,6 +3537,10 @@ static int __response_handler(struct venus_hfi_device *device) "Too many packets in message queue to handle at once, deferring read\n"); break; } + + /* do not read packets after sys error packet */ + if (info->response_type == HAL_SYS_ERROR) + break; } if (requeue_pm_work && device->res->sw_power_collapsible) { @@ -3601,7 +3603,13 @@ err_no_work: for (i = 0; !IS_ERR_OR_NULL(device->response_pkt) && i < num_responses; ++i) { struct msm_vidc_cb_info *r = &device->response_pkt[i]; - + if (!__core_in_valid_state(device)) { + dprintk(VIDC_ERR, + "Ignore responses from %d to %d as device is " + "in invalid state", + (i + 1), num_responses); + break; + } device->callback(r->response_type, &r->response); } diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 24a1366fcd3b..a663336d5642 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -357,6 +357,8 @@ struct binder_error { * (invariant after initialized) * @inherit_rt: inherit RT scheduling policy from caller * (invariant after initialized) + * @txn_security_ctx: require sender's security context + * (invariant after initialized) * @async_todo: list of async work items * (protected by @proc->inner_lock) * @@ -395,6 +397,7 @@ struct binder_node { u8 sched_policy:2; u8 inherit_rt:1; u8 accept_fds:1; + u8 txn_security_ctx:1; u8 min_priority; }; bool has_async_transaction; @@ -655,6 +658,7 @@ struct binder_transaction { struct binder_priority saved_priority; bool set_priority_called; kuid_t sender_euid; + binder_uintptr_t security_ctx; /** * @lock: protects @from, @to_proc, and @to_thread * @@ -1364,6 +1368,7 @@ static struct binder_node *binder_init_node_ilocked( node->min_priority = to_kernel_prio(node->sched_policy, priority); node->accept_fds = !!(flags & FLAT_BINDER_FLAG_ACCEPTS_FDS); node->inherit_rt = !!(flags & FLAT_BINDER_FLAG_INHERIT_RT); + node->txn_security_ctx = !!(flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX); spin_lock_init(&node->lock); INIT_LIST_HEAD(&node->work.entry); INIT_LIST_HEAD(&node->async_todo); @@ -2934,6 +2939,8 @@ static void binder_transaction(struct binder_proc *proc, binder_size_t last_fixup_min_off = 0; struct binder_context *context = proc->context; int t_debug_id = atomic_inc_return(&binder_last_id); + char *secctx = NULL; + u32 secctx_sz = 0; e = binder_transaction_log_add(&binder_transaction_log); e->debug_id = t_debug_id; @@ -3149,6 +3156,20 @@ static void binder_transaction(struct binder_proc *proc, t->priority = target_proc->default_priority; } + if (target_node && target_node->txn_security_ctx) { + u32 secid; + + security_task_getsecid(proc->tsk, &secid); + ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); + if (ret) { + return_error = BR_FAILED_REPLY; + return_error_param = ret; + return_error_line = __LINE__; + goto err_get_secctx_failed; + } + extra_buffers_size += ALIGN(secctx_sz, sizeof(u64)); + } + trace_binder_transaction(reply, t, target_node); t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size, @@ -3165,7 +3186,19 @@ static void binder_transaction(struct binder_proc *proc, t->buffer = NULL; goto err_binder_alloc_buf_failed; } - t->buffer->allow_user_free = 0; + if (secctx) { + size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) + + ALIGN(tr->offsets_size, sizeof(void *)) + + ALIGN(extra_buffers_size, sizeof(void *)) - + ALIGN(secctx_sz, sizeof(u64)); + char *kptr = t->buffer->data + buf_offset; + + t->security_ctx = (binder_uintptr_t)kptr + + binder_alloc_get_user_buffer_offset(&target_proc->alloc); + memcpy(kptr, secctx, secctx_sz); + security_release_secctx(secctx, secctx_sz); + secctx = NULL; + } t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; t->buffer->target_node = target_node; @@ -3429,6 +3462,9 @@ err_copy_data_failed: t->buffer->transaction = NULL; binder_alloc_free_buf(&target_proc->alloc, t->buffer); err_binder_alloc_buf_failed: + if (secctx) + security_release_secctx(secctx, secctx_sz); +err_get_secctx_failed: kfree(tcomplete); binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); err_alloc_tcomplete_failed: @@ -3654,14 +3690,18 @@ static int binder_thread_write(struct binder_proc *proc, buffer = binder_alloc_prepare_to_free(&proc->alloc, data_ptr); - if (buffer == NULL) { - binder_user_error("%d:%d BC_FREE_BUFFER u%016llx no match\n", - proc->pid, thread->pid, (u64)data_ptr); - break; - } - if (!buffer->allow_user_free) { - binder_user_error("%d:%d BC_FREE_BUFFER u%016llx matched unreturned buffer\n", - proc->pid, thread->pid, (u64)data_ptr); + if (IS_ERR_OR_NULL(buffer)) { + if (PTR_ERR(buffer) == -EPERM) { + binder_user_error( + "%d:%d BC_FREE_BUFFER u%016llx matched unreturned or currently freeing buffer\n", + proc->pid, thread->pid, + (u64)data_ptr); + } else { + binder_user_error( + "%d:%d BC_FREE_BUFFER u%016llx no match\n", + proc->pid, thread->pid, + (u64)data_ptr); + } break; } binder_debug(BINDER_DEBUG_FREE_BUFFER, @@ -4071,11 +4111,13 @@ retry: while (1) { uint32_t cmd; - struct binder_transaction_data tr; + struct binder_transaction_data_secctx tr; + struct binder_transaction_data *trd = &tr.transaction_data; struct binder_work *w = NULL; struct list_head *list = NULL; struct binder_transaction *t = NULL; struct binder_thread *t_from; + size_t trsize = sizeof(*trd); binder_inner_proc_lock(proc); if (!binder_worklist_empty_ilocked(&thread->todo)) @@ -4270,41 +4312,47 @@ retry: struct binder_node *target_node = t->buffer->target_node; struct binder_priority node_prio; - tr.target.ptr = target_node->ptr; - tr.cookie = target_node->cookie; + trd->target.ptr = target_node->ptr; + trd->cookie = target_node->cookie; node_prio.sched_policy = target_node->sched_policy; node_prio.prio = target_node->min_priority; binder_transaction_priority(current, t, node_prio, target_node->inherit_rt); cmd = BR_TRANSACTION; } else { - tr.target.ptr = 0; - tr.cookie = 0; + trd->target.ptr = 0; + trd->cookie = 0; cmd = BR_REPLY; } - tr.code = t->code; - tr.flags = t->flags; - tr.sender_euid = from_kuid(current_user_ns(), t->sender_euid); + trd->code = t->code; + trd->flags = t->flags; + trd->sender_euid = from_kuid(current_user_ns(), t->sender_euid); t_from = binder_get_txn_from(t); if (t_from) { struct task_struct *sender = t_from->proc->tsk; - tr.sender_pid = task_tgid_nr_ns(sender, - task_active_pid_ns(current)); + trd->sender_pid = + task_tgid_nr_ns(sender, + task_active_pid_ns(current)); } else { - tr.sender_pid = 0; + trd->sender_pid = 0; } - tr.data_size = t->buffer->data_size; - tr.offsets_size = t->buffer->offsets_size; - tr.data.ptr.buffer = (binder_uintptr_t) + trd->data_size = t->buffer->data_size; + trd->offsets_size = t->buffer->offsets_size; + trd->data.ptr.buffer = (binder_uintptr_t) ((uintptr_t)t->buffer->data + binder_alloc_get_user_buffer_offset(&proc->alloc)); - tr.data.ptr.offsets = tr.data.ptr.buffer + + trd->data.ptr.offsets = trd->data.ptr.buffer + ALIGN(t->buffer->data_size, sizeof(void *)); + if (t->security_ctx) { + cmd = BR_TRANSACTION_SEC_CTX; + tr.secctx = t->security_ctx; + trsize = sizeof(tr); + } if (put_user(cmd, (uint32_t __user *)ptr)) { if (t_from) binder_thread_dec_tmpref(t_from); @@ -4315,7 +4363,7 @@ retry: return -EFAULT; } ptr += sizeof(uint32_t); - if (copy_to_user(ptr, &tr, sizeof(tr))) { + if (copy_to_user(ptr, &tr, trsize)) { if (t_from) binder_thread_dec_tmpref(t_from); @@ -4324,7 +4372,7 @@ retry: return -EFAULT; } - ptr += sizeof(tr); + ptr += trsize; trace_binder_transaction_received(t); binder_stat_br(proc, thread, cmd); @@ -4332,16 +4380,18 @@ retry: "%d:%d %s %d %d:%d, cmd %d size %zd-%zd ptr %016llx-%016llx\n", proc->pid, thread->pid, (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" : - "BR_REPLY", + (cmd == BR_TRANSACTION_SEC_CTX) ? + "BR_TRANSACTION_SEC_CTX" : "BR_REPLY", t->debug_id, t_from ? t_from->proc->pid : 0, t_from ? t_from->pid : 0, cmd, t->buffer->data_size, t->buffer->offsets_size, - (u64)tr.data.ptr.buffer, (u64)tr.data.ptr.offsets); + (u64)trd->data.ptr.buffer, + (u64)trd->data.ptr.offsets); if (t_from) binder_thread_dec_tmpref(t_from); t->buffer->allow_user_free = 1; - if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) { + if (cmd != BR_REPLY && !(t->flags & TF_ONE_WAY)) { binder_inner_proc_lock(thread->proc); t->to_parent = thread->transaction_stack; t->to_thread = thread; @@ -4663,7 +4713,8 @@ out: return ret; } -static int binder_ioctl_set_ctx_mgr(struct file *filp) +static int binder_ioctl_set_ctx_mgr(struct file *filp, + struct flat_binder_object *fbo) { int ret = 0; struct binder_proc *proc = filp->private_data; @@ -4692,7 +4743,7 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp) } else { context->binder_context_mgr_uid = curr_euid; } - new_node = binder_new_node(proc, NULL); + new_node = binder_new_node(proc, fbo); if (!new_node) { ret = -ENOMEM; goto out; @@ -4778,8 +4829,20 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) binder_inner_proc_unlock(proc); break; } + case BINDER_SET_CONTEXT_MGR_EXT: { + struct flat_binder_object fbo; + + if (copy_from_user(&fbo, ubuf, sizeof(fbo))) { + ret = -EINVAL; + goto err; + } + ret = binder_ioctl_set_ctx_mgr(filp, &fbo); + if (ret) + goto err; + break; + } case BINDER_SET_CONTEXT_MGR: - ret = binder_ioctl_set_ctx_mgr(filp); + ret = binder_ioctl_set_ctx_mgr(filp, NULL); if (ret) goto err; break; diff --git a/drivers/staging/android/binder_alloc.c b/drivers/staging/android/binder_alloc.c index 3e58537156d8..d60ffb2dfe84 100644 --- a/drivers/staging/android/binder_alloc.c +++ b/drivers/staging/android/binder_alloc.c @@ -149,14 +149,12 @@ static struct binder_buffer *binder_alloc_prepare_to_free_locked( else { /* * Guard against user threads attempting to - * free the buffer twice + * free the buffer when in use by kernel or + * after it's already been freed. */ - if (buffer->free_in_progress) { - pr_err("%d:%d FREE_BUFFER u%016llx user freed buffer twice\n", - alloc->pid, current->pid, (u64)user_ptr); - return NULL; - } - buffer->free_in_progress = 1; + if (!buffer->allow_user_free) + return ERR_PTR(-EPERM); + buffer->allow_user_free = 0; return buffer; } } @@ -462,7 +460,7 @@ struct binder_buffer *binder_alloc_new_buf_locked(struct binder_alloc *alloc, rb_erase(best_fit, &alloc->free_buffers); buffer->free = 0; - buffer->free_in_progress = 0; + buffer->allow_user_free = 0; binder_insert_allocated_buffer_locked(alloc, buffer); binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%d: binder_alloc_buf size %zd got %pK\n", diff --git a/drivers/staging/android/binder_alloc.h b/drivers/staging/android/binder_alloc.h index 9dc8f32a53d6..8ce2cb246798 100644 --- a/drivers/staging/android/binder_alloc.h +++ b/drivers/staging/android/binder_alloc.h @@ -50,8 +50,7 @@ struct binder_buffer { unsigned free:1; unsigned allow_user_free:1; unsigned async_transaction:1; - unsigned free_in_progress:1; - unsigned debug_id:28; + unsigned debug_id:29; struct binder_transaction *transaction; diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h index 79524f832e80..82f8be72efa3 100644 --- a/drivers/staging/android/uapi/binder.h +++ b/drivers/staging/android/uapi/binder.h @@ -84,6 +84,14 @@ enum flat_binder_object_flags { * scheduling policy from the caller (for synchronous transactions). */ FLAT_BINDER_FLAG_INHERIT_RT = 0x800, + + /** + * @FLAT_BINDER_FLAG_TXN_SECURITY_CTX: request security contexts + * + * Only when set, causes senders to include their security + * context + */ + FLAT_BINDER_FLAG_TXN_SECURITY_CTX = 0x1000, }; #ifdef BINDER_IPC_32BIT @@ -249,6 +257,7 @@ struct binder_node_debug_info { #define BINDER_THREAD_EXIT _IOW('b', 8, __s32) #define BINDER_VERSION _IOWR('b', 9, struct binder_version) #define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info) +#define BINDER_SET_CONTEXT_MGR_EXT _IOW('b', 13, struct flat_binder_object) /* * NOTE: Two special error codes you should check for when calling @@ -307,6 +316,11 @@ struct binder_transaction_data { } data; }; +struct binder_transaction_data_secctx { + struct binder_transaction_data transaction_data; + binder_uintptr_t secctx; +}; + struct binder_transaction_data_sg { struct binder_transaction_data transaction_data; binder_size_t buffers_size; @@ -342,6 +356,11 @@ enum binder_driver_return_protocol { BR_OK = _IO('r', 1), /* No parameters! */ + BR_TRANSACTION_SEC_CTX = _IOR('r', 2, + struct binder_transaction_data_secctx), + /* + * binder_transaction_data_secctx: the received command. + */ BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data), BR_REPLY = _IOR('r', 3, struct binder_transaction_data), /* diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c index 7134864d1c9f..2a523f8446b7 100644 --- a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -552,8 +552,16 @@ ol_tx_completion_handler( trace_str = (status) ? "OT:C:F:" : "OT:C:S:"; for (i = 0; i < num_msdus; i++) { tx_desc_id = desc_ids[i]; - tx_desc = td_array[tx_desc_id].tx_desc; - tx_desc->status = status; + if (tx_desc_id >= pdev->tx_desc.pool_size) { + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, + "%s: drop due to invalid msdu id = %x\n", + __func__, tx_desc_id); + continue; + } + + tx_desc = td_array[tx_desc_id].tx_desc; + adf_os_assert(tx_desc); + tx_desc->status = status; netbuf = tx_desc->netbuf; NBUF_UPDATE_TX_PKT_COUNT(netbuf, NBUF_TX_PKT_FREE); DPTRACE(adf_dp_trace_ptr(netbuf, @@ -816,8 +824,16 @@ ol_tx_inspect_handler( for (i = 0; i < num_msdus; i++) { tx_desc_id = desc_ids[i]; - tx_desc = td_array[tx_desc_id].tx_desc; - netbuf = tx_desc->netbuf; + if (tx_desc_id >= pdev->tx_desc.pool_size) { + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, + "%s: drop due to invalid msdu id = %x\n", + __func__, tx_desc_id); + continue; + } + + tx_desc = td_array[tx_desc_id].tx_desc; + adf_os_assert(tx_desc); + netbuf = tx_desc->netbuf; /* find the "vdev" this tx_desc belongs to */ vdev_id = HTT_TX_DESC_VDEV_ID_GET(*((u_int32_t *)(tx_desc->htt_tx_desc))); diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c index f85a3bf3fc89..0af42c24e8f4 100644 --- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c @@ -2616,6 +2616,11 @@ static void wma_vdev_stats_lost_link_helper(tp_wma_handle wma, uint8_t zero_mac[ETH_ALEN] = {0}; int8_t bcn_snr, dat_snr; + if (vdev_stats->vdev_id >= wma->max_bssid) { + WMA_LOGE("%s: Invalid vdev_id %hu", + __func__, vdev_stats->vdev_id); + return; + } node = &wma->interfaces[vdev_stats->vdev_id]; if (node->vdev_up && vos_mem_compare(node->bssid, zero_mac, ETH_ALEN)) { @@ -2660,6 +2665,11 @@ static void wma_update_vdev_stats(tp_wma_handle wma, vos_msg_t sme_msg = {0}; int8_t bcn_snr, dat_snr; + if (vdev_stats->vdev_id >= wma->max_bssid) { + WMA_LOGE("%s: Invalid vdev_id %hu", + __func__, vdev_stats->vdev_id); + return; + } node = &wma->interfaces[vdev_stats->vdev_id]; stats_rsp_params = node->stats_rsp; if (stats_rsp_params) { @@ -2925,6 +2935,11 @@ static void wma_update_rssi_stats(tp_wma_handle wma, uint32_t temp_mask; uint8_t vdev_id; + if (rssi_stats->vdev_id >= wma->max_bssid) { + WMA_LOGE("%s: Invalid vdev_id %hu", + __func__, rssi_stats->vdev_id); + return; + } vdev_id = rssi_stats->vdev_id; node = &wma->interfaces[vdev_id]; if (node->stats_rsp) { @@ -4421,12 +4436,12 @@ static int wma_extscan_change_results_event_handler(void *handle, tSirWifiSignificantChange *dest_ap; wmi_extscan_wlan_change_result_bssid *src_chglist; - int numap; + uint32_t numap; int i, k; u_int8_t *src_rssi; int count = 0; int moredata; - int rssi_num = 0; + uint32_t rssi_num = 0; u_int32_t buf_len; bool excess_data = false; tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context( @@ -4455,8 +4470,18 @@ static int wma_extscan_change_results_event_handler(void *handle, return -EINVAL; } for (i = 0; i < numap; i++) { + if (src_chglist->num_rssi_samples > (UINT_MAX - rssi_num)) { + WMA_LOGE("%s: Invalid num of rssi samples %d numap %d " + "rssi_num %d", + __func__, src_chglist->num_rssi_samples, + numap, rssi_num); + return -EINVAL; + } rssi_num += src_chglist->num_rssi_samples; + src_chglist++; } + src_chglist = param_buf->bssid_signal_descriptor_list; + if (event->first_entry_index + event->num_entries_in_page < event->total_entries) moredata = 1; @@ -4808,7 +4833,7 @@ static int wma_unified_link_peer_stats_event_handler(void *handle, size_t peer_info_size, peer_stats_size, rate_stats_size; size_t link_stats_results_size; bool excess_data = false; - u_int32_t buf_len; + u_int32_t buf_len = 0; tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, wma_handle->vos_context); @@ -4877,7 +4902,7 @@ static int wma_unified_link_peer_stats_event_handler(void *handle, } while (0); if (excess_data || - (sizeof(*fixed_param) > WMA_SVC_MSG_MAX_SIZE - buf_len)) { + (buf_len > WMA_SVC_MSG_MAX_SIZE - sizeof(*fixed_param))) { WMA_LOGE("excess wmi buffer: rates:%d, peers:%d", peer_stats->num_rates, fixed_param->num_peers); VOS_ASSERT(0); @@ -7241,7 +7266,7 @@ static int wma_stats_ext_event_handler(void *handle, u_int8_t *event_buf, alloc_len += stats_ext_info->data_len; if (stats_ext_info->data_len > (WMA_SVC_MSG_MAX_SIZE - - sizeof(*stats_ext_info))) { + WMI_TLV_HDR_SIZE - sizeof(*stats_ext_info))) { WMA_LOGE("Excess data_len:%d", stats_ext_info->data_len); VOS_ASSERT(0); return -EINVAL; diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma_nan_datapath.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma_nan_datapath.c index bf0b57baaafa..1f60c4cf88eb 100644 --- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma_nan_datapath.c +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma_nan_datapath.c @@ -482,11 +482,29 @@ static int wma_ndp_indication_event_handler(void *handle, uint8_t *event_info, vos_msg_t pe_msg = {0}; struct ndp_indication_event *ind_event; VOS_STATUS status; + size_t total_array_len = 0; event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)event_info; fixed_params = (wmi_ndp_indication_event_fixed_param *)event->fixed_param; + if (fixed_params->ndp_cfg_len > + (WMA_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) { + WMA_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", + __func__, fixed_params->ndp_cfg_len); + return -EINVAL; + } else { + total_array_len = fixed_params->ndp_cfg_len + + sizeof(*fixed_params); + } + + if (fixed_params->ndp_app_info_len > + (WMA_SVC_MSG_MAX_SIZE - total_array_len)) { + WMA_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", + __func__, fixed_params->ndp_app_info_len); + return -EINVAL; + } + ind_event = vos_mem_malloc(sizeof(*ind_event)); if (!ind_event) { WMA_LOGP(FL("Failed to allocate memory")); diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 7f908b4fce3a..6996b0846863 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2854,9 +2854,6 @@ extern struct buffer_head *ext4_get_first_inline_block(struct inode *inode, extern int ext4_inline_data_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, int *has_inline); -extern int ext4_try_to_evict_inline_data(handle_t *handle, - struct inode *inode, - int needed); extern void ext4_inline_data_truncate(struct inode *inode, int *has_inline); extern int ext4_convert_inline_data(struct inode *inode); diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 1906720f2953..dd17031515b1 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -875,11 +875,11 @@ retry_journal: } if (ret == -ENOSPC) { + ext4_journal_stop(handle); ret = ext4_da_convert_inline_data_to_extent(mapping, inode, flags, fsdata); - ext4_journal_stop(handle); if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) goto retry_journal; @@ -1843,42 +1843,6 @@ out: return (error < 0 ? error : 0); } -/* - * Called during xattr set, and if we can sparse space 'needed', - * just create the extent tree evict the data to the outer block. - * - * We use jbd2 instead of page cache to move data to the 1st block - * so that the whole transaction can be committed as a whole and - * the data isn't lost because of the delayed page cache write. - */ -int ext4_try_to_evict_inline_data(handle_t *handle, - struct inode *inode, - int needed) -{ - int error; - struct ext4_xattr_entry *entry; - struct ext4_inode *raw_inode; - struct ext4_iloc iloc; - - error = ext4_get_inode_loc(inode, &iloc); - if (error) - return error; - - raw_inode = ext4_raw_inode(&iloc); - entry = (struct ext4_xattr_entry *)((void *)raw_inode + - EXT4_I(inode)->i_inline_off); - if (EXT4_XATTR_LEN(entry->e_name_len) + - EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size)) < needed) { - error = -ENOSPC; - goto out; - } - - error = ext4_convert_inline_data_nolock(handle, inode, &iloc); -out: - brelse(iloc.bh); - return error; -} - void ext4_inline_data_truncate(struct inode *inode, int *has_inline) { handle_t *handle; diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 9832960c584e..662fdc18d785 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -1045,22 +1045,8 @@ int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode, if (EXT4_I(inode)->i_extra_isize == 0) return -ENOSPC; error = ext4_xattr_set_entry(i, s, inode); - if (error) { - if (error == -ENOSPC && - ext4_has_inline_data(inode)) { - error = ext4_try_to_evict_inline_data(handle, inode, - EXT4_XATTR_LEN(strlen(i->name) + - EXT4_XATTR_SIZE(i->value_len))); - if (error) - return error; - error = ext4_xattr_ibody_find(inode, i, is); - if (error) - return error; - error = ext4_xattr_set_entry(i, s, inode); - } - if (error) - return error; - } + if (error) + return error; header = IHDR(inode, ext4_raw_inode(&is->iloc)); if (!IS_LAST_ENTRY(s->first)) { header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC); diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index f3818e7cfa60..ab034f48ffe4 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -1283,11 +1283,11 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) * of the transaction. This needs to be done * once a transaction -bzzz */ - jh->b_modified = 1; if (handle->h_buffer_credits <= 0) { ret = -ENOSPC; goto out_unlock_bh; } + jh->b_modified = 1; handle->h_buffer_credits--; } diff --git a/net/key/af_key.c b/net/key/af_key.c index fbd25f58d18e..d30d6f922f10 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -196,30 +196,22 @@ static int pfkey_release(struct socket *sock) return 0; } -static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2, - gfp_t allocation, struct sock *sk) +static int pfkey_broadcast_one(struct sk_buff *skb, gfp_t allocation, + struct sock *sk) { int err = -ENOBUFS; - sock_hold(sk); - if (*skb2 == NULL) { - if (atomic_read(&skb->users) != 1) { - *skb2 = skb_clone(skb, allocation); - } else { - *skb2 = skb; - atomic_inc(&skb->users); - } - } - if (*skb2 != NULL) { - if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) { - skb_set_owner_r(*skb2, sk); - skb_queue_tail(&sk->sk_receive_queue, *skb2); - sk->sk_data_ready(sk); - *skb2 = NULL; - err = 0; - } + if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf) + return err; + + skb = skb_clone(skb, allocation); + + if (skb) { + skb_set_owner_r(skb, sk); + skb_queue_tail(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk); + err = 0; } - sock_put(sk); return err; } @@ -234,7 +226,6 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, { struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); struct sock *sk; - struct sk_buff *skb2 = NULL; int err = -ESRCH; /* XXX Do we need something like netlink_overrun? I think @@ -253,7 +244,7 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, * socket. */ if (pfk->promisc) - pfkey_broadcast_one(skb, &skb2, allocation, sk); + pfkey_broadcast_one(skb, GFP_ATOMIC, sk); /* the exact target will be processed later */ if (sk == one_sk) @@ -268,9 +259,9 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, continue; } - err2 = pfkey_broadcast_one(skb, &skb2, allocation, sk); + err2 = pfkey_broadcast_one(skb, GFP_ATOMIC, sk); - /* Error is cleare after succecful sending to at least one + /* Error is cleared after successful sending to at least one * registered KM */ if ((broadcast_flags & BROADCAST_REGISTERED) && err) err = err2; @@ -278,9 +269,8 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, rcu_read_unlock(); if (one_sk != NULL) - err = pfkey_broadcast_one(skb, &skb2, allocation, one_sk); + err = pfkey_broadcast_one(skb, allocation, one_sk); - kfree_skb(skb2); kfree_skb(skb); return err; } |