]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 1 Aug 2020 13:36:11 +0000 (15:36 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 1 Aug 2020 13:36:11 +0000 (15:36 +0200)
added patches:
drm-amd-display-clear-dm_state-for-fast-updates.patch
drm-amdgpu-prevent-kernel-infoleak-in-amdgpu_info_ioctl.patch
drm-dbi-fix-spi-type-1-9-bit-transfer.patch
drm-hold-gem-reference-until-object-is-no-longer-accessed.patch
revert-drm-amdgpu-fix-null-dereference-in-dpm-sysfs-handlers.patch

queue-5.4/drm-amd-display-clear-dm_state-for-fast-updates.patch [new file with mode: 0644]
queue-5.4/drm-amdgpu-prevent-kernel-infoleak-in-amdgpu_info_ioctl.patch [new file with mode: 0644]
queue-5.4/drm-dbi-fix-spi-type-1-9-bit-transfer.patch [new file with mode: 0644]
queue-5.4/drm-hold-gem-reference-until-object-is-no-longer-accessed.patch [new file with mode: 0644]
queue-5.4/revert-drm-amdgpu-fix-null-dereference-in-dpm-sysfs-handlers.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/drm-amd-display-clear-dm_state-for-fast-updates.patch b/queue-5.4/drm-amd-display-clear-dm_state-for-fast-updates.patch
new file mode 100644 (file)
index 0000000..9c3d938
--- /dev/null
@@ -0,0 +1,101 @@
+From fde9f39ac7f1ffd799a96ffa1e06b2051f0898f1 Mon Sep 17 00:00:00 2001
+From: Mazin Rezk <mnrzk@protonmail.com>
+Date: Mon, 27 Jul 2020 05:40:46 +0000
+Subject: drm/amd/display: Clear dm_state for fast updates
+
+From: Mazin Rezk <mnrzk@protonmail.com>
+
+commit fde9f39ac7f1ffd799a96ffa1e06b2051f0898f1 upstream.
+
+This patch fixes a race condition that causes a use-after-free during
+amdgpu_dm_atomic_commit_tail. This can occur when 2 non-blocking commits
+are requested and the second one finishes before the first. Essentially,
+this bug occurs when the following sequence of events happens:
+
+1. Non-blocking commit #1 is requested w/ a new dm_state #1 and is
+deferred to the workqueue.
+
+2. Non-blocking commit #2 is requested w/ a new dm_state #2 and is
+deferred to the workqueue.
+
+3. Commit #2 starts before commit #1, dm_state #1 is used in the
+commit_tail and commit #2 completes, freeing dm_state #1.
+
+4. Commit #1 starts after commit #2 completes, uses the freed dm_state
+1 and dereferences a freelist pointer while setting the context.
+
+Since this bug has only been spotted with fast commits, this patch fixes
+the bug by clearing the dm_state instead of using the old dc_state for
+fast updates. In addition, since dm_state is only used for its dc_state
+and amdgpu_dm_atomic_commit_tail will retain the dc_state if none is found,
+removing the dm_state should not have any consequences in fast updates.
+
+This use-after-free bug has existed for a while now, but only caused a
+noticeable issue starting from 5.7-rc1 due to 3202fa62f ("slub: relocate
+freelist pointer to middle of object") moving the freelist pointer from
+dm_state->base (which was unused) to dm_state->context (which is
+dereferenced).
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=207383
+Fixes: bd200d190f45 ("drm/amd/display: Don't replace the dc_state for fast updates")
+Reported-by: Duncan <1i5t5.duncan@cox.net>
+Signed-off-by: Mazin Rezk <mnrzk@protonmail.com>
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   36 ++++++++++++++++------
+ 1 file changed, 27 insertions(+), 9 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -7464,20 +7464,38 @@ static int amdgpu_dm_atomic_check(struct
+                * the same resource. If we have a new DC context as part of
+                * the DM atomic state from validation we need to free it and
+                * retain the existing one instead.
++               *
++               * Furthermore, since the DM atomic state only contains the DC
++               * context and can safely be annulled, we can free the state
++               * and clear the associated private object now to free
++               * some memory and avoid a possible use-after-free later.
+                */
+-              struct dm_atomic_state *new_dm_state, *old_dm_state;
+-              new_dm_state = dm_atomic_get_new_state(state);
+-              old_dm_state = dm_atomic_get_old_state(state);
++              for (i = 0; i < state->num_private_objs; i++) {
++                      struct drm_private_obj *obj = state->private_objs[i].ptr;
+-              if (new_dm_state && old_dm_state) {
+-                      if (new_dm_state->context)
+-                              dc_release_state(new_dm_state->context);
++                      if (obj->funcs == adev->dm.atomic_obj.funcs) {
++                              int j = state->num_private_objs-1;
+-                      new_dm_state->context = old_dm_state->context;
++                              dm_atomic_destroy_state(obj,
++                                              state->private_objs[i].state);
+-                      if (old_dm_state->context)
+-                              dc_retain_state(old_dm_state->context);
++                              /* If i is not at the end of the array then the
++                               * last element needs to be moved to where i was
++                               * before the array can safely be truncated.
++                               */
++                              if (i != j)
++                                      state->private_objs[i] =
++                                              state->private_objs[j];
++
++                              state->private_objs[j].ptr = NULL;
++                              state->private_objs[j].state = NULL;
++                              state->private_objs[j].old_state = NULL;
++                              state->private_objs[j].new_state = NULL;
++
++                              state->num_private_objs = j;
++                              break;
++                      }
+               }
+       }
diff --git a/queue-5.4/drm-amdgpu-prevent-kernel-infoleak-in-amdgpu_info_ioctl.patch b/queue-5.4/drm-amdgpu-prevent-kernel-infoleak-in-amdgpu_info_ioctl.patch
new file mode 100644 (file)
index 0000000..85f18ff
--- /dev/null
@@ -0,0 +1,47 @@
+From 543e8669ed9bfb30545fd52bc0e047ca4df7fb31 Mon Sep 17 00:00:00 2001
+From: Peilin Ye <yepeilin.cs@gmail.com>
+Date: Tue, 28 Jul 2020 15:29:24 -0400
+Subject: drm/amdgpu: Prevent kernel-infoleak in amdgpu_info_ioctl()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Peilin Ye <yepeilin.cs@gmail.com>
+
+commit 543e8669ed9bfb30545fd52bc0e047ca4df7fb31 upstream.
+
+Compiler leaves a 4-byte hole near the end of `dev_info`, causing
+amdgpu_info_ioctl() to copy uninitialized kernel stack memory to userspace
+when `size` is greater than 356.
+
+In 2015 we tried to fix this issue by doing `= {};` on `dev_info`, which
+unfortunately does not initialize that 4-byte hole. Fix it by using
+memset() instead.
+
+Cc: stable@vger.kernel.org
+Fixes: c193fa91b918 ("drm/amdgpu: information leak in amdgpu_info_ioctl()")
+Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)")
+Suggested-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+@@ -667,9 +667,10 @@ static int amdgpu_info_ioctl(struct drm_
+               return n ? -EFAULT : 0;
+       }
+       case AMDGPU_INFO_DEV_INFO: {
+-              struct drm_amdgpu_info_device dev_info = {};
++              struct drm_amdgpu_info_device dev_info;
+               uint64_t vm_size;
++              memset(&dev_info, 0, sizeof(dev_info));
+               dev_info.device_id = dev->pdev->device;
+               dev_info.chip_rev = adev->rev_id;
+               dev_info.external_rev = adev->external_rev_id;
diff --git a/queue-5.4/drm-dbi-fix-spi-type-1-9-bit-transfer.patch b/queue-5.4/drm-dbi-fix-spi-type-1-9-bit-transfer.patch
new file mode 100644 (file)
index 0000000..30a7a36
--- /dev/null
@@ -0,0 +1,47 @@
+From 900ab59e2621053b009f707f80b2c19ce0af5dee Mon Sep 17 00:00:00 2001
+From: Paul Cercueil <paul@crapouillou.net>
+Date: Fri, 3 Jul 2020 16:13:41 +0200
+Subject: drm/dbi: Fix SPI Type 1 (9-bit) transfer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Paul Cercueil <paul@crapouillou.net>
+
+commit 900ab59e2621053b009f707f80b2c19ce0af5dee upstream.
+
+The function mipi_dbi_spi1_transfer() will transfer its payload as 9-bit
+data, the 9th (MSB) bit being the data/command bit. In order to do that,
+it unpacks the 8-bit values into 16-bit values, then sets the 9th bit if
+the byte corresponds to data, clears it otherwise. The 7 MSB are
+padding. The array of now 16-bit values is then passed to the SPI core
+for transfer.
+
+This function was broken since its introduction, as the length of the
+SPI transfer was set to the payload size before its conversion, but the
+payload doubled in size due to the 8-bit -> 16-bit conversion.
+
+Fixes: 02dd95fe3169 ("drm/tinydrm: Add MIPI DBI support")
+Cc: <stable@vger.kernel.org> # 5.4+
+Signed-off-by: Paul Cercueil <paul@crapouillou.net>
+Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
+Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
+Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20200703141341.1266263-1-paul@crapouillou.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_mipi_dbi.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/drm_mipi_dbi.c
++++ b/drivers/gpu/drm/drm_mipi_dbi.c
+@@ -937,7 +937,7 @@ static int mipi_dbi_spi1_transfer(struct
+                       }
+               }
+-              tr.len = chunk;
++              tr.len = chunk * 2;
+               len -= chunk;
+               ret = spi_sync(spi, &m);
diff --git a/queue-5.4/drm-hold-gem-reference-until-object-is-no-longer-accessed.patch b/queue-5.4/drm-hold-gem-reference-until-object-is-no-longer-accessed.patch
new file mode 100644 (file)
index 0000000..456b2c8
--- /dev/null
@@ -0,0 +1,57 @@
+From 8490d6a7e0a0a6fab5c2d82d57a3937306660864 Mon Sep 17 00:00:00 2001
+From: Steve Cohen <cohens@codeaurora.org>
+Date: Mon, 20 Jul 2020 18:30:50 -0400
+Subject: drm: hold gem reference until object is no longer accessed
+
+From: Steve Cohen <cohens@codeaurora.org>
+
+commit 8490d6a7e0a0a6fab5c2d82d57a3937306660864 upstream.
+
+A use-after-free in drm_gem_open_ioctl can happen if the
+GEM object handle is closed between the idr lookup and
+retrieving the size from said object since a local reference
+is not being held at that point. Hold the local reference
+while the object can still be accessed to fix this and
+plug the potential security hole.
+
+Signed-off-by: Steve Cohen <cohens@codeaurora.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/1595284250-31580-1-git-send-email-cohens@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_gem.c |   10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/drm_gem.c
++++ b/drivers/gpu/drm/drm_gem.c
+@@ -872,9 +872,6 @@ err:
+  * @file_priv: drm file-private structure
+  *
+  * Open an object using the global name, returning a handle and the size.
+- *
+- * This handle (of course) holds a reference to the object, so the object
+- * will not go away until the handle is deleted.
+  */
+ int
+ drm_gem_open_ioctl(struct drm_device *dev, void *data,
+@@ -899,14 +896,15 @@ drm_gem_open_ioctl(struct drm_device *de
+       /* drm_gem_handle_create_tail unlocks dev->object_name_lock. */
+       ret = drm_gem_handle_create_tail(file_priv, obj, &handle);
+-      drm_gem_object_put_unlocked(obj);
+       if (ret)
+-              return ret;
++              goto err;
+       args->handle = handle;
+       args->size = obj->size;
+-      return 0;
++err:
++      drm_gem_object_put_unlocked(obj);
++      return ret;
+ }
+ /**
diff --git a/queue-5.4/revert-drm-amdgpu-fix-null-dereference-in-dpm-sysfs-handlers.patch b/queue-5.4/revert-drm-amdgpu-fix-null-dereference-in-dpm-sysfs-handlers.patch
new file mode 100644 (file)
index 0000000..e42fdf8
--- /dev/null
@@ -0,0 +1,54 @@
+From 87004abfbc27261edd15716515d89ab42198b405 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Thu, 30 Jul 2020 11:02:30 -0400
+Subject: Revert "drm/amdgpu: Fix NULL dereference in dpm sysfs handlers"
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 87004abfbc27261edd15716515d89ab42198b405 upstream.
+
+This regressed some working configurations so revert it.  Will
+fix this properly for 5.9 and backport then.
+
+This reverts commit 38e0c89a19fd13f28d2b4721035160a3e66e270b.
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+@@ -691,7 +691,8 @@ static ssize_t amdgpu_set_pp_od_clk_volt
+               tmp_str++;
+       while (isspace(*++tmp_str));
+-      while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) {
++      while (tmp_str[0]) {
++              sub_str = strsep(&tmp_str, delimiter);
+               ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
+               if (ret)
+                       return -EINVAL;
+@@ -882,7 +883,8 @@ static ssize_t amdgpu_read_mask(const ch
+       memcpy(buf_cpy, buf, bytes);
+       buf_cpy[bytes] = '\0';
+       tmp = buf_cpy;
+-      while ((sub_str = strsep(&tmp, delimiter)) != NULL) {
++      while (tmp[0]) {
++              sub_str = strsep(&tmp, delimiter);
+               if (strlen(sub_str)) {
+                       ret = kstrtol(sub_str, 0, &level);
+                       if (ret)
+@@ -1298,7 +1300,8 @@ static ssize_t amdgpu_set_pp_power_profi
+                       i++;
+               memcpy(buf_cpy, buf, count-i);
+               tmp_str = buf_cpy;
+-              while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) {
++              while (tmp_str[0]) {
++                      sub_str = strsep(&tmp_str, delimiter);
+                       ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
+                       if (ret) {
+                               count = -EINVAL;
index bc7ff0f655b79db5b8f89497b6bb1ddfcfe052f4..de7ec6e64013ae232457984f4ccd4fa884f66318 100644 (file)
@@ -21,3 +21,8 @@ arm-dts-imx6qdl-icore-fix-otg_id-pin-and-sdcard-detect.patch
 virtio_balloon-fix-up-endian-ness-for-free-cmd-id.patch
 random32-update-the-net-random-state-on-interrupt-and-activity.patch
 arm-percpu.h-fix-build-error.patch
+revert-drm-amdgpu-fix-null-dereference-in-dpm-sysfs-handlers.patch
+drm-amd-display-clear-dm_state-for-fast-updates.patch
+drm-amdgpu-prevent-kernel-infoleak-in-amdgpu_info_ioctl.patch
+drm-dbi-fix-spi-type-1-9-bit-transfer.patch
+drm-hold-gem-reference-until-object-is-no-longer-accessed.patch