diff options
author | sobomax <sobomax@FreeBSD.org> | 2001-04-09 17:24:29 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2001-04-09 17:24:29 +0000 |
commit | c6519e3e0388685fc2a942ced6420a40fc7f38a5 (patch) | |
tree | 6ca7b010816880f6fc270e856bc54f9b1974b251 /usr.sbin/vidcontrol/decode.c | |
parent | d06e42bb7e201adc51a3604b67db6591e901e7f0 (diff) | |
download | FreeBSD-src-c6519e3e0388685fc2a942ced6420a40fc7f38a5.zip FreeBSD-src-c6519e3e0388685fc2a942ced6420a40fc7f38a5.tar.gz |
Allow user to omit font size specification when loading a font. In addition
the following fixes had been made:
- check the size of the font being loaded and compare it with possible sizes
to minimise possibility of loading something that is not a fontfile at all
and turning console screen into garbage;
- prevent buffer overflow (and coredump as a result ) when loading valid
uuencoded file with size that exceeds allocated buffer;
- correct and improve several error messages.
Approved by: -audit, -hackers (silently)
Diffstat (limited to 'usr.sbin/vidcontrol/decode.c')
-rw-r--r-- | usr.sbin/vidcontrol/decode.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/usr.sbin/vidcontrol/decode.c b/usr.sbin/vidcontrol/decode.c index 1990595..3c6b467 100644 --- a/usr.sbin/vidcontrol/decode.c +++ b/usr.sbin/vidcontrol/decode.c @@ -35,10 +35,11 @@ static const char rcsid[] = #include <string.h> #include "decode.h" -int decode(FILE *fd, char *buffer) +int decode(FILE *fd, char *buffer, int len) { - int n, pos = 0; - char *p; + int n, pos = 0, tpos; + char *bp, *p; + char tbuffer[3]; char temp[128]; #define DEC(c) (((c) - ' ') & 0x3f) @@ -48,31 +49,49 @@ int decode(FILE *fd, char *buffer) return(0); } while (strncmp(temp, "begin ", 6)); sscanf(temp, "begin %o %s", &n, temp); + bp = buffer; for (;;) { if (!fgets(p = temp, sizeof(temp), fd)) return(0); if ((n = DEC(*p)) <= 0) break; - for (++p; n > 0; p += 4, n -= 3) + for (++p; n > 0; p += 4, n -= 3) { + tpos = 0; if (n >= 3) { - buffer[pos++] = DEC(p[0])<<2 | DEC(p[1])>>4; - buffer[pos++] = DEC(p[1])<<4 | DEC(p[2])>>2; - buffer[pos++] = DEC(p[2])<<6 | DEC(p[3]); + tbuffer[tpos++] = DEC(p[0])<<2 | DEC(p[1])>>4; + tbuffer[tpos++] = DEC(p[1])<<4 | DEC(p[2])>>2; + tbuffer[tpos++] = DEC(p[2])<<6 | DEC(p[3]); } else { if (n >= 1) { - buffer[pos++] = + tbuffer[tpos++] = DEC(p[0])<<2 | DEC(p[1])>>4; } if (n >= 2) { - buffer[pos++] = + tbuffer[tpos++] = DEC(p[1])<<4 | DEC(p[2])>>2; } if (n >= 3) { - buffer[pos++] = + tbuffer[tpos++] = DEC(p[2])<<6 | DEC(p[3]); } } + if (tpos == 0) + continue; + if (tpos + pos > len) { + tpos = len - pos; + /* + * Arrange return value > len to indicate + * overflow. + */ + pos++; + } + bcopy(tbuffer, bp, tpos); + pos += tpos; + bp += tpos; + if (pos > len) + return(pos); + } } if (!fgets(temp, sizeof(temp), fd) || strcmp(temp, "end\n")) return(0); |