Skip to content

Commit d8b9fae

Browse files
committed
Merge tag 'drm-fixes-2020-07-31' of git://anongit.freedesktop.org/drm/drm
Pull more drm fixes from Dave Airlie: "As mentioned previously this contains the nouveau regression fix. amdgpu had three fixes outstanding as well, one revert, an info leak and use after free. The use after free is a bit trickier than I'd like, and I've personally gone over it to confirm I'm happy that it is doing what it says. nouveau: - final modifiers regression fix amdgpu: - Revert a fix which caused other regressions - Fix potential kernel info leak - Fix a use-after-free bug that was uncovered by another change in 5.7" * tag 'drm-fixes-2020-07-31' of git://anongit.freedesktop.org/drm/drm: drm/nouveau: Accept 'legacy' format modifiers Revert "drm/amdgpu: Fix NULL dereference in dpm sysfs handlers" drm/amd/display: Clear dm_state for fast updates drm/amdgpu: Prevent kernel-infoleak in amdgpu_info_ioctl()
2 parents a2ec905 + 887c909 commit d8b9fae

File tree

4 files changed

+60
-15
lines changed

4 files changed

+60
-15
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,9 +692,10 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
692692
return n ? -EFAULT : 0;
693693
}
694694
case AMDGPU_INFO_DEV_INFO: {
695-
struct drm_amdgpu_info_device dev_info = {};
695+
struct drm_amdgpu_info_device dev_info;
696696
uint64_t vm_size;
697697

698+
memset(&dev_info, 0, sizeof(dev_info));
698699
dev_info.device_id = dev->pdev->device;
699700
dev_info.chip_rev = adev->rev_id;
700701
dev_info.external_rev = adev->external_rev_id;

drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,8 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,
778778
tmp_str++;
779779
while (isspace(*++tmp_str));
780780

781-
while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) {
781+
while (tmp_str[0]) {
782+
sub_str = strsep(&tmp_str, delimiter);
782783
ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
783784
if (ret)
784785
return -EINVAL;
@@ -1038,7 +1039,8 @@ static ssize_t amdgpu_read_mask(const char *buf, size_t count, uint32_t *mask)
10381039
memcpy(buf_cpy, buf, bytes);
10391040
buf_cpy[bytes] = '\0';
10401041
tmp = buf_cpy;
1041-
while ((sub_str = strsep(&tmp, delimiter)) != NULL) {
1042+
while (tmp[0]) {
1043+
sub_str = strsep(&tmp, delimiter);
10421044
if (strlen(sub_str)) {
10431045
ret = kstrtol(sub_str, 0, &level);
10441046
if (ret)
@@ -1635,7 +1637,8 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
16351637
i++;
16361638
memcpy(buf_cpy, buf, count-i);
16371639
tmp_str = buf_cpy;
1638-
while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) {
1640+
while (tmp_str[0]) {
1641+
sub_str = strsep(&tmp_str, delimiter);
16391642
ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
16401643
if (ret)
16411644
return -EINVAL;

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8717,20 +8717,38 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
87178717
* the same resource. If we have a new DC context as part of
87188718
* the DM atomic state from validation we need to free it and
87198719
* retain the existing one instead.
8720+
*
8721+
* Furthermore, since the DM atomic state only contains the DC
8722+
* context and can safely be annulled, we can free the state
8723+
* and clear the associated private object now to free
8724+
* some memory and avoid a possible use-after-free later.
87208725
*/
8721-
struct dm_atomic_state *new_dm_state, *old_dm_state;
87228726

8723-
new_dm_state = dm_atomic_get_new_state(state);
8724-
old_dm_state = dm_atomic_get_old_state(state);
8727+
for (i = 0; i < state->num_private_objs; i++) {
8728+
struct drm_private_obj *obj = state->private_objs[i].ptr;
87258729

8726-
if (new_dm_state && old_dm_state) {
8727-
if (new_dm_state->context)
8728-
dc_release_state(new_dm_state->context);
8730+
if (obj->funcs == adev->dm.atomic_obj.funcs) {
8731+
int j = state->num_private_objs-1;
87298732

8730-
new_dm_state->context = old_dm_state->context;
8733+
dm_atomic_destroy_state(obj,
8734+
state->private_objs[i].state);
8735+
8736+
/* If i is not at the end of the array then the
8737+
* last element needs to be moved to where i was
8738+
* before the array can safely be truncated.
8739+
*/
8740+
if (i != j)
8741+
state->private_objs[i] =
8742+
state->private_objs[j];
87318743

8732-
if (old_dm_state->context)
8733-
dc_retain_state(old_dm_state->context);
8744+
state->private_objs[j].ptr = NULL;
8745+
state->private_objs[j].state = NULL;
8746+
state->private_objs[j].old_state = NULL;
8747+
state->private_objs[j].new_state = NULL;
8748+
8749+
state->num_private_objs = j;
8750+
break;
8751+
}
87348752
}
87358753
}
87368754

drivers/gpu/drm/nouveau/nouveau_display.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ nouveau_decode_mod(struct nouveau_drm *drm,
191191
uint32_t *tile_mode,
192192
uint8_t *kind)
193193
{
194+
struct nouveau_display *disp = nouveau_display(drm->dev);
194195
BUG_ON(!tile_mode || !kind);
195196

196197
if (modifier == DRM_FORMAT_MOD_LINEAR) {
@@ -202,6 +203,12 @@ nouveau_decode_mod(struct nouveau_drm *drm,
202203
* Extract the block height and kind from the corresponding
203204
* modifier fields. See drm_fourcc.h for details.
204205
*/
206+
207+
if ((modifier & (0xffull << 12)) == 0ull) {
208+
/* Legacy modifier. Translate to this dev's 'kind.' */
209+
modifier |= disp->format_modifiers[0] & (0xffull << 12);
210+
}
211+
205212
*tile_mode = (uint32_t)(modifier & 0xF);
206213
*kind = (uint8_t)((modifier >> 12) & 0xFF);
207214

@@ -227,6 +234,16 @@ nouveau_framebuffer_get_layout(struct drm_framebuffer *fb,
227234
}
228235
}
229236

237+
static const u64 legacy_modifiers[] = {
238+
DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0),
239+
DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1),
240+
DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2),
241+
DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3),
242+
DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4),
243+
DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5),
244+
DRM_FORMAT_MOD_INVALID
245+
};
246+
230247
static int
231248
nouveau_validate_decode_mod(struct nouveau_drm *drm,
232249
uint64_t modifier,
@@ -247,8 +264,14 @@ nouveau_validate_decode_mod(struct nouveau_drm *drm,
247264
(disp->format_modifiers[mod] != modifier);
248265
mod++);
249266

250-
if (disp->format_modifiers[mod] == DRM_FORMAT_MOD_INVALID)
251-
return -EINVAL;
267+
if (disp->format_modifiers[mod] == DRM_FORMAT_MOD_INVALID) {
268+
for (mod = 0;
269+
(legacy_modifiers[mod] != DRM_FORMAT_MOD_INVALID) &&
270+
(legacy_modifiers[mod] != modifier);
271+
mod++);
272+
if (legacy_modifiers[mod] == DRM_FORMAT_MOD_INVALID)
273+
return -EINVAL;
274+
}
252275

253276
nouveau_decode_mod(drm, modifier, tile_mode, kind);
254277

0 commit comments

Comments
 (0)