mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 12:35:52 +02:00
ACPI fix for final 6.13
Prevent acpi_video_device_EDID() from returning a pointer to a memory region that should not be passed to kfree() which causes one of its users to crash randomly on attempts to free it (Chris Bainbridge). -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAmeJF6YSHHJqd0Byand5 c29ja2kubmV0AAoJEILEb/54YlRxqbgQAIdwiU/kLnvhIxfgOpaqMtAWxlpwmMyU qXmBNrvrW0CueMy2lCCKQZbVcyxxzvZigV8eW1rdmx+ISfI3fPTFeroqK+XHMl6z +izohhWVKj3hCormkefOLuqh1TnJsM0OVYVVJrQZ4CrewunCzG7mR72qaJnk+98x LQuSOCIbAe7AChAEW1Ydg1I2oWcwz4HUdixkJse5F3h8M51ZhwyoUZsRvk2fIIVA pfcZw2yz9bidCzUuhP54pfVwVItngCe9AwUu7/gDUXCAtxyMQrMn5ppDSmYhCHxc BSACmcDdJzOOcwoBRbsaYJrc33zRXH8NmXK3ekZLb3FgozDmuT01lvsn+tGay/zR Ektk0d0uSLLDfaXdO4IycuEtngINkO7R43J4TiT5QufN+HLJz3Ru+0/cGe3YkSae WLu+N3ZDnpA9CDT4A/eEL6taabZfgN2FIKNq+OuKdhb9sogrcrN2U6R5RvIWZipN +Xgwg1euRrmAfjDZngvpDRVMTYywl8PYoGdoYKMDHlLU6ftzK+5d59juBXVsoze8 8IUUgszkNcqunMj+V3GlnRmu6LlTpRQinArFU+DKf3/YQvqr+l9V8IDjiiFiQh6N P2BPUlKTl3LgiY2vNvztxQK504cim78Xwe2U+rwngJS6y2SiGldkwwxSzILAsVA2 YIbY9jfQeTlF =7/13 -----END PGP SIGNATURE----- Merge tag 'acpi-6.13-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull ACPI fix from Rafael Wysocki: "Prevent acpi_video_device_EDID() from returning a pointer to a memory region that should not be passed to kfree() which causes one of its users to crash randomly on attempts to free it (Chris Bainbridge)" * tag 'acpi-6.13-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI: video: Fix random crashes due to bad kfree()
This commit is contained in:
commit
5d5c478759
|
|
@ -610,16 +610,28 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_video_device_EDID() - Get EDID from ACPI _DDC
|
||||
* @device: video output device (LCD, CRT, ..)
|
||||
* @edid: address for returned EDID pointer
|
||||
* @length: _DDC length to request (must be a multiple of 128)
|
||||
*
|
||||
* Get EDID from ACPI _DDC. On success, a pointer to the EDID data is written
|
||||
* to the @edid address, and the length of the EDID is returned. The caller is
|
||||
* responsible for freeing the edid pointer.
|
||||
*
|
||||
* Return the length of EDID (positive value) on success or error (negative
|
||||
* value).
|
||||
*/
|
||||
static int
|
||||
acpi_video_device_EDID(struct acpi_video_device *device,
|
||||
union acpi_object **edid, int length)
|
||||
acpi_video_device_EDID(struct acpi_video_device *device, void **edid, int length)
|
||||
{
|
||||
int status;
|
||||
acpi_status status;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *obj;
|
||||
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
|
||||
struct acpi_object_list args = { 1, &arg0 };
|
||||
|
||||
int ret;
|
||||
|
||||
*edid = NULL;
|
||||
|
||||
|
|
@ -636,16 +648,17 @@ acpi_video_device_EDID(struct acpi_video_device *device,
|
|||
|
||||
obj = buffer.pointer;
|
||||
|
||||
if (obj && obj->type == ACPI_TYPE_BUFFER)
|
||||
*edid = obj;
|
||||
else {
|
||||
if (obj && obj->type == ACPI_TYPE_BUFFER) {
|
||||
*edid = kmemdup(obj->buffer.pointer, obj->buffer.length, GFP_KERNEL);
|
||||
ret = *edid ? obj->buffer.length : -ENOMEM;
|
||||
} else {
|
||||
acpi_handle_debug(device->dev->handle,
|
||||
"Invalid _DDC data for length %d\n", length);
|
||||
status = -EFAULT;
|
||||
kfree(obj);
|
||||
ret = -EFAULT;
|
||||
}
|
||||
|
||||
return status;
|
||||
kfree(obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* bus */
|
||||
|
|
@ -1435,9 +1448,7 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
|
|||
{
|
||||
struct acpi_video_bus *video;
|
||||
struct acpi_video_device *video_device;
|
||||
union acpi_object *buffer = NULL;
|
||||
acpi_status status;
|
||||
int i, length;
|
||||
int i, length, ret;
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
|
|
@ -1477,16 +1488,10 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
|
|||
}
|
||||
|
||||
for (length = 512; length > 0; length -= 128) {
|
||||
status = acpi_video_device_EDID(video_device, &buffer,
|
||||
length);
|
||||
if (ACPI_SUCCESS(status))
|
||||
break;
|
||||
ret = acpi_video_device_EDID(video_device, edid, length);
|
||||
if (ret > 0)
|
||||
return ret;
|
||||
}
|
||||
if (!length)
|
||||
continue;
|
||||
|
||||
*edid = buffer->buffer.pointer;
|
||||
return length;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector)
|
|||
if (ret < 0)
|
||||
return NULL;
|
||||
|
||||
return kmemdup(edid, EDID_LENGTH, GFP_KERNEL);
|
||||
return edid;
|
||||
}
|
||||
|
||||
bool nouveau_acpi_video_backlight_use_native(void)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user