diff -ruN Canna35b2.orig/server/convert.c Canna35b2/server/convert.c --- Canna35b2.orig/server/convert.c Mon Dec 2 20:01:34 1996 +++ Canna35b2/server/convert.c Mon Nov 11 19:59:52 2002 @@ -53,6 +53,8 @@ #define ACK2 2 #define ACK3 3 #define CHECK_ACK_BUF_SIZE (ACK_BUFSIZE + (SIZEOFLONG * 2) ) +#define IR_INT_MAX 32767 +#define IR_INT_INVAL(x) ((unsigned int)x > IR_INT_MAX) extern int errno; @@ -1778,6 +1780,8 @@ return( needsize ) ; req->namelen = (int)L4TOL(buf + SIZE4); + if( IR_INT_INVAL(req->namelen) ) + return( -1 ); ir_debug( Dmsg(10,"req->namelen =%d\n", req->namelen ); ) if( (needsize = SIZE8 + req->namelen - size) > 0 ) @@ -1785,6 +1789,8 @@ if( req->namelen > 0 ){ req->name = buf + SIZE8 ; + if( req->name[req->namelen - 1] != 0 ) + return( -1 ); } ir_debug( Dmsg(10,"req->namelen =%d\n", req->namelen ); ) ir_debug( Dmsg(10,"req->name =%s\n", req->name ); ) diff -ruN Canna35b2.orig/server/util.c Canna35b2/server/util.c --- Canna35b2.orig/server/util.c Wed Nov 6 19:09:47 1996 +++ Canna35b2/server/util.c Mon Nov 11 19:59:52 2002 @@ -217,6 +217,19 @@ return res; } +const Ushort * +ushortmemchr(ws, ch, len) +const Ushort *ws; +int ch; +size_t len; +{ + const Ushort *p, *end; + for (p = ws, end = ws + len; p < end; ++p) + if (*p == (Ushort)ch) + return p; + return NULL; +} + int ushortstrcpy(wd, ws) Ushort *wd, *ws; diff -ruN Canna35b2.orig/server/wconvert.c Canna35b2/server/wconvert.c --- Canna35b2.orig/server/wconvert.c Mon Nov 11 19:42:07 2002 +++ Canna35b2/server/wconvert.c Mon Nov 11 19:59:52 2002 @@ -100,6 +100,7 @@ #endif extern void DispDebug() ; +extern const Ushort *ushortmemchr pro((const Ushort *, int, size_t)); extern int canna_server_hi ; extern int canna_server_lo ; #ifdef DEBUG @@ -1322,7 +1323,10 @@ char *dirname, *dirnamelong = (char *)0; int cxnum = Request.type18.context, stat = -1; int requestsize = Request.type18.size, retval; + size_t datasize = Request.type18.datalen - SIZEOFSHORT * 2; + if (datasize == 0 || req->data[datasize - 1] != 0) + goto protoerr; if (validcontext(cxnum, client, wListDictionary)) { if (requestsize <= sizeof(local_buffer) || (dicnames = malloc(requestsize))) { @@ -1359,6 +1363,7 @@ } } +protoerr: retval = SendType6Reply(client, wListDictionary, EXTPROTO, stat, dicnames, namesize(dicnames, stat)); if (dicnames != (char *)local_buffer) free(dicnames); @@ -1470,10 +1475,15 @@ char *dicname, *dirname, *dirnamelong = (char *)0; int cxnum = Request.type18.context, stat = BADCONT; int dirlen, requestsize = Request.type18.size, retval; + size_t datasize = Request.type18.datalen - SIZEOFSHORT * 2; + if (datasize == 0 || req->data[datasize - 1] != 0) + goto protoerr; if (validcontext(cxnum, client, wGetWordTextDictionary)) { dirname = req->data ; dirlen = strlen(dirname) + 1 ; + if (dirlen == datasize) + goto protoerr; dicname = &(req->data[dirlen]) ; if (dirlen > 1) { if (!dirname || dirname[0] != ':' || @@ -1515,6 +1525,7 @@ free(dirnamelong); } } +protoerr: retval = SendType7Reply(client, wGetWordTextDictionary, EXTPROTO, stat, stat > 0 ? stat + 1 : 0, infobuf); if (infobuf != (Ushort *)local_buffer) free((char *)infobuf); @@ -2296,6 +2307,9 @@ { ir_debug( Dmsg(10, "ProcWideReq1 start!!\n") ); + if (Request.type1.datalen != 0) + return( -1 ); + return( 0 ) ; } @@ -2305,6 +2319,8 @@ { ir_debug( Dmsg(10, "ProcWideReq2 start!!\n") ); + if (Request.type2.datalen != SIZEOFSHORT) + return( -1 ); buf += HEADER_SIZE; Request.type2.context = S2TOS(buf); ir_debug( Dmsg(10, "req->context =%d\n", Request.type2.context) ); @@ -2317,6 +2333,8 @@ { ir_debug( Dmsg(10, "ProcWideReq3 start!!\n") ); + if (Request.type3.datalen != SIZEOFSHORT * 2) + return( -1 ); buf += HEADER_SIZE; Request.type3.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type3.buflen = S2TOS(buf); ir_debug( Dmsg(10, "req->context =%d\n", Request.type3.context) ); @@ -2334,12 +2352,18 @@ ir_debug( Dmsg(10, "ProcWideReq4 start!!\n") ); + if (Request.type4.datalen < SIZEOFSHORT * 4) + return( -1 ); buf += HEADER_SIZE; Request.type4.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type4.begin = S2TOS(buf); buf += SIZEOFSHORT; Request.type4.end = S2TOS(buf); buf += SIZEOFSHORT; Request.type4.yomilen = S2TOS(buf); Request.type4.yomi = (Ushort *)(buf += SIZEOFSHORT) ; - len = Request.type4.datalen - SIZEOFSHORT * 4; + len = Request.type4.yomilen + 1; + if (Request.type4.datalen != SIZEOFSHORT * (4 + len) + || len == 0 + || Request.type4.yomi[len - 1] != 0) + return( -1 ); for (data = Request.type4.yomi, i = 0; i < len; i++, data++) *data = ntohs((unsigned short)*data); /* ちょっとやだなあ */ ir_debug( Dmsg(10, "req->context =%d\n", Request.type4.context) ); @@ -2359,6 +2383,8 @@ { ir_debug( Dmsg(10, "ProcWideReq5 start!!\n") ); + if (Request.type5.datalen != SIZEOFSHORT * 2 + SIZEOFINT) + return( -1 ); buf += HEADER_SIZE; Request.type5.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type5.size = S2TOS(buf); buf += SIZEOFSHORT; Request.type5.mode = L4TOL(buf); @@ -2375,6 +2401,8 @@ { ir_debug( Dmsg(10, "ProcWideReq6 start!!\n") ); + if (Request.type6.datalen != SIZEOFSHORT * 3) + return( -1 ); buf += HEADER_SIZE; Request.type6.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type6.number = S2TOS(buf); buf += SIZEOFSHORT; Request.type6.buflen = S2TOS(buf); @@ -2391,6 +2419,8 @@ { ir_debug( Dmsg(10, "ProcWideReq7 start!!\n") ); + if (Request.type7.datalen != SIZEOFSHORT * 3) + return( -1 ); buf += HEADER_SIZE; Request.type7.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type7.number = S2TOS(buf); buf += SIZEOFSHORT; Request.type7.yomilen = (short)S2TOS(buf); @@ -2407,6 +2437,8 @@ { ir_debug( Dmsg(10, "ProcWideReq8 start!!\n") ); + if (Request.type8.datalen != SIZEOFSHORT * 4) + return( -1 ); buf += HEADER_SIZE; Request.type8.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type8.curbun = S2TOS(buf); buf += SIZEOFSHORT; Request.type8.curkouho = S2TOS(buf); @@ -2425,6 +2457,8 @@ { ir_debug( Dmsg(10, "ProcWideReq9 start!!\n") ); + if (Request.type9.datalen != SIZEOFSHORT * 4) + return( -1 ); buf += HEADER_SIZE; Request.type9.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type9.number = S2TOS(buf); buf += SIZEOFSHORT; Request.type9.kouho = S2TOS(buf); @@ -2442,9 +2476,13 @@ BYTE *buf ; { register int i ; + int rest; ir_debug( Dmsg(10, "ProcWideReq10 start!!\n") ); + rest = Request.type10.datalen - (SIZEOFSHORT * 2 + SIZEOFINT); + if (rest < 0) + return( -1 ); buf += HEADER_SIZE; Request.type10.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type10.number = S2TOS(buf); buf += SIZEOFSHORT; Request.type10.mode = L4TOL(buf); @@ -2452,6 +2490,8 @@ ir_debug( Dmsg(10, "req->number =%d\n", Request.type10.number) ); ir_debug( Dmsg(10, "req->mode =%d\n", Request.type10.mode) ); + if (rest != Request.type10.number * SIZEOFSHORT) + return( -1 ); buf += SIZEOFINT; Request.type10.kouho = (short *)buf; /* short? */ for (i = 0; i < Request.type10.number; i++) { Request.type10.kouho[i] = S2TOS(buf); buf += SIZEOFSHORT; @@ -2468,12 +2508,18 @@ register Ushort *data; int i, len ; - ir_debug( Dmsg(10, "ProcWideReq10 start!!\n") ); + ir_debug( Dmsg(10, "ProcWideReq11 start!!\n") ); + if (Request.type11.datalen < SIZEOFSHORT * 2) + return( -1 ); buf += HEADER_SIZE; Request.type11.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type11.curbun = S2TOS(buf); buf += SIZEOFSHORT; Request.type11.yomi = (Ushort *)buf; + if (Request.type11.datalen % SIZEOFSHORT != 0) + return( -1 ); len = ((int)Request.type11.datalen - SIZEOFSHORT * 2) / SIZEOFSHORT ; + if (len == 0 || Request.type11.yomi[len - 1] != 0) + return( -1 ); for (data = Request.type11.yomi, i = 0; i < len; i++, data++) *data = ntohs( *data ); /* なんかやだ */ ir_debug( Dmsg(10, "req->context =%d\n", Request.type11.context) ); @@ -2490,16 +2536,26 @@ BYTE *buf ; { register Ushort *data; - int i, len ; + int i, len, rest; ir_debug( Dmsg(10, "ProcWideReq12 start!!\n") ); + rest = Request.type12.datalen - SIZEOFSHORT; + if (rest < 0) + return( -1 ); buf += HEADER_SIZE; Request.type12.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type12.datainfo = (Ushort *)buf; + if (!ushortmemchr((Ushort *)buf, 0, rest / SIZEOFSHORT)) + return( -1 ); len = ushortstrlen((Ushort *)buf) + 1; + rest -= len * SIZEOFSHORT; + if (rest <= 0) + return( -1 ); for( data = Request.type12.datainfo, i = 0; i < len; i++, data++ ) *data = ntohs( *data ); /* なんかやだ */ buf += len * SIZEOFSHORT; + if (buf[rest - 1] != '\0') + return( -1 ); Request.type12.dicname = (char *)buf; ir_debug( Dmsg(10, "req->context =%d\n", Request.type12.context) ); ir_debug( Dmsg(10, "req->datainfo =%s\n", @@ -2517,24 +2573,37 @@ BYTE *buf ; { register Ushort *data; - int i ,len ; + int i ,len, rest; ir_debug( Dmsg(10, "ProcWideReq13 start!!\n") ); + rest = Request.type13.datalen - SIZEOFSHORT; + if (rest < 0) + return( -1 ); buf += HEADER_SIZE; Request.type13.context = S2TOS(buf); len = SIZEOFSHORT ; buf += len; Request.type13.dicname = (char *)buf; + if (!memchr(buf, 0, rest)) + return( -1 ); len = strlen( (char *)buf ) + 1; + rest -= len; + if (rest % SIZEOFSHORT + || rest < SIZEOFSHORT * 3) + return( -1 ); buf += len; Request.type13.yomi = (Ushort *)buf; len = ((int)Request.type13.datalen - len - SIZEOFSHORT * 4) / SIZEOFSHORT; + if (ushortmemchr((Ushort *)buf, 0, len) != (Ushort *)buf + len - 1) + return( -1 ); for( data = Request.type13.yomi, i = 0; i < len; i++, data++) *data = ntohs( *data ); - buf += (ushortstrlen((Ushort *)buf) + 1) * SIZEOFSHORT; + buf += len * SIZEOFSHORT; Request.type13.yomilen = S2TOS(buf); buf += SIZEOFSHORT; Request.type13.kouhosize = S2TOS(buf); buf += SIZEOFSHORT; Request.type13.hinshisize = S2TOS(buf); + if (Request.type13.yomilen != len - 1) + return( -1 ); ir_debug( Dmsg(10, "req->context =%d\n", Request.type13.context) ); ir_debug( Dmsg(10, "req->dicname =%s\n", Request.type13.dicname) ); ir_debug( Dmsg(10, "req->yomi =%s\n", @@ -2556,11 +2625,16 @@ ir_debug( Dmsg(10, "ProcWideReq14 start!!\n") ); + if (Request.type14.datalen <= SIZEOFINT + SIZEOFSHORT + || Request.type14.datalen % SIZEOFSHORT) + return( -1 ); buf += HEADER_SIZE; Request.type14.mode = L4TOL(buf); buf += SIZEOFINT; Request.type14.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type14.yomi = (Ushort *)buf; len = ((int)Request.type14.datalen - SIZEOFSHORT - SIZEOFINT) / SIZEOFSHORT; + if (Request.type14.yomi[len - 1] != 0) + return( -1 ); for (data = Request.type14.yomi, i = 0; i < len; i++, data++) *data = ntohs( *data ); /* なんかやだ */ @@ -2577,11 +2651,17 @@ ProcWideReq15(buf) BYTE *buf ; { + int rest; ir_debug( Dmsg(10, "ProcWideReq15 start!!\n") ); + rest = Request.type15.datalen - (SIZEOFINT + SIZEOFSHORT); + if (rest <= 0) + return( -1 ); buf += HEADER_SIZE; Request.type15.mode = L4TOL(buf); buf += SIZEOFINT; Request.type15.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type15.dicname = (char *)buf; + if (buf[rest - 1] != 0) + return( -1 ); ir_debug( Dmsg(10, "req->mode =%d\n", Request.type15.mode) ); ir_debug( Dmsg(10, "req->context =%d\n", Request.type15.context) ); ir_debug( Dmsg(10, "req->dicname =%s\n", @@ -2597,6 +2677,9 @@ ir_debug( Dmsg(10, "ProcWideReq17 start!!\n") ); buf += HEADER_SIZE; + if (Request.type17.datalen < SIZEOFCHAR * 2 + || buf[Request.type17.datalen - SIZEOFCHAR * 2] != 0) + return( -1 ); Request.type17.dicname = (char *)buf; Request.type17.mode = (char)*(buf + Request.type17.datalen - SIZEOFCHAR) ; ir_debug( Dmsg(10, "req->dicname =%s\n", @@ -2613,6 +2696,8 @@ { ir_debug( Dmsg(10, "ProcWideReq18 start!!\n") ); + if (Request.type18.datalen < SIZEOFSHORT * 2) + return( -1 ); buf += HEADER_SIZE; Request.type18.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type18.data = (char *)buf; buf += Request.type18.datalen - SIZEOFSHORT * 2; @@ -2630,12 +2715,18 @@ ProcWideReq19(buf) BYTE *buf ; { + int rest; ir_debug( Dmsg(10, "ProcWideReq19 start!!\n") ); + rest = Request.type20.datalen - (SIZEOFSHORT + SIZEOFINT * 2); + if (rest < 0) + return( -1 ); buf += HEADER_SIZE; Request.type20.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type20.command = L4TOL(buf); buf += SIZEOFINT; Request.type20.bufsize = L4TOL(buf); buf += SIZEOFINT; Request.type20.buf = (char *)buf; + if (Request.type20.bufsize != rest) + return( -1 ); ir_debug( Dmsg(10, "req->context =%d\n", Request.type20.context) ); ir_debug( Dmsg(10, "req->command =%d\n", Request.type20.command) ); ir_debug( Dmsg(10, "req->bufsize =%d\n", Request.type20.bufsize) ); @@ -2647,15 +2738,25 @@ ProcWideReq20(buf) BYTE *buf ; { + BYTE *bufend; ir_debug( Dmsg(10, "ProcWideReq20 start!!\n") ); + if (Request.type21.datalen < SIZEOFINT + SIZEOFSHORT) + return( -1 ); buf += HEADER_SIZE; Request.type21.mode = L4TOL(buf); + bufend = buf + Request.type21.datalen; buf += SIZEOFINT; Request.type21.context = S2TOS(buf); buf += SIZEOFSHORT; Request.type21.dirname = (char *)buf; + if (!memchr(buf, 0, bufend - buf)) + return( -1 ); buf += strlen((char *)buf) + 1; Request.type21.srcdic = (char *)buf; + if (!memchr(buf, 0, bufend - buf)) + return( -1 ); buf += strlen((char *)buf) + 1; Request.type21.dstdic = (char *)buf; + if (*(bufend - 1) != 0) + return( -1 ); ir_debug( Dmsg(10, "req->mode =%d\n", Request.type21.mode) ); ir_debug( Dmsg(10, "req->context =%d\n", Request.type21.context) );