From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on sa.local.altlinux.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.1 Date: Sun, 20 Nov 2016 18:15:43 +0100 From: Tobias Stoeckmann To: kbd@lists.altlinux.org Message-ID: <20161120171543.GA30913@localhost> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="FCuugMFkClbJLl1L" Content-Disposition: inline X-Provags-ID: V03:K0:2NISQ9fr3By0dLAbAxuofrKuXEoc8A7kwaIS8sZs/OJ60760lNv 5C8cPpUmewcctYKMaC7T3Ce0PN6yprvNORZlX0sD4ogbirNaIvyA2acPhxobX8OZADklSVF DNrhlyvHElrOqMZinKPK8iYx/7RiLbIpFauH+VhrDNRtfD4He2cfIka+/pirFwzqCNjK4Bh YaZcpqaN6InsyK1bkwJuQ== X-UI-Out-Filterresults: notjunk:1;V01:K0:sLEK05s70Vs=:P8ZxSUWH4exBTIED7YvQnI WLMH5ffZW2CJmDdmAibFiYXq9oeQcN3JZ/agjAKVz3Ms4twcO4zLdfDjtoaJcY3EtcfGfNW3+ Oywjrtaz9YLBOYxLDS0ByT1rRicb1UqfiL7C2uSjXVnCp2+6rBeClZ/jpE0Z5wSX5pFRmkkCN 4e3TkNTY0qM1k/U3KhvaM1cAoLq7d9/da016fDUdjw0tBCzid+nmtaOcW5ShhQWr5Lt2zN4J0 61nGuCMvNbqlQMywsvZZtGbfxx4QoVqSw7xkTWeM+4tbLMGmre500pOLuRNgXR7UeYFeOFC47 r7KcoIM7l/2T2LDYp11EyJUS4sue0Nsm6KHkpgwEyLz95HUYR1c0eV1mk9zV6hbrm03+KF/eC 31zh8D8oMotrsga4IXVKDZ+IdWDSSzFUY2RUJz9O7hcPg/9JnBqHTM5WwYxeH9XO1kH5+33WN FcyLusDU08gzbUIDSWLHWmNWQc+gR9NpTZtYfRkhAEpzhpyQC3/Q2MTUqNQz50OrCnE8439vp nE4nI8hp3OyMs+uEGFWXNKhBPQ9Z+Yu5zzubWTFZBVdFG+5IIO9wHwpSktcuBVhjiop1sL0Q3 F7kLMGIQ1GJI1fRUIm5Tet4NA9gzwmtHBwGTsQHdcV3naVpPVoSU5w9H9zCwZNFK46CwRvhu6 VJU8YQUO+IfTGcXN1N92fV+TUrvUPGcFQ4evxHs+6Zdjn4JMVQepP3C3sk7FJQ8Putug= 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: Sun, 20 Nov 2016 17:15:51 -0000 Archived-At: List-Archive: --FCuugMFkClbJLl1L 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 --- I've sent this mail in August 2015 already. Based on the upcoming release, it might be a good idea to re-evaluate it. 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.10.2 --FCuugMFkClbJLl1L Content-Type: application/octet-stream Content-Disposition: attachment; filename="psfxtable-segfault.psfu" Content-Transfer-Encoding: base64 crVKhgAAAAAfAAAAAAAAAFZVVRUMAAAAAQAAAPn///8AAAAAAAAA --FCuugMFkClbJLl1L Content-Type: application/octet-stream Content-Disposition: attachment; filename="setfont-fpe.psfu" Content-Transfer-Encoding: base64 crVKhgAAAAAfAAAAAAAAAAEAAAABAAAAAQAAAPn///8= --FCuugMFkClbJLl1L--