diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2018-09-23 19:26:02 -0700 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2018-09-23 19:26:02 -0700 |
commit | d3af455fb236931fadb6e863e5a4ed509c61d868 (patch) | |
tree | f67e9803474a3d7bfd305afc16ac4b1cf05bb44b | |
parent | 12d64c65200930885c694d018ec66d8946b3a214 (diff) |
Don't try to send strings larger than protocol allows in requests
Also clears up all "Loss of precision on implicit conversion" warnings
from Oracle's Parfait static analyser.
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/FSFontInfo.c | 25 | ||||
-rw-r--r-- | src/FSFtNames.c | 23 | ||||
-rw-r--r-- | src/FSListCats.c | 23 | ||||
-rw-r--r-- | src/FSOpenFont.c | 17 | ||||
-rw-r--r-- | src/FSQGlyphs.c | 20 | ||||
-rw-r--r-- | src/FSQXExt.c | 20 | ||||
-rw-r--r-- | src/FSQuExt.c | 13 | ||||
-rw-r--r-- | src/FSSetCats.c | 31 | ||||
-rw-r--r-- | src/FSlibint.h | 3 |
10 files changed, 136 insertions, 41 deletions
diff --git a/configure.ac b/configure.ac index 7ea0e4f..24b06c4 100644 --- a/configure.ac +++ b/configure.ac @@ -52,7 +52,7 @@ PKG_CHECK_MODULES(FS, xproto >= 7.0.17 fontsproto xtrans) XTRANS_CONNECTION_FLAGS # Checks for library functions. -AC_CHECK_FUNCS([strlcpy]) +AC_CHECK_FUNCS([strlcpy strnlen]) # Allow checking code with lint, sparse, etc. XORG_WITH_LINT diff --git a/src/FSFontInfo.c b/src/FSFontInfo.c index 39539c1..fd807ae 100644 --- a/src/FSFontInfo.c +++ b/src/FSFontInfo.c @@ -64,7 +64,6 @@ FSListFontsWithXInfo( FSPropOffset ***offsets, unsigned char ***prop_data) { - long nbytes; int i; size_t size = 0; FSXFontInfoHeader **fhdr = (FSXFontInfoHeader **) NULL; @@ -80,10 +79,24 @@ FSListFontsWithXInfo( Bool eat_data = True; GetReq(ListFontsWithXInfo, req); - req->maxNames = maxNames; - nbytes = req->nbytes = pattern ? strlen(pattern) : 0; - req->length += (nbytes + 3) >> 2; - _FSSend(svr, pattern, nbytes); + req->maxNames = (CARD32) maxNames; + req->nbytes = 0; + if (pattern != NULL) { + size_t nbytes; + +#ifdef HAVE_STRNLEN + nbytes = strnlen(pattern, FSMaxRequestBytes(svr)); +#else + nbytes = strlen(pattern); +#endif + + if (nbytes <= (FSMaxRequestBytes(svr) - + SIZEOF(fsListFontsWithXInfoReq))) { + req->nbytes = (CARD16) nbytes; + req->length += (CARD16) ((nbytes + 3) >> 2); + _FSSend(svr, pattern, (long) nbytes); + } + } for (i = 0;; i++) { if (FSProtocolVersion(svr) > 1) @@ -196,6 +209,8 @@ FSListFontsWithXInfo( if (FSProtocolVersion(svr) != 1) { + unsigned long nbytes; + /* get the name */ _FSRead(svr, flist[i], (long) reply.nameLength); flist[i][reply.nameLength] = '\0'; diff --git a/src/FSFtNames.c b/src/FSFtNames.c index 732040f..1dea246 100644 --- a/src/FSFtNames.c +++ b/src/FSFtNames.c @@ -61,7 +61,6 @@ FSListFonts( int maxNames, int *actualCount) { - long nbytes; unsigned int i, length; char **flist; @@ -71,10 +70,24 @@ FSListFonts( unsigned long rlen; GetReq(ListFonts, req); - req->maxNames = maxNames; - nbytes = req->nbytes = pattern ? strlen(pattern) : 0; - req->length += (nbytes + 3) >> 2; - _FSSend(svr, pattern, nbytes); + req->maxNames = (CARD32) maxNames; + req->nbytes = 0; + if (pattern != NULL) { + size_t nbytes; + +#ifdef HAVE_STRNLEN + nbytes = strnlen(pattern, FSMaxRequestBytes(svr)); +#else + nbytes = strlen(pattern); +#endif + + if (nbytes <= (FSMaxRequestBytes(svr) - SIZEOF(fsListFontsReq))) { + req->nbytes = (CARD16) nbytes; + req->length += (CARD16) ((nbytes + 3) >> 2); + _FSSend(svr, pattern, (long) nbytes); + } + } + if (!_FSReply(svr, (fsReply *) & rep, (SIZEOF(fsListFontsReply) - SIZEOF(fsGenericReply)) >> 2, fsFalse)) return (char **) NULL; diff --git a/src/FSListCats.c b/src/FSListCats.c index bc3dd62..2bc1393 100644 --- a/src/FSListCats.c +++ b/src/FSListCats.c @@ -61,7 +61,6 @@ FSListCatalogues( int maxNames, int *actualCount) { - long nbytes; int length; char **clist; char *c; @@ -70,10 +69,24 @@ FSListCatalogues( unsigned long rlen; GetReq(ListCatalogues, req); - req->maxNames = maxNames; - nbytes = req->nbytes = pattern ? strlen(pattern) : 0; - req->length += (nbytes + 3) >> 2; - _FSSend(svr, pattern, nbytes); + req->maxNames = (CARD32) maxNames; + req->nbytes = 0; + if (pattern != NULL) { + size_t nbytes; + +#ifdef HAVE_STRNLEN + nbytes = strnlen(pattern, FSMaxRequestBytes(svr)); +#else + nbytes = strlen(pattern); +#endif + + if (nbytes <= (FSMaxRequestBytes(svr) - SIZEOF(fsListCataloguesReq))) { + req->nbytes = (CARD16) nbytes; + req->length += (CARD16) ((nbytes + 3) >> 2); + _FSSend(svr, pattern, (long) nbytes); + } + } + if (!_FSReply(svr, (fsReply *) & rep, (SIZEOF(fsListCataloguesReply) - SIZEOF(fsGenericReply)) >> 2, fsFalse)) return (char **) NULL; diff --git a/src/FSOpenFont.c b/src/FSOpenFont.c index d35b75e..a079c69 100644 --- a/src/FSOpenFont.c +++ b/src/FSOpenFont.c @@ -62,22 +62,29 @@ FSOpenBitmapFont( const char *name, Font *otherid) { - unsigned int nbytes; + size_t nbytes; fsOpenBitmapFontReq *req; fsOpenBitmapFontReply reply; Font fid; char buf[256]; - nbytes = name ? strlen(name) : 0; - if (nbytes > 255) return 0; +#ifdef HAVE_STRNLEN + nbytes = strnlen(name, 256); +#else + nbytes = strlen(name); +#endif + + if ((nbytes == 0) || (nbytes > 255) || + (nbytes > (FSMaxRequestBytes(svr) - SIZEOF(fsOpenBitmapFontReq)))) + return 0; GetReq(OpenBitmapFont, req); - buf[0] = nbytes; + buf[0] = (CARD8) nbytes; memcpy(&buf[1], name, nbytes); nbytes++; req->fid = fid = svr->resource_id++; req->format_hint = hint; req->format_mask = fmask; - req->length += (nbytes + 3) >> 2; + req->length += (CARD16) ((nbytes + 3) >> 2); _FSSend(svr, buf, (long) nbytes); if (!_FSReply(svr, (fsReply *) & reply, (SIZEOF(fsOpenBitmapFontReply)-SIZEOF(fsGenericReply)) >> 2, diff --git a/src/FSQGlyphs.c b/src/FSQGlyphs.c index ddc02e6..0452d33 100644 --- a/src/FSQGlyphs.c +++ b/src/FSQGlyphs.c @@ -72,12 +72,15 @@ FSQueryXBitmaps8( unsigned char *gd; int left; + if (str_len > (FSMaxRequestBytes(svr) - SIZEOF(fsQueryXBitmaps8Req))) + return FSBadLength; + GetReq(QueryXBitmaps8, req); req->fid = fid; - req->range = range_type; + req->range = (BOOL) range_type; req->format = format; - req->num_ranges = str_len; - req->length += (str_len + 3) >> 2; + req->num_ranges = (CARD32) str_len; + req->length += (CARD16) ((str_len + 3) >> 2); _FSSend(svr, (char *) str, str_len); /* get back the info */ @@ -140,12 +143,17 @@ FSQueryXBitmaps16( unsigned char *gd; int left; + /* Relies on fsChar2b & fsChar2b_version1 being the same size */ + if (str_len > ((FSMaxRequestBytes(svr) - SIZEOF(fsQueryXBitmaps16Req)) + / SIZEOF(fsChar2b))) + return FSBadLength; + GetReq(QueryXBitmaps16, req); req->fid = fid; - req->range = range_type; + req->range = (BOOL) range_type; req->format = format; - req->num_ranges = str_len; - req->length += ((str_len * SIZEOF(fsChar2b)) + 3) >> 2; + req->num_ranges = (CARD32) str_len; + req->length += (CARD16) (((str_len * SIZEOF(fsChar2b)) + 3) >> 2); if (FSProtocolVersion(svr) == 1) { fsChar2b_version1 *swapped_str; diff --git a/src/FSQXExt.c b/src/FSQXExt.c index 82bab7b..1469636 100644 --- a/src/FSQXExt.c +++ b/src/FSQXExt.c @@ -79,11 +79,14 @@ FSQueryXExtents8( FSXCharInfo *ext; fsXCharInfo local_exts; + if (str_len > (FSMaxRequestBytes(svr) - SIZEOF(fsQueryXExtents8Req))) + return FSBadLength; + GetReq(QueryXExtents8, req); req->fid = fid; - req->range = range_type; - req->num_ranges = str_len; - req->length += (str_len + 3) >> 2; + req->range = (BOOL) range_type; + req->num_ranges = (CARD32) str_len; + req->length += (CARD16) ((str_len + 3) >> 2); _FSSend(svr, (char *) str, str_len); /* get back the info */ @@ -124,11 +127,16 @@ FSQueryXExtents16( FSXCharInfo *ext; fsXCharInfo local_exts; + /* Relies on fsChar2b & fsChar2b_version1 being the same size */ + if (str_len > ((FSMaxRequestBytes(svr) - SIZEOF(fsQueryXExtents16Req)) + / SIZEOF(fsChar2b))) + return FSBadLength; + GetReq(QueryXExtents16, req); req->fid = fid; - req->range = range_type; - req->num_ranges = str_len; - req->length += ((str_len * SIZEOF(fsChar2b)) + 3) >> 2; + req->range = (BOOL) range_type; + req->num_ranges = (CARD32) str_len; + req->length += (CARD16) (((str_len * SIZEOF(fsChar2b)) + 3) >> 2); if (FSProtocolVersion(svr) == 1) { fsChar2b_version1 *swapped_str; diff --git a/src/FSQuExt.c b/src/FSQuExt.c index fa3dd7e..9f6bcac 100644 --- a/src/FSQuExt.c +++ b/src/FSQuExt.c @@ -64,9 +64,20 @@ FSQueryExtension( { fsQueryExtensionReply rep; fsQueryExtensionReq *req; + size_t namelen; + +#ifdef HAVE_STRNLEN + namelen = name ? strnlen(name, 256) : 0; +#else + namelen = name ? strlen(name) : 0; +#endif + + if ((namelen == 0) || (namelen > 255) || + (namelen > (FSMaxRequestBytes(svr) - SIZEOF(fsQueryExtensionReq)))) + return False; GetReq(QueryExtension, req); - req->nbytes = name ? strlen(name) : 0; + req->nbytes = (CARD8) namelen; req->length += (req->nbytes + 3) >> 2; _FSSend(svr, name, (long) req->nbytes); if (!_FSReply(svr, (fsReply *) & rep, diff --git a/src/FSSetCats.c b/src/FSSetCats.c index e0dbbb3..f59badb 100644 --- a/src/FSSetCats.c +++ b/src/FSSetCats.c @@ -60,27 +60,44 @@ FSSetCatalogues( int num, char **cats) { - int nbytes; fsSetCataloguesReq *req; char buf[256]; - int i; - int len, tlen, tnum; + int i, tnum; + size_t len; for (i = 0, tnum = 0, len = 0; i < num; i++) { - if ((tlen = strlen(cats[i])) < 256) { + size_t tlen; + +#ifdef HAVE_STRNLEN + tlen = strnlen(cats[i], 256); +#else + tlen = strlen(cats[i]); +#endif + if (tlen < 256) { len += tlen; tnum++; } } + if ((tnum > 255) || + (len > (FSMaxRequestBytes(svr) - SIZEOF(fsSetCataloguesReq)))) + return FSBadLength; + GetReq(SetCatalogues, req); - req->num_catalogues = tnum; - req->length += (len + 3) >> 2; + req->num_catalogues = (CARD8) tnum; + req->length += (CARD16) ((len + 3) >> 2); for (i = 0; i < num; i++) { + size_t nbytes; + +#ifdef HAVE_STRNLEN + nbytes = strnlen(cats[i], 256); +#else nbytes = strlen(cats[i]); +#endif + if (nbytes < 256) { - buf[0] = nbytes; + buf[0] = (CARD8) nbytes; memcpy(&buf[1], cats[i], nbytes); nbytes++; _FSSend(svr, buf, (long) nbytes); diff --git a/src/FSlibint.h b/src/FSlibint.h index d68102a..303261c 100644 --- a/src/FSlibint.h +++ b/src/FSlibint.h @@ -110,6 +110,9 @@ extern FSServer *_FSHeadOfServerList; #define FSlibServerClosing (1L << 1) +/* FSMaxRequestBytes - returns FSMaxRequestSize converted to bytes */ +#define FSMaxRequestBytes(svr) ((svr)->max_request_size << 2) + /* * GetReq - Get the next available FS request packet in the buffer and * return it. |