summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@oracle.com>2018-09-23 19:26:02 -0700
committerAlan Coopersmith <alan.coopersmith@oracle.com>2018-09-23 19:26:02 -0700
commitd3af455fb236931fadb6e863e5a4ed509c61d868 (patch)
treef67e9803474a3d7bfd305afc16ac4b1cf05bb44b
parent12d64c65200930885c694d018ec66d8946b3a214 (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.ac2
-rw-r--r--src/FSFontInfo.c25
-rw-r--r--src/FSFtNames.c23
-rw-r--r--src/FSListCats.c23
-rw-r--r--src/FSOpenFont.c17
-rw-r--r--src/FSQGlyphs.c20
-rw-r--r--src/FSQXExt.c20
-rw-r--r--src/FSQuExt.c13
-rw-r--r--src/FSSetCats.c31
-rw-r--r--src/FSlibint.h3
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.