diff mbox

intel: don't crash when freeing an uninitialized screen

Message ID 1363117558-19966-1-git-send-email-aplattner@nvidia.com (mailing list archive)
State New, archived
Headers show

Commit Message

Aaron Plattner March 12, 2013, 7:45 p.m. UTC
When intel_scrn_create creates a screen, it sets scrn->driverPrivate to
(void *)(match_data | 1).  Normally, this is read by I830PreInit and then
replaced with a pointer to the intel_screen_private structure.  However, it's
possible for the server to delete the screen before initializing it, which leads
to a crash in I830FreeScreen when it tries to interpret the unaligned match_data
pointer as a pointer to a intel_screen_private.

Fix this by checking the low bit of the pointer and skipping the teardown code
if it's set.

Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
---
 src/intel_driver.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Chris Wilson March 12, 2013, 8:22 p.m. UTC | #1
On Tue, Mar 12, 2013 at 12:45:58PM -0700, Aaron Plattner wrote:
> When intel_scrn_create creates a screen, it sets scrn->driverPrivate to
> (void *)(match_data | 1).  Normally, this is read by I830PreInit and then
> replaced with a pointer to the intel_screen_private structure.  However, it's
> possible for the server to delete the screen before initializing it, which leads
> to a crash in I830FreeScreen when it tries to interpret the unaligned match_data
> pointer as a pointer to a intel_screen_private.
> 
> Fix this by checking the low bit of the pointer and skipping the teardown code
> if it's set.
> 
> Signed-off-by: Aaron Plattner <aplattner@nvidia.com>

Thanks, I had forgotten all about that path. Pushed,
-Chris
diff mbox

Patch

diff --git a/src/intel_driver.c b/src/intel_driver.c
index 7f11978..ae2e31e 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -1093,7 +1093,7 @@  static void I830FreeScreen(FREE_SCREEN_ARGS_DECL)
 	SCRN_INFO_PTR(arg);
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 
-	if (intel) {
+	if (intel && !((uintptr_t)intel & 1)) {
 		intel_mode_fini(intel);
 		intel_close_drm_master(intel);
 		intel_bufmgr_fini(intel);