mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-06-06 22:18:24 +02:00
Merge branch 'wip/zdi-fixes-server-21.1-branch' into 'server-21.1-branch'
[server 21.1] Backport the latest batch of security issues See merge request xorg/xserver!2229
This commit is contained in:
commit
56febfe786
9 changed files with 122 additions and 62 deletions
|
|
@ -348,6 +348,9 @@ ScreenSaverFreeAttr(void *value, XID id)
|
|||
dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive);
|
||||
}
|
||||
CheckScreenPrivate(pScreen);
|
||||
/* CheckScreenPrivate may have freed pPriv (same pattern as
|
||||
* CreateSaverWindow fix for ZDI-CAN-30168). */
|
||||
pPriv = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -479,6 +482,8 @@ CreateSaverWindow(ScreenPtr pScreen)
|
|||
UninstallSaverColormap(pScreen);
|
||||
pPriv->hasWindow = FALSE;
|
||||
CheckScreenPrivate(pScreen);
|
||||
/* Re-fetch pPriv since CheckScreenPrivate may have freed it */
|
||||
pPriv = GetScreenPrivate(pScreen);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
55
Xext/sync.c
55
Xext/sync.c
|
|
@ -720,8 +720,29 @@ SyncChangeCounter(SyncCounter * pCounter, int64_t newval)
|
|||
/* run through triggers to see if any become true */
|
||||
for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) {
|
||||
pnext = ptl->next;
|
||||
if ((*ptl->pTrigger->CheckTrigger) (ptl->pTrigger, oldval))
|
||||
if ((*ptl->pTrigger->CheckTrigger) (ptl->pTrigger, oldval)) {
|
||||
(*ptl->pTrigger->TriggerFired) (ptl->pTrigger);
|
||||
/* TriggerFired may have called SyncDeleteTriggerFromSyncObject
|
||||
* for sibling triggers in the same Await group, freeing their
|
||||
* trigger list nodes - potentially including pnext. Verify
|
||||
* pnext is still on the counter's trigger list; if not,
|
||||
* restart from the list head.
|
||||
*
|
||||
* Unlike miSyncTriggerFence() we cannot use a do/while
|
||||
* restart loop here: counter trigger lists may contain alarm
|
||||
* triggers which are not removed after firing and would cause
|
||||
* an infinite loop when delta is 0.
|
||||
*/
|
||||
if (pnext) {
|
||||
SyncTriggerList *tmp;
|
||||
for (tmp = pCounter->sync.pTriglist; tmp; tmp = tmp->next) {
|
||||
if (tmp == pnext)
|
||||
break;
|
||||
}
|
||||
if (!tmp)
|
||||
pnext = pCounter->sync.pTriglist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsSystemCounter(pCounter)) {
|
||||
|
|
@ -1162,9 +1183,12 @@ FreeCounter(void *env, XID id)
|
|||
SyncTriggerList *ptl, *pnext;
|
||||
|
||||
/* tell all the counter's triggers that counter has been destroyed */
|
||||
for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) {
|
||||
(*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);
|
||||
pnext = ptl->next;
|
||||
nt_list_for_each_entry_safe(ptl, pnext, pCounter->sync.pTriglist, next) {
|
||||
/* Remove it from the list first so CounterDestroyed
|
||||
* callbacks have a valid list to iterate */
|
||||
pCounter->sync.pTriglist = pnext;
|
||||
if (ptl->pTrigger)
|
||||
(*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);
|
||||
free(ptl); /* destroy the trigger list as we go */
|
||||
}
|
||||
if (IsSystemCounter(pCounter)) {
|
||||
|
|
@ -1196,13 +1220,28 @@ FreeAwait(void *addr, XID id)
|
|||
|
||||
for (numwaits = pAwaitUnion->header.num_waitconditions; numwaits;
|
||||
numwaits--, pAwait++) {
|
||||
/* If the counter is being destroyed, FreeCounter will delete
|
||||
* the trigger list itself, so don't do it here.
|
||||
/* If the counter is being destroyed, FreeCounter/miSyncDestroyFence
|
||||
* will delete the trigger list itself, so don't do it here.
|
||||
* However, we must NULL out the pTrigger pointer in the trigger list
|
||||
* node so the destroy loop knows not to dereference it - the backing
|
||||
* SyncAwait memory is about to be freed below.
|
||||
*/
|
||||
SyncObject *pSync = pAwait->trigger.pSync;
|
||||
|
||||
if (pSync && !pSync->beingDestroyed)
|
||||
SyncDeleteTriggerFromSyncObject(&pAwait->trigger);
|
||||
if (pSync) {
|
||||
if (!pSync->beingDestroyed) {
|
||||
SyncDeleteTriggerFromSyncObject(&pAwait->trigger);
|
||||
} else {
|
||||
SyncTriggerList *ptl;
|
||||
|
||||
nt_list_for_each_entry(ptl, pSync->pTriglist, next) {
|
||||
if (ptl->pTrigger == &pAwait->trigger) {
|
||||
ptl->pTrigger = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(pAwaitUnion);
|
||||
return Success;
|
||||
|
|
|
|||
|
|
@ -670,6 +670,10 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
|
|||
* is BadFontName, indicating the alias resolution
|
||||
* is complete.
|
||||
*/
|
||||
if (resolvedlen > XLFDMAXFONTNAMELEN) {
|
||||
err = BadFontName;
|
||||
goto ContBadFontName;
|
||||
}
|
||||
memmove(tmp_pattern, resolved, resolvedlen);
|
||||
if (c->haveSaved) {
|
||||
char *tmpname;
|
||||
|
|
@ -932,6 +936,10 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
|
|||
memcpy(c->savedName, name, namelen + 1);
|
||||
aliascount = 20;
|
||||
}
|
||||
if (namelen > XLFDMAXFONTNAMELEN) {
|
||||
err = BadFontName;
|
||||
goto ContBadFontName;
|
||||
}
|
||||
memmove(c->current.pattern, name, namelen);
|
||||
c->current.patlen = namelen;
|
||||
c->current.max_names = 1;
|
||||
|
|
|
|||
|
|
@ -1144,8 +1144,7 @@ __glXDisp_GetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc)
|
|||
ClientPtr client = cl->client;
|
||||
xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
|
||||
|
||||
/* work around mesa bug, don't use REQUEST_SIZE_MATCH */
|
||||
REQUEST_AT_LEAST_SIZE(xGLXGetFBConfigsSGIXReq);
|
||||
REQUEST_SIZE_MATCH(xGLXGetFBConfigsSGIXReq);
|
||||
return DoGetFBConfigs(cl, req->screen);
|
||||
}
|
||||
|
||||
|
|
@ -1366,9 +1365,7 @@ __glXDisp_DestroyPixmap(__GLXclientState * cl, GLbyte * pc)
|
|||
ClientPtr client = cl->client;
|
||||
xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
|
||||
|
||||
/* should be REQUEST_SIZE_MATCH, but mesa's glXDestroyPixmap used to set
|
||||
* length to 3 instead of 2 */
|
||||
REQUEST_AT_LEAST_SIZE(xGLXDestroyPixmapReq);
|
||||
REQUEST_SIZE_MATCH(xGLXDestroyPixmapReq);
|
||||
|
||||
return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
|
||||
}
|
||||
|
|
@ -1524,14 +1521,8 @@ __glXDisp_ChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
|
|||
client->errorValue = req->numAttribs;
|
||||
return BadValue;
|
||||
}
|
||||
#if 0
|
||||
/* mesa sends an additional 8 bytes */
|
||||
|
||||
REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3);
|
||||
#else
|
||||
if (((sizeof(xGLXChangeDrawableAttributesReq) +
|
||||
(req->numAttribs << 3)) >> 2) < client->req_len)
|
||||
return BadLength;
|
||||
#endif
|
||||
|
||||
return DoChangeDrawableAttributes(cl->client, req->drawable,
|
||||
req->numAttribs, (CARD32 *) (req + 1));
|
||||
|
|
@ -1598,8 +1589,7 @@ __glXDisp_DestroyWindow(__GLXclientState * cl, GLbyte * pc)
|
|||
ClientPtr client = cl->client;
|
||||
xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
|
||||
|
||||
/* mesa's glXDestroyWindow used to set length to 3 instead of 2 */
|
||||
REQUEST_AT_LEAST_SIZE(xGLXDestroyWindowReq);
|
||||
REQUEST_SIZE_MATCH(xGLXDestroyWindowReq);
|
||||
|
||||
return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW);
|
||||
}
|
||||
|
|
@ -1960,8 +1950,7 @@ __glXDisp_GetDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
|
|||
ClientPtr client = cl->client;
|
||||
xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *) pc;
|
||||
|
||||
/* this should be REQUEST_SIZE_MATCH, but mesa sends an additional 4 bytes */
|
||||
REQUEST_AT_LEAST_SIZE(xGLXGetDrawableAttributesReq);
|
||||
REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesReq);
|
||||
|
||||
return DoGetDrawableAttributes(cl, req->drawable);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ __glXDispSwap_GetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc)
|
|||
|
||||
__GLX_DECLARE_SWAP_VARIABLES;
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xGLXGetFBConfigsSGIXReq);
|
||||
REQUEST_SIZE_MATCH(xGLXGetFBConfigsSGIXReq);
|
||||
|
||||
__GLX_SWAP_INT(&req->screen);
|
||||
return __glXDisp_GetFBConfigsSGIX(cl, pc);
|
||||
|
|
@ -327,7 +327,7 @@ __glXDispSwap_DestroyPixmap(__GLXclientState * cl, GLbyte * pc)
|
|||
|
||||
__GLX_DECLARE_SWAP_VARIABLES;
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xGLXDestroyGLXPixmapReq);
|
||||
REQUEST_SIZE_MATCH(xGLXDestroyGLXPixmapReq);
|
||||
|
||||
__GLX_SWAP_SHORT(&req->length);
|
||||
__GLX_SWAP_INT(&req->glxpixmap);
|
||||
|
|
@ -440,9 +440,7 @@ __glXDispSwap_ChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
|
|||
client->errorValue = req->numAttribs;
|
||||
return BadValue;
|
||||
}
|
||||
if (((sizeof(xGLXChangeDrawableAttributesReq) +
|
||||
(req->numAttribs << 3)) >> 2) < client->req_len)
|
||||
return BadLength;
|
||||
REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3);
|
||||
|
||||
attribs = (CARD32 *) (req + 1);
|
||||
__GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1);
|
||||
|
|
@ -514,7 +512,7 @@ __glXDispSwap_DestroyWindow(__GLXclientState * cl, GLbyte * pc)
|
|||
|
||||
__GLX_DECLARE_SWAP_VARIABLES;
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xGLXDestroyWindowReq);
|
||||
REQUEST_SIZE_MATCH(xGLXDestroyWindowReq);
|
||||
|
||||
__GLX_SWAP_INT(&req->glxwindow);
|
||||
|
||||
|
|
@ -723,7 +721,7 @@ __glXDispSwap_GetDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
|
|||
|
||||
__GLX_DECLARE_SWAP_VARIABLES;
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xGLXGetDrawableAttributesReq);
|
||||
REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesReq);
|
||||
|
||||
__GLX_SWAP_SHORT(&req->length);
|
||||
__GLX_SWAP_INT(&req->drawable);
|
||||
|
|
|
|||
|
|
@ -563,15 +563,16 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
|
|||
DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
|
||||
DRI2ScreenPtr ds;
|
||||
DRI2BufferPtr *buffers;
|
||||
int need_real_front = 0;
|
||||
int need_fake_front = 0;
|
||||
int have_fake_front = 0;
|
||||
unsigned attachments_bitset = 0;
|
||||
Bool need_real_front = FALSE;
|
||||
Bool need_fake_front = FALSE;
|
||||
int front_format = 0;
|
||||
int dimensions_match;
|
||||
int buffers_changed = 0;
|
||||
int i;
|
||||
|
||||
if (!pPriv) {
|
||||
if (!pPriv ||
|
||||
count > DRI2BufferHiz + 1) {
|
||||
*width = pDraw->width;
|
||||
*height = pDraw->height;
|
||||
*out_count = 0;
|
||||
|
|
@ -583,7 +584,10 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
|
|||
dimensions_match = (pDraw->width == pPriv->width)
|
||||
&& (pDraw->height == pPriv->height);
|
||||
|
||||
buffers = calloc((count + 1), sizeof(buffers[0]));
|
||||
/* Since we deduplicate attachments in the buffers array, there cannot be
|
||||
* more entries than there are attachments.
|
||||
*/
|
||||
buffers = calloc((min(count, DRI2BufferHiz) + 1), sizeof(buffers[0]));
|
||||
if (!buffers)
|
||||
goto err_out;
|
||||
|
||||
|
|
@ -591,6 +595,14 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
|
|||
const unsigned attachment = *(attachments++);
|
||||
const unsigned format = (has_format) ? *(attachments++) : 0;
|
||||
|
||||
if (attachment > DRI2BufferHiz)
|
||||
goto err_out;
|
||||
|
||||
if (attachments_bitset & (1u << attachment))
|
||||
continue;
|
||||
|
||||
attachments_bitset |= 1u << attachment;
|
||||
|
||||
if (allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment,
|
||||
format, dimensions_match, &buffers[i]))
|
||||
buffers_changed = 1;
|
||||
|
|
@ -598,34 +610,27 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
|
|||
if (buffers[i] == NULL)
|
||||
goto err_out;
|
||||
|
||||
/* If the drawable is a window and the front-buffer is requested,
|
||||
* silently add the fake front-buffer to the list of requested
|
||||
* attachments. The counting logic in the loop accounts for the case
|
||||
* where the client requests both the fake and real front-buffer.
|
||||
/* In certain cases the (fake) front buffer is always needed, so return
|
||||
* it even if the client failed to request it.
|
||||
* The logic in & after the loop accounts for the case where the client
|
||||
* does request the (fake) front buffer, to avoid returning it multiple
|
||||
* times.
|
||||
*/
|
||||
if (attachment == DRI2BufferBackLeft) {
|
||||
need_real_front++;
|
||||
need_real_front = TRUE;
|
||||
front_format = format;
|
||||
}
|
||||
|
||||
if (attachment == DRI2BufferFrontLeft) {
|
||||
need_real_front--;
|
||||
front_format = format;
|
||||
|
||||
if (pDraw->type == DRAWABLE_WINDOW) {
|
||||
need_fake_front++;
|
||||
}
|
||||
}
|
||||
|
||||
if (pDraw->type == DRAWABLE_WINDOW) {
|
||||
if (attachment == DRI2BufferFakeFrontLeft) {
|
||||
need_fake_front--;
|
||||
have_fake_front = 1;
|
||||
}
|
||||
if (pDraw->type == DRAWABLE_WINDOW)
|
||||
need_fake_front = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_real_front > 0) {
|
||||
if (need_real_front &&
|
||||
!(attachments_bitset & (1u << DRI2BufferFrontLeft))) {
|
||||
if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFrontLeft,
|
||||
front_format, dimensions_match,
|
||||
&buffers[i]))
|
||||
|
|
@ -636,7 +641,8 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
|
|||
i++;
|
||||
}
|
||||
|
||||
if (need_fake_front > 0) {
|
||||
if (need_fake_front &&
|
||||
!(attachments_bitset & (1u << DRI2BufferFakeFrontLeft))) {
|
||||
if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFakeFrontLeft,
|
||||
front_format, dimensions_match,
|
||||
&buffers[i]))
|
||||
|
|
@ -646,7 +652,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
|
|||
goto err_out;
|
||||
|
||||
i++;
|
||||
have_fake_front = 1;
|
||||
attachments_bitset |= 1u << DRI2BufferFakeFrontLeft;
|
||||
}
|
||||
|
||||
*out_count = i;
|
||||
|
|
@ -658,7 +664,8 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
|
|||
* contents of the real front-buffer. This ensures correct operation of
|
||||
* applications that call glXWaitX before calling glDrawBuffer.
|
||||
*/
|
||||
if (have_fake_front && buffers_changed) {
|
||||
if (buffers_changed &&
|
||||
(attachments_bitset & (1u << DRI2BufferFakeFrontLeft))) {
|
||||
BoxRec box;
|
||||
RegionRec region;
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,12 @@ typedef struct _OFclosure {
|
|||
|
||||
/* ListFontsWithInfo */
|
||||
|
||||
#define XLFDMAXFONTNAMELEN 256
|
||||
/* libXfont2 allows font names/aliases up to MAXFONTNAMELEN (1024) bytes in
|
||||
* fonts.alias files. The server's pattern buffers must be large enough to
|
||||
* hold resolved alias targets returned by the font library.
|
||||
* ZDI-CAN-30136
|
||||
*/
|
||||
#define XLFDMAXFONTNAMELEN 1024
|
||||
typedef struct _LFWIstate {
|
||||
char pattern[XLFDMAXFONTNAMELEN];
|
||||
int patlen;
|
||||
|
|
|
|||
|
|
@ -115,10 +115,14 @@ miSyncDestroyFence(SyncFence * pFence)
|
|||
SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
|
||||
SyncTriggerList *ptl, *pNext;
|
||||
|
||||
/* tell all the fence's triggers that the counter has been destroyed */
|
||||
for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) {
|
||||
(*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);
|
||||
pNext = ptl->next;
|
||||
/* tell all the fence's triggers that the fence has been destroyed.
|
||||
* Update pTriglist before each callback and free so that FreeAwait
|
||||
* sees a valid list head when scanning for triggers to NULL out.
|
||||
*/
|
||||
nt_list_for_each_entry_safe(ptl, pNext, pFence->sync.pTriglist, next) {
|
||||
pFence->sync.pTriglist = pNext;
|
||||
if (ptl->pTrigger)
|
||||
(*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);
|
||||
free(ptl); /* destroy the trigger list as we go */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1617,6 +1617,11 @@ CheckKeyTypes(ClientPtr client,
|
|||
*nMapsRtrn = _XkbErrCode4(0x02, req->firstType, req->nTypes, 4);
|
||||
return 0;
|
||||
}
|
||||
if (nMaps > XkbMaxLegalKeyCode + 1) {
|
||||
*nMapsRtrn = _XkbErrCode4(0x02, req->firstType, req->nTypes,
|
||||
XkbMaxLegalKeyCode + 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (req->present & XkbKeyTypesMask) {
|
||||
nMaps = xkb->map->num_types;
|
||||
|
|
@ -1648,7 +1653,7 @@ CheckKeyTypes(ClientPtr client,
|
|||
}
|
||||
n = i + req->firstType;
|
||||
width = wire->numLevels;
|
||||
if (width < 1) {
|
||||
if (width < 1 || width > XkbMaxShiftLevel) {
|
||||
*nMapsRtrn = _XkbErrCode3(0x04, n, width);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue