[PATCH] libXinerama: Set number to 0 on error.
The documentation of XineramaQueryScreens states that number is always set to the amount of screens in the returned array, but if the communication with the X server fails, NULL is returned without modifying number. At least dwm relies on the fact that number is set to 0 on error, i.e. when NULL is returned. As a NULL pointer contains 0 elements and the documentation states that number contains the amount of elements of the returned array, I think this should be fixed inside libXinerama. --- src/Xinerama.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Xinerama.c b/src/Xinerama.c index 8472ec5..ee1f630 100644 --- a/src/Xinerama.c +++ b/src/Xinerama.c @@ -286,6 +286,7 @@ XineramaQueryScreens( if (!_XReply (dpy, (xReply *) , 0, xFalse)) { UnlockDisplay (dpy); SyncHandle (); + *number = 0; return NULL; } -- 2.11.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH] libXinerama: Set number to 0 on error.
On Mon, Jan 23, 2017 at 11:52:13AM -0500, Adam Jackson wrote: > Not that any caller has likely made this mistake, but you want an if > (number) before this, otherwise you turn a protocol error into a > segfault. If a caller supplies NULL, a segfault would always occur because the pointer is never checked for NULL. Tobias ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH] xinit: check for correct fork error code
Even though this code is only active on __sun machines, the fork return value should be checked for -1, not 1, to detect an error situation. --- xinit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xinit.c b/xinit.c index 1b04911..f826b7a 100644 --- a/xinit.c +++ b/xinit.c @@ -638,7 +638,7 @@ shutdown(void) Fatal("Unable to run program \"%s\"", "kbd_mode"); break; -case 1: +case -1: Error("fork failed"); break; -- 2.11.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH libXrandr] Avoid out of boundary accesses on illegal responses
Hi Julien, On Sat, Jan 07, 2017 at 07:03:17PM +0100, Julien Cristau wrote: > It looks like we're leaking 'attr' on these error paths? confirmed. That is what I get for copying the error handling of the attr == NULL case... diff --git a/src/XrrCrtc.c b/src/XrrCrtc.c index 6665092..8316b78 100644 --- a/src/XrrCrtc.c +++ b/src/XrrCrtc.c @@ -459,6 +459,7 @@ XRRGetCrtcTransform (Display*dpy, e = extra; if (e + rep.pendingNbytesFilter > end) { + XFree (attr); XFree (extra); return False; } @@ -468,6 +469,7 @@ XRRGetCrtcTransform (Display*dpy, for (p = 0; p < rep.pendingNparamsFilter; p++) { INT32 f; if (e + 4 > end) { + XFree (attr); XFree (extra); return False; } @@ -478,6 +480,7 @@ XRRGetCrtcTransform (Display*dpy, attr->pendingNparams = rep.pendingNparamsFilter; if (e + rep.currentNbytesFilter > end) { + XFree (attr); XFree (extra); return False; } @@ -487,6 +490,7 @@ XRRGetCrtcTransform (Display*dpy, for (p = 0; p < rep.currentNparamsFilter; p++) { INT32 f; if (e + 4 > end) { + XFree (attr); XFree (extra); return False; } ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver] Fix OOB access in ProcRecordUnregisterClients
If a client sends a RecordUnregisterClients request with an nClients field larger than INT_MAX / 4, an integer overflow leads to an out of boundary access in RecordSanityCheckClientSpecifiers. An example line with libXtst would be: XRecordUnregisterClients(dpy, rc, clients, 0x4001); --- record/record.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/record/record.c b/record/record.c index 3e8b497e7..fdcee7e00 100644 --- a/record/record.c +++ b/record/record.c @@ -1910,7 +1910,8 @@ ProcRecordUnregisterClients(ClientPtr client) int i; REQUEST_AT_LEAST_SIZE(xRecordUnregisterClientsReq); -if ((client->req_len << 2) - SIZEOF(xRecordUnregisterClientsReq) != +if (INT_MAX / 4 < stuff->nClients || +(client->req_len << 2) - SIZEOF(xRecordUnregisterClientsReq) != 4 * stuff->nClients) return BadLength; VERIFY_CONTEXT(pContext, stuff->context, client); -- 2.12.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH] dmx: Fix null pointer dereference
A null pointer dereference can occur in dmxSync, because TimerForce does not handle a null pointer. dmxSyncTimer is set to NULL a few lines above on a certain condition, which happened on my machine. The explicit NULL check allowed me to start Xdmx again without a segmentation fault. --- hw/dmx/dmxsync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/dmx/dmxsync.c b/hw/dmx/dmxsync.c index 1bc242343..b55c9ddf3 100644 --- a/hw/dmx/dmxsync.c +++ b/hw/dmx/dmxsync.c @@ -182,7 +182,7 @@ dmxSync(DMXScreenInfo * dmxScreen, Bool now) /* Do sync or set time for later */ if (now || !dmxScreen) { -if (!TimerForce(dmxSyncTimer)) +if (dmxSyncTimer == NULL || !TimerForce(dmxSyncTimer)) dmxSyncCallback(NULL, 0, NULL); /* At this point, dmxSyncPending == 0 because * dmxSyncCallback must have been called. */ -- 2.12.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH] dmx: Fix null pointer dereference
On Sun, Mar 12, 2017 at 03:47:50PM +0100, walter harms wrote: > why not patch TimerForce() and solve the problem for once and any one ? I didn't do it because I am not sure about the implied consequences of simply accepting NULL. Maybe it's not meant to be used that way. But here's the alternative possibility. --- os/WaitFor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os/WaitFor.c b/os/WaitFor.c index 613608faf..ab5f8a3b8 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -261,7 +261,7 @@ AdjustWaitForDelay(void *waitTime, int newdelay) } static inline Bool timer_pending(OsTimerPtr timer) { -return !xorg_list_is_empty(>list); +return timer != NULL && !xorg_list_is_empty(>list); } /* If time has rewound, re-run every affected timer. -- 2.12.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH] render: Fix out of boundary heap access
ProcRenderCreateRadialGradient and ProcRenderCreateConicalGradient must be protected against an integer overflow during length check. This is already included in ProcRenderCreateLinearGradient since the fix for CVE-2008-2362. This can only be successfully exploited on a 32 bit system for an out of boundary read later on. Validated by using ASAN. --- render/render.c | 4 1 file changed, 4 insertions(+) diff --git a/render/render.c b/render/render.c index 8dc1f3425..ccae49a41 100644 --- a/render/render.c +++ b/render/render.c @@ -1908,6 +1908,8 @@ ProcRenderCreateRadialGradient(ClientPtr client) LEGAL_NEW_RESOURCE(stuff->pid, client); len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); +if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) +return BadLength; if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) return BadLength; @@ -1946,6 +1948,8 @@ ProcRenderCreateConicalGradient(ClientPtr client) LEGAL_NEW_RESOURCE(stuff->pid, client); len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); +if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) +return BadLength; if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) return BadLength; -- 2.12.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXaw] NULL pointer dereference in XawAsciiSinkInitialize
The function XawAsciiSinkInitialize is prone to a NULL pointer dereference if no font is available. Even though a specific check for a NULL font exists, it is called after GetGC(), which in turn would trigger the NPE in such a case. Spotted by calling xmessage on a system with an incomplete x font setup: $ xmessage -b text Warning: Unable to load any usable ISO8859 font Segmentation fault $ _ Signed-off-by: Tobias Stoeckmann <tob...@stoeckmann.org> --- src/AsciiSink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AsciiSink.c b/src/AsciiSink.c index d776895..1cccb1c 100644 --- a/src/AsciiSink.c +++ b/src/AsciiSink.c @@ -1704,10 +1704,10 @@ XawAsciiSinkInitialize(Widget request, Widget cnew, { AsciiSinkObject sink = (AsciiSinkObject)cnew; -GetGC(sink); - if (!sink->ascii_sink.font) XtError("Aborting: no font found\n"); +GetGC(sink); + sink->ascii_sink.cursor_position = 0; sink->ascii_sink.laststate = XawisOff; sink->ascii_sink.cursor_x = sink->ascii_sink.cursor_y = 0; -- 2.12.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXau] Avoid out of boundary read access
If the environment variable HOME is empty, XauFileName triggers an out of boundary read access (name[1]). If HOME consists of a single character relative path, the output becomes unexpected, because "HOME=a" leads to "a.Xauthority" instead of "a/.Xauthority". Granted, a relative HOME path leads to trouble in general, the code should properly return "a/.Xauthority" nonetheless. Signed-off-by: Tobias Stoeckmann <tob...@stoeckmann.org> --- AuFileName.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AuFileName.c b/AuFileName.c index 37c8b62..2946c80 100644 --- a/AuFileName.c +++ b/AuFileName.c @@ -85,6 +85,6 @@ XauFileName (void) bsize = size; } snprintf (buf, bsize, "%s%s", name, - slashDotXauthority + (name[1] == '\0' ? 1 : 0)); + slashDotXauthority + (name[0] == '/' && name[1] == '\0' ? 1 : 0)); return buf; } -- 2.14.2 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH font-util] ucs2any: Fix parser crash on 32 bit
It is possible to crash ucs2any or provoke successful return value even though the processing was not successful. The problem lies within a possible integer overflow when adding elements with a key which is too large. You can trigger the issue this way on a 32 bit system: $ cat > source.bdf << "EOF" STARTFONT source CHARS 1 ENCODING 1073741823 EOF $ ucs2any source.bdf Segmentation fault $ _ Another possibility would be to add "ENCODING 1" right after the CHARS line. In that case, realloc will allocate 0 bytes afterwards which is a success but might return NULL, e.g. on Linux/glibc systems. Such a result value is handled as an error and errno is evaluated and returned, even though there was no error: $ cat > source.bdf << "EOF" STARTFONT source CHARS 1 ENCODING 1 ENCODING 1073741823 EOF $ ucs2any source.bdf ucs2any: Success $ echo $? 0 $ _ Signed-off-by: Tobias Stoeckmann <tob...@stoeckmann.org> --- ucs2any.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/ucs2any.c b/ucs2any.c index 10bb029..1f575d1 100644 --- a/ucs2any.c +++ b/ucs2any.c @@ -45,6 +45,7 @@ #endif #include #include +#include #include #include #include @@ -220,6 +221,11 @@ da_add(da_t *da, int key, void *value) { int i = da->size; if (key >= 0) { + if ((size_t)key >= SIZE_MAX / sizeof(void *)) { + fprintf(stderr, "%s: Illegal key '%d' encountered!\n", + my_name, key); + exit(1); + } if (key >= da->size) { da->size = key + 1; da->values = zrealloc(da->values, -- 2.15.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libICE] Always terminate strncpy results.
The function strncpy does not guarantee to append a terminating NUL character to the destination. This patch merges libSM's way of handling this issue into libICE. Signed-off-by: Tobias Stoeckmann --- src/connect.c| 66 +++- src/listen.c | 24 +- src/listenwk.c | 24 +- src/protosetup.c | 37 +++ 4 files changed, 110 insertions(+), 41 deletions(-) diff --git a/src/connect.c b/src/connect.c index 086b7f3..1554ad6 100644 --- a/src/connect.c +++ b/src/connect.c @@ -66,8 +66,11 @@ IceOpenConnection ( if (networkIdsList == NULL || *networkIdsList == '\0') { - strncpy (errorStringRet, - "networkIdsList argument is NULL", errorLength); + if (errorStringRet && errorLength > 0) { + strncpy (errorStringRet, + "networkIdsList argument is NULL", errorLength); + errorStringRet[errorLength - 1] = '\0'; + } return (NULL); } @@ -144,7 +147,10 @@ IceOpenConnection ( if ((iceConn = malloc (sizeof (struct _IceConn))) == NULL) { - strncpy (errorStringRet, "Can't malloc", errorLength); + if (errorStringRet && errorLength > 0) { + strncpy (errorStringRet, "Can't malloc", errorLength); + errorStringRet[errorLength - 1] = '\0'; + } return (NULL); } @@ -157,7 +163,10 @@ IceOpenConnection ( >connection_string)) == NULL) { free (iceConn); - strncpy (errorStringRet, "Could not open network socket", errorLength); + if (errorStringRet && errorLength > 0) { + strncpy (errorStringRet, "Could not open network socket", errorLength); + errorStringRet[errorLength - 1] = '\0'; + } return (NULL); } @@ -195,7 +204,10 @@ IceOpenConnection ( if ((iceConn->inbuf = iceConn->inbufptr = malloc (ICE_INBUFSIZE)) == NULL) { _IceFreeConnection (iceConn); - strncpy (errorStringRet, "Can't malloc", errorLength); + if (errorStringRet && errorLength > 0) { + strncpy (errorStringRet, "Can't malloc", errorLength); + errorStringRet[errorLength - 1] = '\0'; + } return (NULL); } @@ -204,7 +216,10 @@ IceOpenConnection ( if ((iceConn->outbuf = iceConn->outbufptr = calloc (1, ICE_OUTBUFSIZE)) == NULL) { _IceFreeConnection (iceConn); - strncpy (errorStringRet, "Can't malloc", errorLength); + if (errorStringRet && errorLength > 0) { + strncpy (errorStringRet, "Can't malloc", errorLength); + errorStringRet[errorLength - 1] = '\0'; + } return (NULL); } @@ -257,8 +272,11 @@ IceOpenConnection ( if (ioErrorOccured) { _IceFreeConnection (iceConn); - strncpy (errorStringRet, "IO error occured opening connection", -errorLength); + if (errorStringRet && errorLength > 0) { + strncpy (errorStringRet, "IO error occured opening connection", +errorLength); + errorStringRet[errorLength - 1] = '\0'; + } return (NULL); } @@ -269,9 +287,12 @@ IceOpenConnection ( */ _IceFreeConnection (iceConn); - strncpy (errorStringRet, - "Internal error - did not receive the expected ByteOrder message", -errorLength); + if (errorStringRet && errorLength > 0) { + strncpy (errorStringRet, + "Internal error - did not receive the expected ByteOrder " + "message", errorLength); + errorStringRet[errorLength - 1] = '\0'; + } return (NULL); } @@ -355,8 +376,11 @@ IceOpenConnection ( if (ioErrorOccured) { - strncpy (errorStringRet, "IO error occured opening connection", - errorLength); + if (errorStringRet && errorLength > 0) { + strncpy (errorStringRet, "IO error occured opening connection", + errorLength); + errorStringRet[errorLength - 1] = '\0'; + } _IceFreeConnection (iceConn); iceConn = NULL; } @@ -366,9 +390,12 @@ IceOpenConnection ( { if (reply.connection_reply.version_index >= _IceVersionCount) { - strncpy (errorStringRet, - "Got a bad version index in the Connection Reply", - errorLength); + if (errorStringRet && errorLength > 0) { + strncpy (errorStringRet, + "Got a bad version index in the Co
[PATCH app/xlsatoms 1/3] Support xcb_atom_t in range specification.
The data type xcb_atom_t is an unsigned int (32 bit), but the optional range argument is parsed with atoi(), which returns a signed int. Even though it is possible to reach all values through clever casting, it is more readable by properly using correct data types. This also fixes a segmentation fault on 32 bit systems if a range is supplied which overflows size_t: $ xlsatoms -range 0-1073741824 Segmentation fault (core dumped) If an invalid range is supplied, an error message is printed. This is new because previously an invalid range was silently accepted. $ xlsatoms -range 0--1 $ _ $ xlsatoms-new -range 0--1 xlsatoms-new: invalid range: 0--1 Signed-off-by: Tobias Stoeckmann --- xlsatoms.c | 51 +-- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/xlsatoms.c b/xlsatoms.c index d3e0883..2bb5b47 100644 --- a/xlsatoms.c +++ b/xlsatoms.c @@ -31,6 +31,7 @@ in this Software without prior written authorization from The Open Group. # include "config.h" #endif +#include #include #include #include @@ -45,10 +46,10 @@ static const char *ProgramName; static const char *DisplayString; static void do_name ( xcb_connection_t *c, const char *format, char *name ); -static int parse_range ( char *range, long *lowp, long *highp ); +static int parse_range ( char *range, xcb_atom_t *lowp, xcb_atom_t *highp ); static void do_range ( xcb_connection_t *c, const char *format, char *range ); static void list_atoms ( xcb_connection_t *c, const char *format, int mask, -long low, long high ); +xcb_atom_t low, xcb_atom_t high ); static void usage(const char *errmsg) @@ -161,8 +162,23 @@ do_name(xcb_connection_t *c, const char *format, char *name) #define RangeLow (1 << 0) #define RangeHigh (1 << 1) +static int +strtoatom(char *s, xcb_atom_t *atom) +{ +long long value; +char *end; + +value = strtoll(s, , 10); +if (s == end || *end != '\0' || value < 0 || value > UINT32_MAX) { + return 1; +} + +*atom = value; +return 0; +} + static int -parse_range(char *range, long *lowp, long *highp) +parse_range(char *range, xcb_atom_t *lowp, xcb_atom_t *highp) { char *dash; int mask = 0; @@ -179,35 +195,46 @@ parse_range(char *range, long *lowp, long *highp) *lowp = 1; } else {/* low-[high] */ *dash = '\0'; - *lowp = atoi (range); + if (strtoatom(range, lowp)) { + *dash = '-'; + goto invalid; + } *dash = '-'; } mask |= RangeLow; dash++; if (*dash) {/* [low]-high */ - *highp = atoi (dash); + if (strtoatom(dash, highp) || *highp < *lowp) { + goto invalid; + } mask |= RangeHigh; } } else { /* number (low == high) */ - *lowp = *highp = atoi (range); + if (strtoatom(range, lowp)) { + goto invalid; + } + *highp = *lowp; mask |= (RangeLow | RangeHigh); } return mask; +invalid: +fprintf(stderr, "%s: invalid range: %s\n", ProgramName, range); +exit(1); } static void do_range(xcb_connection_t *c, const char *format, char *range) { int mask; -long low, high; +xcb_atom_t low, high; mask = parse_range (range, , ); list_atoms (c, format, mask, low, high); } static int -say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *cookie, long low, long count) +say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *cookie, xcb_atom_t low, long count) { xcb_generic_error_t *e; char atom_name[1024]; @@ -240,7 +267,7 @@ say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *c } static void -list_atoms(xcb_connection_t *c, const char *format, int mask, long low, long high) +list_atoms(xcb_connection_t *c, const char *format, int mask, xcb_atom_t low, xcb_atom_t high) { xcb_get_atom_name_cookie_t *cookie_jar; int done = 0; @@ -250,9 +277,13 @@ list_atoms(xcb_connection_t *c, const char *format, int mask, long low, long hig low = 1; /* fall through */ case (RangeLow | RangeHigh): + if (high - low >= SIZE_MAX / sizeof(xcb_get_atom_name_cookie_t)) { + fprintf(stderr, "Cannot allocate space for %lu atom requests\n", (unsigned long) (high - low)); + return; + } cookie_jar = malloc((high - low + 1) * sizeof(xcb_get_atom_name_cookie_t)); if (!cookie_jar) { - fprintf(stderr, "Out of memory allocating space for %ld atom requests\n", high - low); + fprintf(stderr, "Out of memory allocating space for %lu atom requests\n",
[PATCH app/xlsatoms 3/3] Always use chunks when retrieving atoms.
If a low and high range limit has been specified, all atoms are retrieved at once. This is also the reason why malloc() is used: All cookies are stored before collecting the data. By using chunks it is possible to specify a huge range or even all possible atoms without running out of memory. Signed-off-by: Tobias Stoeckmann --- xlsatoms.c | 51 ++- 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/xlsatoms.c b/xlsatoms.c index 5bed0cc..a971901 100644 --- a/xlsatoms.c +++ b/xlsatoms.c @@ -234,7 +234,7 @@ do_range(xcb_connection_t *c, const char *format, char *range) } static int -say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *cookie, xcb_atom_t low, long count) +say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *cookie, xcb_atom_t low, long count, int stop_error) { xcb_generic_error_t *e; char atom_name[1024]; @@ -248,7 +248,7 @@ say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *c xcb_get_atom_name_reply_t *r; r = xcb_get_atom_name_reply(c, cookie[i], ); if (r) { - if (!done) { + if (!done || !stop_error) { /* We could just use %.*s in 'format', but we want to be compatible with legacy command line usage */ snprintf(atom_name, sizeof(atom_name), "%.*s", @@ -265,50 +265,27 @@ say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *c } } -return done; +return done && stop_error; } static void list_atoms(xcb_connection_t *c, const char *format, int mask, xcb_atom_t low, xcb_atom_t high) { -xcb_get_atom_name_cookie_t *cookie_jar; +xcb_get_atom_name_cookie_t cookie_jar[ATOMS_PER_BATCH]; int done = 0; +long count; -switch (mask) { - case RangeHigh: +if ((mask & RangeLow) == 0) low = 1; - /* fall through */ - case (RangeLow | RangeHigh): - if (high - low >= SIZE_MAX / sizeof(xcb_get_atom_name_cookie_t)) { - fprintf(stderr, "Cannot allocate space for %lu atom requests\n", (unsigned long) (high - low)); - return; - } - cookie_jar = malloc((high - low + 1) * sizeof(xcb_get_atom_name_cookie_t)); -if (!cookie_jar) { - fprintf(stderr, "Out of memory allocating space for %lu atom requests\n", (unsigned long) (high - low)); - return; - } +if ((mask & RangeHigh) == 0) + high = UINT32_MAX; - say_batch(c, format, cookie_jar, low, high - low + 1); - free(cookie_jar); - break; - - default: - low = 1; - /* fall through */ - case RangeLow: - cookie_jar = malloc(ATOMS_PER_BATCH * sizeof(xcb_get_atom_name_cookie_t)); -if (!cookie_jar) { - fprintf(stderr, "Out of memory allocating space for %ld atom requests\n", (long) ATOMS_PER_BATCH); - return; - } - while (!done) { - done = say_batch(c, format, cookie_jar, low, ATOMS_PER_BATCH); - low += ATOMS_PER_BATCH; +while (!done) { + count = high - low < ATOMS_PER_BATCH - 1 ? high - low + 1 : ATOMS_PER_BATCH; + done = say_batch(c, format, cookie_jar, low, count, (mask & RangeHigh) == 0); + if (high - low < UINT32_MAX && low == high - count + 1) { + done = 1; } - free(cookie_jar); - break; + low += count; } - -return; } -- 2.18.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH app/xlsatoms 2/3] Actually stop after an invalid atom.
The manual page states that if no upper range limit has been specified, no higher atoms will be printed. This is not true for $ xlsatoms -range 0- This prints the first 100 atoms, even though it already encountered an invalid one at 0. The reason is that say_batch works as a batch, i.e. retrieves 100 atoms at a time. If one of them is invalid, the rest is still printed. With this adjustment, xlsatoms behaves as stated in manual page. Signed-off-by: Tobias Stoeckmann --- xlsatoms.c | 16 +--- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/xlsatoms.c b/xlsatoms.c index 2bb5b47..5bed0cc 100644 --- a/xlsatoms.c +++ b/xlsatoms.c @@ -248,13 +248,15 @@ say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *c xcb_get_atom_name_reply_t *r; r = xcb_get_atom_name_reply(c, cookie[i], ); if (r) { - /* We could just use %.*s in 'format', but we want to be compatible - with legacy command line usage */ - snprintf(atom_name, sizeof(atom_name), "%.*s", - r->name_len, xcb_get_atom_name_name(r)); - - printf (format, i + low, atom_name); - putchar ('\n'); + if (!done) { + /* We could just use %.*s in 'format', but we want to be compatible + with legacy command line usage */ + snprintf(atom_name, sizeof(atom_name), "%.*s", + r->name_len, xcb_get_atom_name_name(r)); + + printf (format, i + low, atom_name); + putchar ('\n'); + } free(r); } if (e) { -- 2.18.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH app/xlsatoms] Adjust man page to show default format.
The default format is %lu\t%s, not %ld\t%s, i.e. unsigned. Signed-off-by: Tobias Stoeckmann --- man/xlsatoms.man | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/xlsatoms.man b/man/xlsatoms.man index afa89bf..34d386e 100644 --- a/man/xlsatoms.man +++ b/man/xlsatoms.man @@ -44,7 +44,7 @@ This option specifies the X server to which to connect. This option specifies a \fIprintf\fP-style string used to list each atom \fI\fP pair, printed in that order (\fIvalue\fP is an \fIunsigned long\fP and \fIname\fP is a \fIchar *\fP). \fIXlsatoms\fP will supply a -newline at the end of each line. The default is \fI%ld\\t%s\fP. +newline at the end of each line. The default is \fI%lu\\t%s\fP. .TP 8 .B \-range \fI[low]-[high]\fP This option specifies the range of atom values to check. If \fIlow\fP is not -- 2.18.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH app/xinit] Buffer overflow with many arguments.
Command line arguments are copied into clientargv and serverargv without verifying that enough space is available. A high amount of arguments can therefore trigger a buffer overflow like this: $ xinit $(seq 1 500) Signed-off-by: Tobias Stoeckmann --- xinit.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/xinit.c b/xinit.c index f826b7a..8efd0be 100644 --- a/xinit.c +++ b/xinit.c @@ -151,7 +151,6 @@ main(int argc, char *argv[]) register char **ptr; pid_t pid; int client_given = 0, server_given = 0; -int client_args_given = 0, server_args_given = 0; int start_of_client_args, start_of_server_args; struct sigaction sa, si; #ifdef __APPLE__ @@ -174,7 +173,8 @@ main(int argc, char *argv[]) } start_of_client_args = (cptr - client); while (argc && strcmp(*argv, "--")) { -client_args_given++; +if (cptr > clientargv + 98) +Fatalx("too many client arguments"); *cptr++ = *argv++; argc--; } @@ -202,7 +202,8 @@ main(int argc, char *argv[]) start_of_server_args = (sptr - server); while (--argc >= 0) { -server_args_given++; +if (sptr > serverargv + 98) +Fatalx("too many server arguments"); *sptr++ = *argv++; } *sptr = NULL; -- 2.20.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH app/xinit] Buffer overflow with many arguments.
Command line arguments are copied into clientargv and serverargv without verifying that enough space is available. A high amount of arguments can therefore trigger a buffer overflow like this: $ xinit $(seq 1 500) Signed-off-by: Tobias Stoeckmann --- Integrated calculation as suggested by Walter with style according to rest of the code. --- xinit.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/xinit.c b/xinit.c index f826b7a..06c92b2 100644 --- a/xinit.c +++ b/xinit.c @@ -151,7 +151,6 @@ main(int argc, char *argv[]) register char **ptr; pid_t pid; int client_given = 0, server_given = 0; -int client_args_given = 0, server_args_given = 0; int start_of_client_args, start_of_server_args; struct sigaction sa, si; #ifdef __APPLE__ @@ -174,7 +173,8 @@ main(int argc, char *argv[]) } start_of_client_args = (cptr - client); while (argc && strcmp(*argv, "--")) { -client_args_given++; +if (cptr > clientargv + sizeof(clientargv) / sizeof(*clientargv) - 2) +Fatalx("too many client arguments"); *cptr++ = *argv++; argc--; } @@ -202,7 +202,8 @@ main(int argc, char *argv[]) start_of_server_args = (sptr - server); while (--argc >= 0) { -server_args_given++; +if (sptr > serverargv + sizeof(serverargv) / sizeof(*serverargv) - 2) +Fatalx("too many server arguments"); *sptr++ = *argv++; } *sptr = NULL; -- 2.20.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel