Merge branch 'LA.UM.9.6.2.c25' into int/11/fp3
* LA.UM.9.6.2.c25:
disp: msm: sde: protect file private structure with mutex lock
msm: adsprpc: Allocate buffer taking NULL byte into consideration
msm: kgsl: Update register protection config
msm: adsprpc: null pointer check for fl
msm: kgsl: Fix out of bound write in adreno_profile_submit_time
msm: adsprpc: overflow vulnerability by race condition in adsprpc driver
disp: msm: sde: add null check for drm file in msm_release
msm: adsprpc: Handle UAF in process shell memory
msm: adsprpc: Fix race condition in internal_control
net:sockev: hold file reference till the sock event is sent
Change-Id: I365c83e64ccd60c3748e8413f03af884cc34f582
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index ff8c1cd..d9708d1 100755
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -57,6 +57,8 @@
#define MSM_VERSION_MINOR 2
#define MSM_VERSION_PATCHLEVEL 0
+static DEFINE_MUTEX(msm_release_lock);
+
static void msm_fb_output_poll_changed(struct drm_device *dev)
{
struct msm_drm_private *priv = NULL;
@@ -1419,14 +1421,27 @@
static int msm_release(struct inode *inode, struct file *filp)
{
- struct drm_file *file_priv = filp->private_data;
- struct drm_minor *minor = file_priv->minor;
- struct drm_device *dev = minor->dev;
- struct msm_drm_private *priv = dev->dev_private;
+ struct drm_file *file_priv;
+ struct drm_minor *minor;
+ struct drm_device *dev;
+ struct msm_drm_private *priv;
struct msm_drm_event *node, *temp, *tmp_node;
u32 count;
unsigned long flags;
LIST_HEAD(tmp_head);
+ int ret = 0;
+
+ mutex_lock(&msm_release_lock);
+
+ file_priv = filp->private_data;
+ if (!file_priv) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ minor = file_priv->minor;
+ dev = minor->dev;
+ priv = dev->dev_private;
spin_lock_irqsave(&dev->event_lock, flags);
list_for_each_entry_safe(node, temp, &priv->client_event_list,
@@ -1454,7 +1469,11 @@
kfree(node);
}
- return drm_release(inode, filp);
+ ret = drm_release(inode, filp);
+ filp->private_data = NULL;
+end:
+ mutex_unlock(&msm_release_lock);
+ return ret;
}
/**
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index 754e419..5a3a26d 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018,2020 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018,2020-2021, 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
@@ -277,6 +277,7 @@
{ 0x8D0, 0x23, 0 },
{ 0x980, 0x4, 0 },
{ 0xA630, 0x0, 1 },
+ { 0x1b400, 0x1fff, 1 },
};
/* IFPC & Preemption static powerup restore list */
diff --git a/drivers/gpu/msm/kgsl_drawobj.c b/drivers/gpu/msm/kgsl_drawobj.c
index 1bfc905..b0dd4ac 100644
--- a/drivers/gpu/msm/kgsl_drawobj.c
+++ b/drivers/gpu/msm/kgsl_drawobj.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2019,2021, 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
@@ -569,6 +569,7 @@
{
struct kgsl_mem_entry *entry;
struct kgsl_drawobj *drawobj = DRAWOBJ(cmdobj);
+ u64 start;
if (!(drawobj->flags & KGSL_DRAWOBJ_PROFILING))
return;
@@ -585,7 +586,14 @@
gpuaddr);
if (entry != NULL) {
- if (!kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr, size)) {
+ start = id ? (entry->memdesc.gpuaddr + offset) : gpuaddr;
+ /*
+ * Make sure there is enough room in the object to store the
+ * entire profiling buffer object
+ */
+ if (!kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr, size) ||
+ !kgsl_gpuaddr_in_memdesc(&entry->memdesc, start,
+ sizeof(struct kgsl_drawobj_profiling_buffer))) {
kgsl_mem_entry_put(entry);
entry = NULL;
}
@@ -598,28 +606,7 @@
return;
}
-
- if (!id) {
- cmdobj->profiling_buffer_gpuaddr = gpuaddr;
- } else {
- u64 off = offset + sizeof(struct kgsl_drawobj_profiling_buffer);
-
- /*
- * Make sure there is enough room in the object to store the
- * entire profiling buffer object
- */
- if (off < offset || off >= entry->memdesc.size) {
- dev_err(device->dev,
- "ignore invalid profile offset ctxt %d id %d offset %lld gpuaddr %llx size %lld\n",
- drawobj->context->id, id, offset, gpuaddr, size);
- kgsl_mem_entry_put(entry);
- return;
- }
-
- cmdobj->profiling_buffer_gpuaddr =
- entry->memdesc.gpuaddr + offset;
- }
-
+ cmdobj->profiling_buffer_gpuaddr = start;
cmdobj->profiling_buf_entry = entry;
}