aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel de Dios <migueldedios@google.com>2019-01-10 17:52:17 -0800
committerMiguel de Dios <migueldedios@google.com>2019-01-10 17:52:17 -0800
commit665c9a1d4de133b320772698066d8ec060a218f6 (patch)
tree80b15288d909c1081465a0e4266d224813c9e7a8
parent8cf5239d58fd34dd0a80f9549d01aa8187126ecc (diff)
parentc31e2d78b3f29bdf18b1044c1509ba55d5202e4f (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.c16
-rw-r--r--drivers/staging/android/binder.c127
-rw-r--r--drivers/staging/android/binder_alloc.c14
-rw-r--r--drivers/staging/android/binder_alloc.h3
-rw-r--r--drivers/staging/android/uapi/binder.h19
-rw-r--r--drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c26
-rw-r--r--drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c35
-rw-r--r--drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma_nan_datapath.c18
-rw-r--r--fs/ext4/ext4.h3
-rw-r--r--fs/ext4/inline.c38
-rw-r--r--fs/ext4/xattr.c18
-rw-r--r--fs/jbd2/transaction.c2
-rw-r--r--net/key/af_key.c42
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;
}