(master) randr: free/terminate resource structs on AddResource() OOM failure#3273
(master) randr: free/terminate resource structs on AddResource() OOM failure#3273metux wants to merge 1 commit into
Conversation
Five constructors in Xext/randr/ leaked or permanently pinned their struct
when AddResource()'s internal calloc() failed (memory pressure):
- ProcRRCreateLease() (rrlease.c): links 'lease' into scr_priv->leases
*before* AddResource(). RRLeaseDestroyResource() (the delete callback
AddResource() invokes on a successfully-*started*-but-failed
registration) only clears lease->id -- it doesn't unlink or free the
lease. Without terminating it explicitly, the lease stays on
scr_priv->leases forever, permanently marking its outputs/crtcs as leased
(RROutputIsLeased()/RRCrtcIsLeased()) with no XID for the client to ever
free it by. Fixed by calling RRTerminateLease(lease), mirroring the
WriteFdToClient() failure branch a few lines below, which already does
this correctly.
- RRModeGet() (rrmode.c), RRCrtcCreate() (rrcrtc.c), RROutputCreate()
(rroutput.c), RRProviderCreate() (rrprovider.c): all four 'return NULL'
directly on AddResource() failure without freeing the struct they just
calloc'd. None of the four are linked into their owning screen-private
array/field yet at that point (verified: each is only stored into
pScrPriv->{modes,crtcs,outputs,provider} a few lines *after* the
AddResource() check), so a plain free() is safe. rrmode.c already freed
its secondary 'newModes' array allocation on this path but forgot 'mode'
itself.
All five are narrow (OOM-gated) but real leaks/dangling-reference bugs, not
crashes -- bundled as one fix since they're the same missing-cleanup shape
in the same subsystem.
Found via a fleet-directed alloc-fail/UAF sweep of Xext/, not from a live
crash report.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Independent review — verdict: changes requested (blocking)Reviewed from scratch against Root cause: what
|
Five constructors in Xext/randr/ leaked or permanently pinned their struct
when AddResource()'s internal calloc() failed (memory pressure):
ProcRRCreateLease() (rrlease.c): links 'lease' into scr_priv->leases
before AddResource(). RRLeaseDestroyResource() (the delete callback
AddResource() invokes on a successfully-started-but-failed
registration) only clears lease->id -- it doesn't unlink or free the
lease. Without terminating it explicitly, the lease stays on
scr_priv->leases forever, permanently marking its outputs/crtcs as leased
(RROutputIsLeased()/RRCrtcIsLeased()) with no XID for the client to ever
free it by. Fixed by calling RRTerminateLease(lease), mirroring the
WriteFdToClient() failure branch a few lines below, which already does
this correctly.
RRModeGet() (rrmode.c), RRCrtcCreate() (rrcrtc.c), RROutputCreate()
(rroutput.c), RRProviderCreate() (rrprovider.c): all four 'return NULL'
directly on AddResource() failure without freeing the struct they just
calloc'd. None of the four are linked into their owning screen-private
array/field yet at that point (verified: each is only stored into
pScrPriv->{modes,crtcs,outputs,provider} a few lines after the
AddResource() check), so a plain free() is safe. rrmode.c already freed
its secondary 'newModes' array allocation on this path but forgot 'mode'
itself.
All five are narrow (OOM-gated) but real leaks/dangling-reference bugs, not
crashes -- bundled as one fix since they're the same missing-cleanup shape
in the same subsystem.
Found via a fleet-directed alloc-fail/UAF sweep of Xext/, not from a live
crash report.
Signed-off-by: Enrico Weigelt, metux IT consult info@metux.net