aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2019-05-29 21:55:06 -0700
committerLinux Build Service Account <lnxbuild@localhost>2019-05-29 21:55:06 -0700
commit28d24113e637879e72abbec172029ab54f41c4c0 (patch)
tree70276e31b4c2a1a4aad2a91d59df6427b2112ae9
parent537b5837eecb836c45a18b2245bc2620a5aec7e1 (diff)
parentb531cbcf5a76b348d3192eb52b74dcd9e84dc180 (diff)
Merge b531cbcf5a76b348d3192eb52b74dcd9e84dc180 on remote branchLA.UM.6.6.2.r1-07300-89xx.0
Change-Id: I074fbe13c5ec73ce94e5e87c435706144a26e525
-rw-r--r--drivers/android/binder.c127
-rw-r--r--drivers/android/binder_alloc.c14
-rw-r--r--drivers/android/binder_alloc.h3
-rw-r--r--drivers/char/diag/diag_dci.c22
-rw-r--r--drivers/char/diag/diagchar_core.c19
-rw-r--r--drivers/gpu/msm/kgsl.c4
-rw-r--r--drivers/iommu/dma-mapping-fast.c14
-rw-r--r--drivers/media/platform/msm/camera_v2/camera/camera.c33
-rw-r--r--drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c9
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c20
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_clocks.c4
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.c10
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c3
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_nat.c3
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c35
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c9
-rw-r--r--drivers/soc/qcom/glink_smem_native_xprt.c12
-rw-r--r--drivers/soc/qcom/icnss.c17
-rw-r--r--drivers/staging/android/ion/ion_cma_secure_heap.c10
-rw-r--r--drivers/thermal/qpnp-adc-tm.c4
-rw-r--r--fs/ext4/ext4.h3
-rw-r--r--fs/ext4/inline.c38
-rw-r--r--fs/ext4/xattr.c44
-rw-r--r--fs/jbd2/transaction.c9
-rw-r--r--include/uapi/linux/android/binder.h19
25 files changed, 324 insertions, 161 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 1ef2f68bfcb2..ae74e425e0cb 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -360,6 +360,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)
*
@@ -398,6 +400,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;
@@ -652,6 +655,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
*
@@ -1368,6 +1372,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);
@@ -2900,6 +2905,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;
@@ -3115,6 +3122,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,
@@ -3131,7 +3152,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;
@@ -3402,6 +3435,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:
@@ -3627,14 +3663,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,
@@ -4044,11 +4084,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))
@@ -4243,41 +4285,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);
@@ -4288,7 +4336,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);
@@ -4297,7 +4345,7 @@ retry:
return -EFAULT;
}
- ptr += sizeof(tr);
+ ptr += trsize;
trace_binder_transaction_received(t);
binder_stat_br(proc, thread, cmd);
@@ -4305,16 +4353,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;
@@ -4636,7 +4686,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;
@@ -4665,7 +4716,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;
@@ -4751,8 +4802,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/android/binder_alloc.c b/drivers/android/binder_alloc.c
index 6b91ff6758b4..02c3118b110c 100644
--- a/drivers/android/binder_alloc.c
+++ b/drivers/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;
}
}
@@ -458,7 +456,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/android/binder_alloc.h b/drivers/android/binder_alloc.h
index 2dd33b6df104..a3ad7683b6f2 100644
--- a/drivers/android/binder_alloc.h
+++ b/drivers/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/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 286418f9436a..7f2fdd259f6d 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -986,7 +986,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
int save_req_uid = 0;
struct diag_dci_pkt_rsp_header_t pkt_rsp_header;
- if (!buf) {
+ if (!buf || len <= 0) {
pr_err("diag: Invalid pointer in %s\n", __func__);
return;
}
@@ -1000,6 +1000,8 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
dci_cmd_code);
return;
}
+ if (len < (cmd_code_len + sizeof(int)))
+ return;
temp += cmd_code_len;
tag = *(int *)temp;
temp += sizeof(int);
@@ -1008,10 +1010,16 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
* The size of the response is (total length) - (length of the command
* code, the tag (int)
*/
- rsp_len = len - (cmd_code_len + sizeof(int));
- if ((rsp_len == 0) || (rsp_len > (len - 5))) {
- pr_err("diag: Invalid length in %s, len: %d, rsp_len: %d",
- __func__, len, rsp_len);
+ if (len >= cmd_code_len + sizeof(int)) {
+ rsp_len = len - (cmd_code_len + sizeof(int));
+ if ((rsp_len == 0) || (rsp_len > (len - 5))) {
+ pr_err("diag: Invalid length in %s, len: %d, rsp_len: %d\n",
+ __func__, len, rsp_len);
+ return;
+ }
+ } else {
+ pr_err("diag:%s: Invalid length(%d) for calculating rsp_len\n",
+ __func__, len);
return;
}
@@ -2303,8 +2311,8 @@ struct diag_dci_client_tbl *dci_lookup_client_entry_pid(int tgid)
pid_struct = find_get_pid(entry->tgid);
if (!pid_struct) {
DIAG_LOG(DIAG_DEBUG_DCI,
- "diag: valid pid doesn't exist for pid = %d\n",
- entry->tgid);
+ "diag: Exited pid (%d) doesn't match dci client of pid (%d)\n",
+ tgid, entry->tgid);
continue;
}
task_s = get_pid_task(pid_struct, PIDTYPE_PID);
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 17730976c1d2..606e864b5d89 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -556,8 +556,8 @@ static int diagchar_close(struct inode *inode, struct file *file)
{
int ret;
- DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: process exit %s\n",
- current->comm);
+ DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: %s process exit with pid = %d\n",
+ current->comm, current->tgid);
ret = diag_remove_client_entry(file);
mutex_lock(&driver->diag_maskclear_mutex);
driver->mask_clear = 0;
@@ -3218,6 +3218,8 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
int exit_stat = 0;
int write_len = 0;
struct diag_md_session_t *session_info = NULL;
+ struct pid *pid_struct = NULL;
+ struct task_struct *task_s = NULL;
mutex_lock(&driver->diagchar_mutex);
for (i = 0; i < driver->num_clients; i++)
@@ -3462,8 +3464,19 @@ exit:
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl,
track);
- if (entry->client->tgid != current->tgid)
+ pid_struct = find_get_pid(entry->tgid);
+ if (!pid_struct)
continue;
+ task_s = get_pid_task(pid_struct, PIDTYPE_PID);
+ if (!task_s) {
+ DIAG_LOG(DIAG_DEBUG_DCI,
+ "diag: valid task doesn't exist for pid = %d\n",
+ entry->tgid);
+ continue;
+ }
+ if (task_s == entry->client)
+ if (entry->client->tgid != current->tgid)
+ continue;
if (!entry->in_service)
continue;
if (copy_to_user(buf + ret, &data_type, sizeof(int))) {
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 2f975098d93c..cdcf2c3f9f99 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -327,7 +327,7 @@ kgsl_mem_entry_destroy(struct kref *kref)
entry->memdesc.sgt->nents, i) {
page = sg_page(sg);
for (j = 0; j < (sg->length >> PAGE_SHIFT); j++)
- set_page_dirty(nth_page(page, j));
+ set_page_dirty_lock(nth_page(page, j));
}
}
diff --git a/drivers/iommu/dma-mapping-fast.c b/drivers/iommu/dma-mapping-fast.c
index eac7b410a688..7871370e44f1 100644
--- a/drivers/iommu/dma-mapping-fast.c
+++ b/drivers/iommu/dma-mapping-fast.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -542,12 +542,22 @@ static void *fast_smmu_alloc(struct device *dev, size_t size,
av8l_fast_iopte *ptep;
unsigned long flags;
struct sg_mapping_iter miter;
- unsigned int count = ALIGN(size, SZ_4K) >> PAGE_SHIFT;
+ size_t count = ALIGN(size, SZ_4K) >> PAGE_SHIFT;
int prot = IOMMU_READ | IOMMU_WRITE; /* TODO: extract from attrs */
bool is_coherent = is_dma_coherent(dev, attrs);
pgprot_t remap_prot = __get_dma_pgprot(attrs, PAGE_KERNEL, is_coherent);
struct page **pages;
+ /*
+ * sg_alloc_table_from_pages accepts unsigned int value for count
+ * so check count doesn't exceed UINT_MAX.
+ */
+
+ if (count > UINT_MAX) {
+ dev_err(dev, "count: %zx exceeds UNIT_MAX\n", count);
+ return NULL;
+ }
+
prot = __get_iommu_pgprot(attrs, prot, is_coherent);
*handle = DMA_ERROR_CODE;
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c
index 01ee5d45b024..cd1c7f10b4ec 100644
--- a/drivers/media/platform/msm/camera_v2/camera/camera.c
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.c
@@ -369,9 +369,12 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh,
if (pfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- if (WARN_ON(!sp->vb2_q.drv_priv))
- return -ENOMEM;
-
+ mutex_lock(sp->vb2_q.lock);
+ if (WARN_ON(!sp->vb2_q.drv_priv)) {
+ rc = -ENOMEM;
+ mutex_unlock(sp->vb2_q.lock);
+ goto done;
+ }
memcpy(sp->vb2_q.drv_priv, pfmt->fmt.raw_data,
sizeof(struct msm_v4l2_format_data));
user_fmt = (struct msm_v4l2_format_data *)sp->vb2_q.drv_priv;
@@ -381,27 +384,29 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh,
/* num_planes need to bound checked, otherwise for loop
* can execute forever
*/
- if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES))
- return -EINVAL;
+ if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES)) {
+ rc = -EINVAL;
+ mutex_unlock(sp->vb2_q.lock);
+ goto done;
+ }
for (i = 0; i < user_fmt->num_planes; i++)
pr_debug("%s: plane size[%d]\n", __func__,
user_fmt->plane_sizes[i]);
-
+ mutex_unlock(sp->vb2_q.lock);
if (msm_is_daemon_present() != false) {
camera_pack_event(filep, MSM_CAMERA_SET_PARM,
MSM_CAMERA_PRIV_S_FMT, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
- return rc;
-
+ goto done;
rc = camera_check_event_status(&event);
if (rc < 0)
- return rc;
+ goto done;
}
sp->is_vb2_valid = 1;
}
-
+done:
return rc;
}
@@ -600,6 +605,12 @@ static int camera_v4l2_vb2_q_init(struct file *filep)
pr_err("%s : memory not available\n", __func__);
return -ENOMEM;
}
+ q->lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
+ if (!q->lock) {
+ kzfree(q->drv_priv);
+ return -ENOMEM;
+ }
+ mutex_init(q->lock);
q->mem_ops = msm_vb2_get_q_mem_ops();
q->ops = msm_vb2_get_q_ops();
@@ -619,6 +630,8 @@ static void camera_v4l2_vb2_q_release(struct file *filep)
kzfree(sp->vb2_q.drv_priv);
mutex_lock(&sp->lock);
vb2_queue_release(&sp->vb2_q);
+ mutex_destroy(sp->vb2_q.lock);
+ kzfree(sp->vb2_q.lock);
mutex_unlock(&sp->lock);
}
diff --git a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
index 9a21282531f9..f1ed1c90085a 100644
--- a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
+++ b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
@@ -1,5 +1,4 @@
-/* Copyright (c) 2011-2014, 2017-2018, The Linux Foundation.
- * All rights reserved.
+/* Copyright (c) 2011-2014, 2017-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -367,12 +366,13 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
}
} else {
for (i = num_clk - 1; i >= 0; i--) {
- if (clk_ptr[i] != NULL) {
+ if (!IS_ERR_OR_NULL(clk_ptr[i])) {
CDBG("%s disable %s\n", __func__,
clk_info[i].clk_name);
clk_disable(clk_ptr[i]);
clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
+ clk_ptr[i] = NULL;
}
}
}
@@ -386,10 +386,11 @@ cam_clk_set_err:
clk_put(clk_ptr[i]);
cam_clk_get_err:
for (i--; i >= 0; i--) {
- if (clk_ptr[i] != NULL) {
+ if (!IS_ERR_OR_NULL(clk_ptr[i])) {
clk_disable(clk_ptr[i]);
clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
+ clk_ptr[i] = NULL;
}
}
return rc;
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index 6e528a65ecc3..b29a6f65ee41 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -19,15 +19,19 @@ static int msm_vb2_queue_setup(struct vb2_queue *q,
unsigned int sizes[], struct device *alloc_ctxs[])
{
int i;
- struct msm_v4l2_format_data *data = q->drv_priv;
+ struct msm_v4l2_format_data *data = NULL;
+ int rc = -EINVAL;
+
+ mutex_lock(q->lock);
+ data = q->drv_priv;
if (!data) {
pr_err("%s: drv_priv NULL\n", __func__);
- return -EINVAL;
+ goto done;
}
if (data->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
if (WARN_ON(data->num_planes > VIDEO_MAX_PLANES))
- return -EINVAL;
+ goto done;
*num_planes = data->num_planes;
@@ -36,9 +40,13 @@ static int msm_vb2_queue_setup(struct vb2_queue *q,
} else {
pr_err("%s: Unsupported buf type :%d\n", __func__,
data->type);
- return -EINVAL;
+ goto done;
}
- return 0;
+ rc = 0;
+
+done:
+ mutex_unlock(q->lock);
+ return rc;
}
static int msm_vb2_buf_init(struct vb2_buffer *vb)
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index 003e56ce5a1f..cd66d42ccc73 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -906,7 +906,7 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst)
dprintk(VIDC_DBG, "Init DCVS Load\n");
- if (!inst || !inst->core) {
+ if (!inst || !inst->core || !inst->clk_data.entry) {
dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n",
__func__, inst);
return;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 4110629944b3..c181124479ca 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -5101,6 +5101,14 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
"Invalid params, inst %pK\n", inst);
return -EINVAL;
}
+
+ if (inst->state < MSM_VIDC_OPEN_DONE) {
+ dprintk(VIDC_ERR,
+ "Invalid state to call flush, inst %pK, state %#x\n",
+ inst, inst->state);
+ return -EINVAL;
+ }
+
core = inst->core;
hdev = core->device;
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 8cedef0daae4..b0aea48907b7 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -2016,6 +2016,8 @@ static int em28xx_dvb_fini(struct em28xx *dev)
}
}
+ em28xx_unregister_dvb(dvb);
+
/* remove I2C SEC */
client = dvb->i2c_client_sec;
if (client) {
@@ -2037,7 +2039,6 @@ static int em28xx_dvb_fini(struct em28xx *dev)
i2c_unregister_device(client);
}
- em28xx_unregister_dvb(dvb);
kfree(dvb);
dev->dvb = NULL;
kref_put(&dev->ref, em28xx_free_device);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
index 7fd8e50009f0..c3229ebec0d9 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1523,7 +1523,6 @@ int ipa3_del_nat_table(struct ipa_ioc_nat_ipv6ct_table_del *del)
ipa3_ctx->nat_mem.pdn_mem.base,
ipa3_ctx->nat_mem.pdn_mem.phys_base);
ipa3_ctx->nat_mem.pdn_mem.base = NULL;
- ipa3_ctx->nat_mem.dev.is_mem_allocated = false;
}
ipa3_nat_ipv6ct_free_mem(&ipa3_ctx->nat_mem.dev);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
index 88de06eaef59..42539cb2ccf2 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -764,7 +764,7 @@ int ipa3_qmi_ul_filter_request_send(
{
struct ipa_configure_ul_firewall_rules_resp_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
- int rc;
+ int rc, i;
IPAWANDBG("IPACM pass %u rules to Q6\n",
req->firewall_rules_list_len);
@@ -784,6 +784,37 @@ int ipa3_qmi_ul_filter_request_send(
}
mutex_unlock(&ipa3_qmi_lock);
+ /* check if modem is up */
+ if (!ipa3_qmi_indication_fin ||
+ !ipa3_qmi_modem_init_fin ||
+ !ipa_q6_clnt) {
+ IPAWANDBG("modem QMI service is not up yet\n");
+ return -EINVAL;
+ }
+
+ /* Passing 0 rules means that firewall is disabled */
+ if (req->firewall_rules_list_len == 0)
+ IPAWANDBG("IPACM passed 0 rules to Q6\n");
+
+ if (req->firewall_rules_list_len >= QMI_IPA_MAX_UL_FIREWALL_RULES_V01) {
+ IPAWANERR(
+ "Number of rules passed by IPACM, %d, exceed limit %d\n",
+ req->firewall_rules_list_len,
+ QMI_IPA_MAX_UL_FIREWALL_RULES_V01);
+ return -EINVAL;
+ }
+
+ /* Check for valid IP type */
+ for (i = 0; i < req->firewall_rules_list_len; i++) {
+ if (req->firewall_rules_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V4_V01 &&
+ req->firewall_rules_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V6_V01)
+ IPAWANERR("Invalid IP type %d\n",
+ req->firewall_rules_list[i].ip_type);
+ return -EINVAL;
+ }
+
req_desc.max_msg_len =
QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_MAX_MSG_LEN_V01;
req_desc.msg_id = QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_V01;
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index 833520c70c2b..cabebc1e1478 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -3762,6 +3762,15 @@ int rmnet_ipa3_send_lan_client_msg(
IPAWANERR("Can't allocate memory for tether_info\n");
return -ENOMEM;
}
+
+ if (data->client_event != IPA_PER_CLIENT_STATS_CONNECT_EVENT &&
+ data->client_event != IPA_PER_CLIENT_STATS_DISCONNECT_EVENT) {
+ IPAWANERR("Wrong event given. Event:- %d\n",
+ data->client_event);
+ kfree(lan_client);
+ return -EINVAL;
+ }
+ data->lan_client.lanIface[IPA_RESOURCE_NAME_MAX-1] = '\0';
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
memcpy(lan_client, &data->lan_client,
sizeof(struct ipa_lan_client_msg));
diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c
index d8e5d9fb38a5..6fd314f133bc 100644
--- a/drivers/soc/qcom/glink_smem_native_xprt.c
+++ b/drivers/soc/qcom/glink_smem_native_xprt.c
@@ -459,8 +459,10 @@ static int fifo_read(struct edge_info *einfo, void *_data, int len)
uint32_t fifo_size = einfo->rx_fifo_size;
uint32_t n;
- if (read_index >= fifo_size || write_index >= fifo_size)
- return 0;
+ if (read_index >= fifo_size || write_index >= fifo_size) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
while (len) {
ptr = einfo->rx_fifo + read_index;
if (read_index <= write_index)
@@ -507,8 +509,10 @@ static int fifo_write_body(struct edge_info *einfo, const void *_data,
uint32_t fifo_size = einfo->tx_fifo_size;
uint32_t n;
- if (read_index >= fifo_size || *write_index >= fifo_size)
- return 0;
+ if (read_index >= fifo_size || *write_index >= fifo_size) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
while (len) {
ptr = einfo->tx_fifo + *write_index;
if (*write_index < read_index) {
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index db019dc5ac20..32e52ca5d278 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -1279,6 +1279,7 @@ static int wlfw_msa_mem_info_send_sync_msg(void)
struct wlfw_msa_info_req_msg_v01 req;
struct wlfw_msa_info_resp_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
+ uint64_t max_mapped_addr;
if (!penv || !penv->wlfw_clnt)
return -ENODEV;
@@ -1325,9 +1326,23 @@ static int wlfw_msa_mem_info_send_sync_msg(void)
goto out;
}
+ max_mapped_addr = penv->msa_pa + penv->msa_mem_size;
penv->stats.msa_info_resp++;
penv->nr_mem_region = resp.mem_region_info_len;
for (i = 0; i < resp.mem_region_info_len; i++) {
+
+ if (resp.mem_region_info[i].size > penv->msa_mem_size ||
+ resp.mem_region_info[i].region_addr > max_mapped_addr ||
+ resp.mem_region_info[i].region_addr < penv->msa_pa ||
+ resp.mem_region_info[i].size +
+ resp.mem_region_info[i].region_addr > max_mapped_addr) {
+ icnss_pr_dbg("Received out of range Addr: 0x%llx Size: 0x%x\n",
+ resp.mem_region_info[i].region_addr,
+ resp.mem_region_info[i].size);
+ ret = -EINVAL;
+ goto fail_unwind;
+ }
+
penv->mem_region[i].reg_addr =
resp.mem_region_info[i].region_addr;
penv->mem_region[i].size =
@@ -1342,6 +1357,8 @@ static int wlfw_msa_mem_info_send_sync_msg(void)
return 0;
+fail_unwind:
+ memset(&penv->mem_region[0], 0, sizeof(penv->mem_region[0]) * i);
out:
penv->stats.msa_info_err++;
ICNSS_QMI_ASSERT();
diff --git a/drivers/staging/android/ion/ion_cma_secure_heap.c b/drivers/staging/android/ion/ion_cma_secure_heap.c
index b2eac281e805..0dd5aefad82f 100644
--- a/drivers/staging/android/ion/ion_cma_secure_heap.c
+++ b/drivers/staging/android/ion/ion_cma_secure_heap.c
@@ -346,8 +346,8 @@ static void ion_secure_cma_free_chunk(struct ion_cma_secure_heap *sheap,
kfree(chunk);
}
-static void __ion_secure_cma_shrink_pool(struct ion_cma_secure_heap *sheap,
- int max_nr)
+static unsigned long
+__ion_secure_cma_shrink_pool(struct ion_cma_secure_heap *sheap, int max_nr)
{
struct list_head *entry, *_n;
unsigned long drained_size = 0, skipped_size = 0;
@@ -371,6 +371,7 @@ static void __ion_secure_cma_shrink_pool(struct ion_cma_secure_heap *sheap,
}
trace_ion_secure_cma_shrink_pool_end(drained_size, skipped_size);
+ return drained_size;
}
int ion_secure_cma_drain_pool(struct ion_heap *heap, void *unused)
@@ -388,6 +389,7 @@ int ion_secure_cma_drain_pool(struct ion_heap *heap, void *unused)
static unsigned long ion_secure_cma_shrinker(struct shrinker *shrinker,
struct shrink_control *sc)
{
+ unsigned long freed;
struct ion_cma_secure_heap *sheap = container_of(shrinker,
struct ion_cma_secure_heap, shrinker);
int nr_to_scan = sc->nr_to_scan;
@@ -400,11 +402,11 @@ static unsigned long ion_secure_cma_shrinker(struct shrinker *shrinker,
if (!mutex_trylock(&sheap->chunk_lock))
return -EAGAIN;
- __ion_secure_cma_shrink_pool(sheap, nr_to_scan);
+ freed = __ion_secure_cma_shrink_pool(sheap, nr_to_scan);
mutex_unlock(&sheap->chunk_lock);
- return atomic_read(&sheap->total_pool_size);
+ return freed;
}
static unsigned long ion_secure_cma_shrinker_count(struct shrinker *shrinker,
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index 5d345cceb702..423e07da480a 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -3253,7 +3253,7 @@ static int qpnp_adc_tm_probe(struct platform_device *pdev)
} else {
rc = devm_request_irq(&pdev->dev, chip->adc->adc_irq_eoc,
qpnp_adc_tm_rc_thr_isr,
- IRQF_TRIGGER_HIGH, "qpnp_adc_tm_interrupt", chip);
+ IRQF_TRIGGER_RISING, "qpnp_adc_tm_interrupt", chip);
if (rc)
dev_err(&pdev->dev, "failed to request adc irq\n");
else
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 064753880e99..5f3d2e2bdbdf 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -3002,9 +3002,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, __u64 start, __u64 len);
-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 4d78b932c320..b7217977e4f8 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -897,11 +897,11 @@ retry_journal:
flags |= AOP_FLAG_NOFS;
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;
@@ -1873,42 +1873,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 b0544114a3b9..32c52fc41c54 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -207,12 +207,12 @@ ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh)
{
int error;
- if (buffer_verified(bh))
- return 0;
-
if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
BHDR(bh)->h_blocks != cpu_to_le32(1))
return -EFSCORRUPTED;
+ if (buffer_verified(bh))
+ return 0;
+
if (!ext4_xattr_block_csum_verify(inode, bh))
return -EFSBADCRC;
error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size,
@@ -643,14 +643,20 @@ static size_t ext4_xattr_free_space(struct ext4_xattr_entry *last,
}
static int
-ext4_xattr_set_entry(struct ext4_xattr_info *i, struct ext4_xattr_search *s)
+ext4_xattr_set_entry(struct ext4_xattr_info *i, struct ext4_xattr_search *s,
+ struct inode *inode)
{
- struct ext4_xattr_entry *last;
+ struct ext4_xattr_entry *last, *next;
size_t free, min_offs = s->end - s->base, name_len = strlen(i->name);
/* Compute min_offs and last. */
last = s->first;
- for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
+ for (; !IS_LAST_ENTRY(last); last = next) {
+ next = EXT4_XATTR_NEXT(last);
+ if ((void *)next >= s->end) {
+ EXT4_ERROR_INODE(inode, "corrupted xattr entries");
+ return -EIO;
+ }
if (last->e_value_size) {
size_t offs = le16_to_cpu(last->e_value_offs);
if (offs < min_offs)
@@ -832,7 +838,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
mb_cache_entry_delete_block(ext4_mb_cache, hash,
bs->bh->b_blocknr);
ea_bdebug(bs->bh, "modifying in-place");
- error = ext4_xattr_set_entry(i, s);
+ error = ext4_xattr_set_entry(i, s, inode);
if (!error) {
if (!IS_LAST_ENTRY(s->first))
ext4_xattr_rehash(header(s->base),
@@ -879,7 +885,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
s->end = s->base + sb->s_blocksize;
}
- error = ext4_xattr_set_entry(i, s);
+ error = ext4_xattr_set_entry(i, s, inode);
if (error == -EFSCORRUPTED)
goto bad_block;
if (error)
@@ -1077,23 +1083,9 @@ 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);
- 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);
- }
- if (error)
- return error;
- }
+ error = ext4_xattr_set_entry(i, s, inode);
+ 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);
@@ -1115,7 +1107,7 @@ static int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
if (EXT4_I(inode)->i_extra_isize == 0)
return -ENOSPC;
- error = ext4_xattr_set_entry(i, s);
+ error = ext4_xattr_set_entry(i, s, inode);
if (error)
return error;
header = IHDR(inode, ext4_raw_inode(&is->iloc));
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 5e659ee08d6a..4aa23281748d 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1349,6 +1349,13 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
if (jh->b_transaction == transaction &&
jh->b_jlist != BJ_Metadata) {
jbd_lock_bh_state(bh);
+ if (jh->b_transaction == transaction &&
+ jh->b_jlist != BJ_Metadata)
+ pr_err("JBD2: assertion failure: h_type=%u "
+ "h_line_no=%u block_no=%llu jlist=%u\n",
+ handle->h_type, handle->h_line_no,
+ (unsigned long long) bh->b_blocknr,
+ jh->b_jlist);
J_ASSERT_JH(jh, jh->b_transaction != transaction ||
jh->b_jlist == BJ_Metadata);
jbd_unlock_bh_state(bh);
@@ -1368,11 +1375,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/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h
index 5539933b3491..993bb463ef96 100644
--- a/include/uapi/linux/android/binder.h
+++ b/include/uapi/linux/android/binder.h
@@ -87,6 +87,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
@@ -254,6 +262,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
@@ -312,6 +321,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;
@@ -347,6 +361,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),
/*