Skip to content

Commit 801dff4

Browse files
committed
Merge tag 'drm-intel-fixes-2018-05-29' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes
- Fix for potential Spectre vector in the new query uAPI - Fix NULL pointer deref (FDO #106559) - DMI fix to hide LVDS for Radiant P845 (FDO #105468) * tag 'drm-intel-fixes-2018-05-29' of git://anongit.freedesktop.org/drm/drm-intel: drm/i915/query: nospec expects no more than an unsigned long drm/i915/query: Protect tainted function pointer lookup drm/i915/lvds: Move acpi lid notification registration to registration phase drm/i915: Disable LVDS on Radiant P845
2 parents b04e217 + 65b3bdc commit 801dff4

File tree

2 files changed

+51
-15
lines changed

2 files changed

+51
-15
lines changed

drivers/gpu/drm/i915/i915_query.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* Copyright © 2018 Intel Corporation
55
*/
66

7+
#include <linux/nospec.h>
8+
79
#include "i915_drv.h"
810
#include "i915_query.h"
911
#include <uapi/drm/i915_drm.h>
@@ -100,7 +102,7 @@ int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
100102

101103
for (i = 0; i < args->num_items; i++, user_item_ptr++) {
102104
struct drm_i915_query_item item;
103-
u64 func_idx;
105+
unsigned long func_idx;
104106
int ret;
105107

106108
if (copy_from_user(&item, user_item_ptr, sizeof(item)))
@@ -109,12 +111,17 @@ int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
109111
if (item.query_id == 0)
110112
return -EINVAL;
111113

114+
if (overflows_type(item.query_id - 1, unsigned long))
115+
return -EINVAL;
116+
112117
func_idx = item.query_id - 1;
113118

114-
if (func_idx < ARRAY_SIZE(i915_query_funcs))
119+
ret = -EINVAL;
120+
if (func_idx < ARRAY_SIZE(i915_query_funcs)) {
121+
func_idx = array_index_nospec(func_idx,
122+
ARRAY_SIZE(i915_query_funcs));
115123
ret = i915_query_funcs[func_idx](dev_priv, &item);
116-
else
117-
ret = -EINVAL;
124+
}
118125

119126
/* Only write the length back to userspace if they differ. */
120127
if (ret != item.length && put_user(ret, &user_item_ptr->length))

drivers/gpu/drm/i915/intel_lvds.c

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,36 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
574574
return NOTIFY_OK;
575575
}
576576

577+
static int
578+
intel_lvds_connector_register(struct drm_connector *connector)
579+
{
580+
struct intel_lvds_connector *lvds = to_lvds_connector(connector);
581+
int ret;
582+
583+
ret = intel_connector_register(connector);
584+
if (ret)
585+
return ret;
586+
587+
lvds->lid_notifier.notifier_call = intel_lid_notify;
588+
if (acpi_lid_notifier_register(&lvds->lid_notifier)) {
589+
DRM_DEBUG_KMS("lid notifier registration failed\n");
590+
lvds->lid_notifier.notifier_call = NULL;
591+
}
592+
593+
return 0;
594+
}
595+
596+
static void
597+
intel_lvds_connector_unregister(struct drm_connector *connector)
598+
{
599+
struct intel_lvds_connector *lvds = to_lvds_connector(connector);
600+
601+
if (lvds->lid_notifier.notifier_call)
602+
acpi_lid_notifier_unregister(&lvds->lid_notifier);
603+
604+
intel_connector_unregister(connector);
605+
}
606+
577607
/**
578608
* intel_lvds_destroy - unregister and free LVDS structures
579609
* @connector: connector to free
@@ -586,9 +616,6 @@ static void intel_lvds_destroy(struct drm_connector *connector)
586616
struct intel_lvds_connector *lvds_connector =
587617
to_lvds_connector(connector);
588618

589-
if (lvds_connector->lid_notifier.notifier_call)
590-
acpi_lid_notifier_unregister(&lvds_connector->lid_notifier);
591-
592619
if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
593620
kfree(lvds_connector->base.edid);
594621

@@ -609,8 +636,8 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
609636
.fill_modes = drm_helper_probe_single_connector_modes,
610637
.atomic_get_property = intel_digital_connector_atomic_get_property,
611638
.atomic_set_property = intel_digital_connector_atomic_set_property,
612-
.late_register = intel_connector_register,
613-
.early_unregister = intel_connector_unregister,
639+
.late_register = intel_lvds_connector_register,
640+
.early_unregister = intel_lvds_connector_unregister,
614641
.destroy = intel_lvds_destroy,
615642
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
616643
.atomic_duplicate_state = intel_digital_connector_duplicate_state,
@@ -827,6 +854,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
827854
DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
828855
},
829856
},
857+
{
858+
.callback = intel_no_lvds_dmi_callback,
859+
.ident = "Radiant P845",
860+
.matches = {
861+
DMI_MATCH(DMI_SYS_VENDOR, "Radiant Systems Inc"),
862+
DMI_MATCH(DMI_PRODUCT_NAME, "P845"),
863+
},
864+
},
830865

831866
{ } /* terminating entry */
832867
};
@@ -1150,12 +1185,6 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
11501185

11511186
lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK;
11521187

1153-
lvds_connector->lid_notifier.notifier_call = intel_lid_notify;
1154-
if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) {
1155-
DRM_DEBUG_KMS("lid notifier registration failed\n");
1156-
lvds_connector->lid_notifier.notifier_call = NULL;
1157-
}
1158-
11591188
return;
11601189

11611190
failed:

0 commit comments

Comments
 (0)