[PATCH] Avoid segfaults in XF86VidMode GammaRamp functions if randr_crtc is NULL
Alan Coopersmith
Alan.Coopersmith at Sun.COM
Tue Jan 26 23:31:55 PST 2010
Keith Packard wrote:
> On Tue, 26 Jan 2010 22:25:04 -0800, Alan Coopersmith <alan.coopersmith at sun.com> wrote:
>
>> Fixes crash when xscreensaver tries to use GammaRamp calls to fade out
>> http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6915712
>
> This seems odd to me; how can you have a crtc and no randr_crtc?
Unfortunately, I don't have the source to the driver used when this was hit
(another engineer here does have it if it helps). I know it's based on the
xf86-video-radeon driver, but modified to work with the SPARC kernel fb driver
for the ATI boards Sun OEM'ed. (Someday I'd love to get ATI's permission to
merge our changes back to the radeon driver, but unfortunately our license
predate ATI's acceptance of open source drivers.)
What I saw in the debugger was:
t at 1 (l at 1) signal SEGV (no mapping at the fault address) in xf86GetGammaRampSize
at line 1080 in file "xf86cmap.c"
1078 RRCrtcPtr crtc =
config->output[config->compat_output]->crtc->randr_crtc;
1079
1080 return crtc->gammaSize;
(dbx) where
current thread: t at 1
=>[1] xf86GetGammaRampSize(pScreen = 0x100868120), line 1080 in "xf86cmap.c"
[2] VidModeGetGammaRampSize(scrnIndex = 0), line 522 in "xf86VidMode.c"
[3] ProcXF86VidModeGetGammaRampSize(0x10092e950, 0xffffffff7bb0cef8, 0x10df64,
0x148, 0x0, 0xffffffff7bc1ab98), at 0xffffffff7bb0cca4
[4] Dispatch(0x4333b0, 0x1008229f8, 0x10092e950, 0x0, 0x10092ecb0, 0xbe0), at
0x100065c00
[5] main(0x8, 0xffffffff7ffffba8, 0x100825250, 0x100822a00, 0x100825248,
0x100819f88), at 0x1000c7c2c
(dbx) print crtc
crtc = (nil)
(dbx) print config->output
config->output = 0x100842190
(dbx) print config->compat_output
config->compat_output = 1
(dbx) print config->output[config->compat_output]
config->output[config->compat_output] = 0x10085c320
(dbx) print config->output[config->compat_output]->crtc
config->output[config->compat_output]->crtc = 0x100859fc0
(dbx) print *config->output[config->compat_output]->crtc
*config->output[config->compat_output]->crtc = {
version = 3
scrn = 0x1008542a0
enabled = 1
mode = {
prev = (nil)
next = 0x10085d090
name = 0x1008421f0 "VESA_STD_1280x1024x75"
status = MODE_OK
type = 136
Clock = 135000
HDisplay = 1280
HSyncStart = 1296
HSyncEnd = 1440
HTotal = 1688
HSkew = 0
VDisplay = 1024
VSyncStart = 1025
VSyncEnd = 1028
VTotal = 1066
VScan = 0
Flags = 5
ClockIndex = 0
SynthClock = 0
CrtcHDisplay = 1280
CrtcHBlankStart = 1280
CrtcHSyncStart = 1296
CrtcHSyncEnd = 1440
CrtcHBlankEnd = 1688
CrtcHTotal = 1688
CrtcHSkew = 0
CrtcVDisplay = 1024
CrtcVBlankStart = 1024
CrtcVSyncStart = 1025
CrtcVSyncEnd = 1028
CrtcVBlankEnd = 1066
CrtcVTotal = 1066
CrtcHAdjusted = 0
CrtcVAdjusted = 0
PrivSize = 0
Private = (nil)
PrivFlags = 0
HSync = 0.0
VRefresh = 75.02467
}
rotation = 1U
rotatedPixmap = (nil)
rotatedData = (nil)
x = 0
y = 0
desiredMode = {
prev = (nil)
next = 0x10085d090
name = 0x1008421f0 "VESA_STD_1280x1024x75"
status = MODE_OK
type = 136
Clock = 135000
HDisplay = 1280
HSyncStart = 1296
HSyncEnd = 1440
HTotal = 1688
HSkew = 0
VDisplay = 1024
VSyncStart = 1025
VSyncEnd = 1028
VTotal = 1066
VScan = 0
Flags = 5
ClockIndex = 0
SynthClock = 0
CrtcHDisplay = 1280
CrtcHBlankStart = 1280
CrtcHSyncStart = 1296
CrtcHSyncEnd = 1440
CrtcHBlankEnd = 1688
CrtcHTotal = 1688
CrtcHSkew = 0
CrtcVDisplay = 1024
CrtcVBlankStart = 1024
CrtcVSyncStart = 1025
CrtcVSyncEnd = 1028
CrtcVBlankEnd = 1066
CrtcVTotal = 1066
CrtcHAdjusted = 0
CrtcVAdjusted = 0
PrivSize = 0
Private = (nil)
PrivFlags = 0
HSync = 0.0
VRefresh = 75.02467
}
desiredRotation = 1U
desiredX = 0
desiredY = 0
funcs = 0xffffffff7af6b8c0
driver_private = 0x10085aa90
randr_crtc = (nil)
cursor_argb = 0
cursor_in_range = 1
cursor_shown = 0
crtc_to_framebuffer = {
matrix = (
(65536, 0, 0)
(0, 65536, 0)
(0, 0, 65536)
)
}
f_crtc_to_framebuffer = {
m = (
(1.0, 0.0, 0.0)
(0.0, 1.0, 0.0)
(0.0, 0.0, 1.0)
)
}
f_framebuffer_to_crtc = {
m = (
(1.0, 0.0, 0.0)
(0.0, 1.0, 0.0)
(0.0, 0.0, 1.0)
)
}
filter = (nil)
params = (nil)
nparams = 0
filter_width = 0
filter_height = 0
transform_in_use = 0
transform = {
transform = {
matrix = (
(0, 0, 0)
(0, 0, 0)
(0, 0, 0)
)
}
f_transform = {
m = (
(0.0, 0.0, 0.0)
(0.0, 0.0, 0.0)
(0.0, 0.0, 0.0)
)
}
f_inverse = {
m = (
(0.0, 0.0, 0.0)
(0.0, 0.0, 0.0)
(0.0, 0.0, 0.0)
)
}
filter = (nil)
params = (nil)
nparams = 0
width = 0
height = 0
}
transformPresent = 0
desiredTransform = {
transform = {
matrix = (
(0, 0, 0)
(0, 0, 0)
(0, 0, 0)
)
}
f_transform = {
m = (
(0.0, 0.0, 0.0)
(0.0, 0.0, 0.0)
(0.0, 0.0, 0.0)
)
}
f_inverse = {
m = (
(0.0, 0.0, 0.0)
(0.0, 0.0, 0.0)
(0.0, 0.0, 0.0)
)
}
filter = (nil)
params = (nil)
nparams = 0
width = 0
height = 0
}
desiredTransformPresent = 0
bounds = {
x1 = 0
y1 = 0
x2 = 1280
y2 = 1024
}
panningTotalArea = {
x1 = 0
y1 = 0
x2 = 0
y2 = 0
}
panningTrackingArea = {
x1 = 0
y1 = 0
x2 = 0
y2 = 0
}
panningBorder = (0, 0, 0, 0)
gamma_red = 0x10085a480
gamma_green = 0x10085a680
gamma_blue = 0x10085a880
gamma_size = 256
active = 1
shadowClear = 0
}
(dbx) print *config->output[config->compat_output]->crtc->funcs
*config->output[config->compat_output]->crtc->funcs = {
dpms = 0xffffffff7ae3b908 =
&`efb_drv.so`radeon_crtc.c`radeon_crtc_dpms()
save = (nil)
restore = (nil)
lock = 0xffffffff7ae3cce4 =
&`efb_drv.so`radeon_crtc.c`radeon_crtc_lock()
unlock = 0xffffffff7ae3cd28 =
&`efb_drv.so`radeon_crtc.c`radeon_crtc_unlock()
mode_fixup = 0xffffffff7ae3ba00 =
&`efb_drv.so`radeon_crtc.c`radeon_crtc_mode_fixup()
prepare = 0xffffffff7ae3ba20 =
&`efb_drv.so`radeon_crtc.c`radeon_crtc_mode_prepare()
mode_set = 0xffffffff7ae3c000 =
&`efb_drv.so`radeon_crtc.c`radeon_crtc_mode_set()
commit = 0xffffffff7ae3c058 =
&`efb_drv.so`radeon_crtc.c`radeon_crtc_mode_commit()
gamma_set = 0xffffffff7ae3c518 =
&`efb_drv.so`radeon_crtc.c`radeon_crtc_gamma_set()
shadow_allocate = 0xffffffff7ae3cdf0 =
&`efb_drv.so`radeon_crtc.c`radeon_crtc_shadow_allocate()
shadow_create = 0xffffffff7ae3cfb8 =
&`efb_drv.so`radeon_crtc.c`radeon_crtc_shadow_create()
shadow_destroy = 0xffffffff7ae3d070 =
&`efb_drv.so`radeon_crtc.c`radeon_crtc_shadow_destroy()
set_cursor_colors = 0xffffffff7ae1919c = &radeon_crtc_set_cursor_colors()
set_cursor_position = 0xffffffff7ae18fac = &radeon_crtc_set_cursor_position()
show_cursor = 0xffffffff7ae18e6c = &radeon_crtc_show_cursor()
hide_cursor = 0xffffffff7ae18f10 = &radeon_crtc_hide_cursor()
load_cursor_image = (nil)
load_cursor_argb = 0xffffffff7ae19304 = &radeon_crtc_load_cursor_argb()
destroy = (nil)
set_mode_major = (nil)
set_origin = (nil)
}
I was only able to reproduce on a configuration with two cards running in
Xinerama mode. Could this be another instance of RandR & Xinerama not
playing nicely together?
>> @@ -1077,7 +1079,8 @@ xf86GetGammaRampSize(ScreenPtr pScreen)
>> xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
>> RRCrtcPtr crtc = config->output[config->compat_output]->crtc->randr_crtc;
>>
>> - return crtc->gammaSize;
>> + if (crtc)
>> + return crtc->gammaSize;
>
> Uh, what's the return value if you don't have a crtc?
In that case it would fall throw to the code that handles the
cases when xf86_crtc_supports_gamma(pScrn) returns false.
--
-Alan Coopersmith- alan.coopersmith at sun.com
Sun Microsystems, Inc. - X Window System Engineering
More information about the xorg-devel
mailing list