From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on sa.local.altlinux.org X-Spam-Level: X-Spam-Status: No, score=-1.6 required=5.0 tests=BAYES_00, DNS_FROM_AHBL_RHSBL, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2 autolearn=no autolearn_force=no version=3.4.0 Date: Fri, 28 Aug 2015 19:34:57 +0200 From: Tobias Stoeckmann To: kbd@lists.altlinux.org Message-ID: <20150828173456.GA3265@localhost> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Qxx1br4bt0+wmkIi" Content-Disposition: inline X-Provags-ID: V03:K0:54RVd6Ipd0xNEwPgixPvdPiZ8RuHK1fqBOxYxut/SRweNwCD7sP 8qI70V4g6c+sYRNCjinsdBYlYk+AX6aIOb+ze9h7M/xU/VyKqELViod2QrOwM1eWhzKdvYi czAEBjEA2MImuzda8Jo9I4ZohBDWXs8Y2AdEKV9O75etPwcltxJpJH6t78GuBjbYJZLsECX yKZQzC0Zj/X0+0l+FWYTQ== X-UI-Out-Filterresults: notjunk:1;V01:K0:hkQZCrK8b3M=:pUzfEeFgL8tkQRBzLPEi6+ xg/BxfQu5B7stfbB6Hne4cZwJTQh/iyDYv+l3aiHU3+5H55jZGITCwQLtKqhFmeaM0mh4zcrV 2icQEwtnK33NEQi8v41gUkl19riQA6RsdAYdabLbfRIjKc7jcyf5nPWB85aBi/TCowdJUxZyt 6yA14DKVbxEvDfaNVz4iK80rTejyl9Ya1v8QOox+hEUwjkNxwFeo6OV/ocsnOzDws2PcMB5H+ drVDMZ2MvF+svvDugQtEehfdV9DmTLVSzy4MtSQsk+DzK7eNYje6YN0atenxMURC/inrytbrY MwDQ3lLnlj0t4DyPgB8B+UKB2cUgGEdrzZzi6Murm3Hyic+jA+QhytoryF8ut9ps+/ODoiJlz IC7C2c4gEAQfPmN5yqy/JBhZYUCGhRe/zNemUqDiNV7rTi0Wr6wFq9H+Fie9jQcb/mghP4mne EzCvxm60dWXjMIJI8rf7U3qdIzbrkel1rvUNgBXpRd3DkQO/lNjauOTk0CA/4EbAPYiy4O4ZM 79KQoahxCY4EgpyWeCUCFUIny8Nn+AELlPyMj95Yte6pdR7a5RsJZnDejuUpCNjeYCXCGTFzy u4Yx9G1j9qm9Gu+hyzvhaio/YijtWaLDaxkLp55gwMgQuuC7Gge7aWyRSZjtzbWnDY4AGuAJh GxO4LvvkfV6FJr3KC12bXX/wkz2//71ldCZp7lC/4Wv4DqLE/40Cz+YVsZttLW7Jx140= Subject: [kbd] [PATCH] Validate psfu headers to avoid integer overflows. X-BeenThere: kbd@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: Linux console tools development discussion List-Id: Linux console tools development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Aug 2015 19:34:58 -0000 Archived-At: List-Archive: --Qxx1br4bt0+wmkIi Content-Type: text/plain; charset=us-ascii Content-Disposition: inline The psfu parser does not properly validate parsed values: * unsigned int values are casted to signed int values when parameters are supplied, therefore they must be checked against INT_MAX (local size_t variables are used) * fontwidth must not be larger than INT_MAX - 7, otherwise later alignment codes would overflow, e.g. (fontwidth + 7) / 8 * "ftoffset + fontlen * charsize" is prone to overflow, make sure that it does not; later on it will be checked against file size * when parsing multiple files, make sure that the sum of all fonts won't overflow --- Attached are two files which will crash the current code: $ setfont setfont-fpe.psfu # font width too large Floating point exception $ psfxtable -i psfxtable-segfault.psfu # on 32 bit archs Segmentation fault Maybe there are more ways to trigger overflows, which makes it a good target for fuzzing. --- src/psffontop.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/psffontop.c b/src/psffontop.c index 9d7ee54..e86d3cd 100644 --- a/src/psffontop.c +++ b/src/psffontop.c @@ -2,6 +2,7 @@ * psffontop.c - aeb@cwi.nl, 990921 */ +#include #include #include #include @@ -275,6 +276,27 @@ readpsffont(FILE *fontf, char **allbufp, int *allszp, fprintf(stderr, u, progname); exit(EX_DATAERR); } + if (INT_MAX - 7 < fontwidth) { + char *u = _("%s: Input file: font width too large\n"); + fprintf(stderr, u, progname); + exit(EX_DATAERR); + } + + /* validate header to avoid integer overflows */ + if ((size_t)(INT_MAX - fontpos0) < fontlen || + INT_MAX / sizeof(struct unicode_list) < fontpos0 + fontlen || + INT_MAX / charsize < fontlen) { + char *u = _("%s: too many glyphs to load\n"); + fprintf(stderr, u, progname); + exit(EX_DATAERR); + } + if (ftoffset > inputbuflth || + INT_MAX - ftoffset < fontlen * charsize) { + char *u = _("%s: Input file: bad offset\n"); + fprintf(stderr, u, progname); + exit(EX_DATAERR); + } + i = ftoffset + fontlen * charsize; if (i > inputlth || (!hastable && i != inputlth)) { char *u = _("%s: Input file: bad input length (%d)\n"); -- 2.5.0 --Qxx1br4bt0+wmkIi Content-Type: application/octet-stream Content-Disposition: attachment; filename="setfont-fpe.psfu" Content-Transfer-Encoding: base64 crVKhgAAAAAfAAAAAAAAAAEAAAABAAAAAQAAAPn///8= --Qxx1br4bt0+wmkIi Content-Type: application/octet-stream Content-Disposition: attachment; filename="psfxtable-segfault.psfu" Content-Transfer-Encoding: base64 crVKhgAAAAAfAAAAAAAAAFZVVRUMAAAAAQAAAPn///8AAAAAAAAA --Qxx1br4bt0+wmkIi--