mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-10 15:54:39 +08:00
drm: qxl: Fix NULL pointer dereference at qxl_alloc_client_monitors_config
If qxl_alloc_client_monitors_config() fails to allocate client_monitors_config then NULL pointer dereference occurs in function qxl_display_copy_rom_client_monitors_config() after qxl_alloc_client_monitors_config() call. The patch adds return error from qxl_alloc_client_monitors_config() and additional status for qxl_display_copy_rom_client_monitors_config return value. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Anton Vasilyev <vasilyev@ispras.ru> Link: http://patchwork.freedesktop.org/patch/msgid/20180727153058.23620-1-vasilyev@ispras.ru Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
5043348a49
commit
66e0c8a5bc
@ -37,7 +37,8 @@ static bool qxl_head_enabled(struct qxl_head *head)
|
|||||||
return head->width && head->height;
|
return head->width && head->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qxl_alloc_client_monitors_config(struct qxl_device *qdev, unsigned count)
|
static int qxl_alloc_client_monitors_config(struct qxl_device *qdev,
|
||||||
|
unsigned int count)
|
||||||
{
|
{
|
||||||
if (qdev->client_monitors_config &&
|
if (qdev->client_monitors_config &&
|
||||||
count > qdev->client_monitors_config->count) {
|
count > qdev->client_monitors_config->count) {
|
||||||
@ -49,15 +50,17 @@ static void qxl_alloc_client_monitors_config(struct qxl_device *qdev, unsigned c
|
|||||||
sizeof(struct qxl_monitors_config) +
|
sizeof(struct qxl_monitors_config) +
|
||||||
sizeof(struct qxl_head) * count, GFP_KERNEL);
|
sizeof(struct qxl_head) * count, GFP_KERNEL);
|
||||||
if (!qdev->client_monitors_config)
|
if (!qdev->client_monitors_config)
|
||||||
return;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
qdev->client_monitors_config->count = count;
|
qdev->client_monitors_config->count = count;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MONITORS_CONFIG_MODIFIED,
|
MONITORS_CONFIG_MODIFIED,
|
||||||
MONITORS_CONFIG_UNCHANGED,
|
MONITORS_CONFIG_UNCHANGED,
|
||||||
MONITORS_CONFIG_BAD_CRC,
|
MONITORS_CONFIG_BAD_CRC,
|
||||||
|
MONITORS_CONFIG_ERROR,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int qxl_display_copy_rom_client_monitors_config(struct qxl_device *qdev)
|
static int qxl_display_copy_rom_client_monitors_config(struct qxl_device *qdev)
|
||||||
@ -87,7 +90,10 @@ static int qxl_display_copy_rom_client_monitors_config(struct qxl_device *qdev)
|
|||||||
&& (num_monitors != qdev->client_monitors_config->count)) {
|
&& (num_monitors != qdev->client_monitors_config->count)) {
|
||||||
status = MONITORS_CONFIG_MODIFIED;
|
status = MONITORS_CONFIG_MODIFIED;
|
||||||
}
|
}
|
||||||
qxl_alloc_client_monitors_config(qdev, num_monitors);
|
if (qxl_alloc_client_monitors_config(qdev, num_monitors)) {
|
||||||
|
status = MONITORS_CONFIG_ERROR;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
/* we copy max from the client but it isn't used */
|
/* we copy max from the client but it isn't used */
|
||||||
qdev->client_monitors_config->max_allowed =
|
qdev->client_monitors_config->max_allowed =
|
||||||
qdev->monitors_config->max_allowed;
|
qdev->monitors_config->max_allowed;
|
||||||
@ -161,6 +167,10 @@ void qxl_display_read_client_monitors_config(struct qxl_device *qdev)
|
|||||||
break;
|
break;
|
||||||
udelay(5);
|
udelay(5);
|
||||||
}
|
}
|
||||||
|
if (status == MONITORS_CONFIG_ERROR) {
|
||||||
|
DRM_DEBUG_KMS("ignoring client monitors config: error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (status == MONITORS_CONFIG_BAD_CRC) {
|
if (status == MONITORS_CONFIG_BAD_CRC) {
|
||||||
DRM_DEBUG_KMS("ignoring client monitors config: bad crc");
|
DRM_DEBUG_KMS("ignoring client monitors config: bad crc");
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user