* [kbd] [PATCH] Validate psfu headers to avoid integer overflows.
@ 2015-08-28 17:34 Tobias Stoeckmann
0 siblings, 0 replies; only message in thread
From: Tobias Stoeckmann @ 2015-08-28 17:34 UTC (permalink / raw)
To: kbd
[-- Attachment #1: Type: text/plain, Size: 2168 bytes --]
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 <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -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
[-- Attachment #2: setfont-fpe.psfu --]
[-- Type: application/octet-stream, Size: 32 bytes --]
[-- Attachment #3: psfxtable-segfault.psfu --]
[-- Type: application/octet-stream, Size: 39 bytes --]
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2015-08-28 17:34 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-28 17:34 [kbd] [PATCH] Validate psfu headers to avoid integer overflows Tobias Stoeckmann
Linux console tools development discussion
This inbox may be cloned and mirrored by anyone:
git clone --mirror http://lore.altlinux.org/kbd/0 kbd/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 kbd kbd/ http://lore.altlinux.org/kbd \
kbd@lists.altlinux.org kbd@lists.altlinux.ru kbd@lists.altlinux.com
public-inbox-index kbd
Example config snippet for mirrors.
Newsgroup available over NNTP:
nntp://lore.altlinux.org/org.altlinux.lists.kbd
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git