Skip to content

Commit 6b9d1aa

Browse files
committed
Security fixes.
- Don't overflow the small cs_start buffer (reported by Niels Thykier via the debian tracker (Jakub Wilk), found with a fuzzer ("American fuzzy lop")). - Cast arguments to <ctype.h> functions to unsigned char.
1 parent b0ee70e commit 6b9d1aa

File tree

6 files changed

+77
-79
lines changed

6 files changed

+77
-79
lines changed

Diff for: Makefile.am

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ t1ascii_SOURCES = include/lcdf/clp.h include/lcdf/inttypes.h \
99
t1binary_SOURCES = include/lcdf/clp.h include/lcdf/inttypes.h \
1010
clp.c t1lib.h t1lib.c t1binary.c
1111
t1asm_SOURCES = include/lcdf/clp.h include/lcdf/inttypes.h \
12-
clp.c t1lib.h t1lib.c t1asm.c
12+
clp.c t1lib.h t1asmhelp.h t1lib.c t1asm.c
1313
t1disasm_SOURCES = include/lcdf/clp.h include/lcdf/inttypes.h \
14-
clp.c t1lib.h t1lib.c t1disasm.c
14+
clp.c t1lib.h t1asmhelp.h t1lib.c t1disasm.c
1515
t1unmac_SOURCES = include/lcdf/clp.h include/lcdf/inttypes.h \
1616
clp.c t1lib.h t1lib.c t1unmac.c
1717
t1mac_SOURCES = include/lcdf/clp.h include/lcdf/inttypes.h \

Diff for: t1asm.c

+13-27
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#include <errno.h>
6767
#include <lcdf/clp.h>
6868
#include "t1lib.h"
69+
#include "t1asmhelp.h"
6970

7071
#define LINESIZE 512
7172

@@ -90,10 +91,6 @@ static int in_eexec = 0;
9091
/* need to add 1 as space for \0 */
9192
static char line[LINESIZE + 1];
9293

93-
/* lenIV and charstring start command */
94-
static int lenIV = 4;
95-
static char cs_start[10];
96-
9794
/* for charstring buffering */
9895
static byte *charstring_buf, *charstring_bp;
9996
static int charstring_bufsiz;
@@ -273,7 +270,7 @@ static void eexec_start(char *string)
273270
static int check_line_charstring(void)
274271
{
275272
char *p = line;
276-
while (isspace(*p))
273+
while (isspace((unsigned char) *p))
277274
p++;
278275
return (*p == '/' || (p[0] == 'd' && p[1] == 'u' && p[2] == 'p'));
279276
}
@@ -359,8 +356,8 @@ static int CDECL command_compare(const void *key, const void *item)
359356

360357
static int is_integer(char *string)
361358
{
362-
if (isdigit(string[0]) || string[0] == '-' || string[0] == '+') {
363-
while (*++string && isdigit(*string))
359+
if (isdigit((unsigned char) string[0]) || string[0] == '-' || string[0] == '+') {
360+
while (*++string && isdigit((unsigned char) *string))
364361
; /* deliberately empty */
365362
if (!*string)
366363
return 1;
@@ -626,7 +623,7 @@ Report bugs to <ekohler@gmail.com>.\n", program_name);
626623

627624
int main(int argc, char *argv[])
628625
{
629-
char *p, *q, *r;
626+
char *p, *q;
630627

631628
Clp_Parser *clp =
632629
Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options);
@@ -740,36 +737,25 @@ particular purpose.\n");
740737
t1utils_getline();
741738

742739
if (!ever_active) {
743-
if (strncmp(line, "currentfile eexec", 17) == 0 && isspace(line[17])) {
740+
if (strncmp(line, "currentfile eexec", 17) == 0 && isspace((unsigned char) line[17])) {
744741
/* Allow arbitrary whitespace after "currentfile eexec".
745742
Thanks to Tom Kacvinsky <tjk@ams.org> for reporting this.
746743
Note: strlen("currentfile eexec") == 17. */
747-
for (p = line + 18; isspace(*p); p++)
744+
for (p = line + 18; isspace((unsigned char) *p); p++)
748745
;
749746
eexec_start(p);
750747
continue;
751748
} else if (strncmp(line, "/lenIV", 6) == 0) {
752-
lenIV = atoi(line + 6);
753-
} else if ((p = strstr(line, "string currentfile"))
754-
&& strstr(line, "readstring")) { /* enforce `readstring' */
755-
/* locate the name of the charstring start command */
756-
*p = '\0'; /* damage line[] */
757-
q = strrchr(line, '/');
758-
if (q) {
759-
r = cs_start;
760-
++q;
761-
while (!isspace(*q) && *q != '{')
762-
*r++ = *q++;
763-
*r = '\0';
764-
}
765-
*p = 's'; /* repair line[] */
749+
set_lenIV(line);
750+
} else if ((p = strstr(line, "string currentfile"))) {
751+
set_cs_start(line);
766752
}
767753
}
768754

769755
if (!active) {
770-
if ((p = strstr(line, "/Subrs")) && isdigit(p[7]))
756+
if ((p = strstr(line, "/Subrs")) && isdigit((unsigned char) p[7]))
771757
ever_active = active = 1;
772-
else if ((p = strstr(line, "/CharStrings")) && isdigit(p[13]))
758+
else if ((p = strstr(line, "/CharStrings")) && isdigit((unsigned char) p[13]))
773759
ever_active = active = 1;
774760
}
775761
if ((p = strstr(line, "currentfile closefile"))) {
@@ -778,7 +764,7 @@ particular purpose.\n");
778764
/* 1/3/2002 -- happy new year! -- Luc Devroye reports a failure with
779765
some printers when `currentfile closefile' is followed by space */
780766
p += sizeof("currentfile closefile") - 1;
781-
for (q = p; isspace(*q) && *q != '\n'; q++)
767+
for (q = p; isspace((unsigned char) *q) && *q != '\n'; q++)
782768
/* nada */;
783769
if (q == p && !*q)
784770
error("warning: `currentfile closefile' line too long");

Diff for: t1asmhelp.h

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#ifndef T1ASMHELP_H
2+
#define T1ASMHELP_H
3+
4+
static int lenIV = 4;
5+
6+
/* If the line contains an entry of the form `/lenIV <num>' then set the global
7+
lenIV to <num>. This indicates the number of random bytes at the beginning
8+
of each charstring. */
9+
10+
static void
11+
set_lenIV(const char* line)
12+
{
13+
char *p = strstr(line, "/lenIV ");
14+
15+
/* Allow lenIV to be negative. Thanks to Tom Kacvinsky <tjk@ams.org> */
16+
if (p && (isdigit((unsigned char) p[7]) || p[7] == '+' || p[7] == '-')) {
17+
lenIV = atoi(p + 7);
18+
}
19+
}
20+
21+
22+
static const char* cs_start = "";
23+
24+
static void
25+
set_cs_start(const char* line)
26+
{
27+
static int cs_start_set = 0;
28+
char *p, *q, *r;
29+
30+
if ((p = strstr(line, "string currentfile"))
31+
&& strstr(line, "readstring")) {
32+
/* locate the name of the charstring start command */
33+
for (q = p; q != line && q[-1] != '/'; --q)
34+
/* nada */;
35+
if (q != line) {
36+
for (r = q; r != p && !isspace((unsigned char) *r) && *r != '{'; ++r)
37+
/* nada */;
38+
if (cs_start_set)
39+
free((char*) cs_start);
40+
cs_start = p = malloc(r - q + 1);
41+
memcpy(p, q, r - q);
42+
p[r - q] = 0;
43+
cs_start_set = 1;
44+
}
45+
}
46+
}
47+
48+
#endif

Diff for: t1disasm.c

+1-40
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
#include <assert.h>
7171
#include <lcdf/clp.h>
7272
#include "t1lib.h"
73+
#include "t1asmhelp.h"
7374

7475
#ifdef __cplusplus
7576
extern "C" {
@@ -78,8 +79,6 @@ extern "C" {
7879
typedef unsigned char byte;
7980

8081
static FILE *ofp;
81-
static int lenIV = 4;
82-
static char cs_start[10];
8382
static int unknown = 0;
8483

8584
/* decryption stuff */
@@ -90,44 +89,6 @@ static uint16_t er_default = 55665;
9089
static int error_count = 0;
9190

9291

93-
/* If the line contains an entry of the form `/lenIV <num>' then set the global
94-
lenIV to <num>. This indicates the number of random bytes at the beginning
95-
of each charstring. */
96-
97-
static void
98-
set_lenIV(char *line)
99-
{
100-
char *p = strstr(line, "/lenIV ");
101-
102-
/* Allow lenIV to be negative. Thanks to Tom Kacvinsky <tjk@ams.org> */
103-
if (p && (isdigit(p[7]) || p[7] == '+' || p[7] == '-')) {
104-
lenIV = atoi(p + 7);
105-
}
106-
}
107-
108-
static void
109-
set_cs_start(char *line)
110-
{
111-
char *p, *q, *r;
112-
113-
if ((p = strstr(line, "string currentfile"))) {
114-
/* enforce presence of `readstring' -- 5/29/99 */
115-
if (!strstr(line, "readstring"))
116-
return;
117-
/* locate the name of the charstring start command */
118-
*p = '\0'; /* damage line[] */
119-
q = strrchr(line, '/');
120-
if (q) {
121-
r = cs_start;
122-
++q;
123-
while (!isspace(*q) && *q != '{')
124-
*r++ = *q++;
125-
*r = '\0';
126-
}
127-
*p = 's'; /* repair line[] */
128-
}
129-
}
130-
13192
/* Subroutine to output strings. */
13293

13394
static void

Diff for: t1lib.c

+8-6
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ translate_hex_string(char *s, char *saved_orphan)
5959
char *start = s;
6060
char *t = s;
6161
for (; *s; s++) {
62-
if (isspace(*s))
62+
if (isspace((unsigned char) *s))
6363
continue;
6464
if (c1) {
6565
*t++ = (hexval(c1) << 4) + hexval(*s);
@@ -136,10 +136,10 @@ process_pfa(FILE *ifp, const char *ifp_filename, struct font_reader *fr)
136136

137137
/* now that we have the line, handle it */
138138
if (blocktyp == PFA_ASCII) {
139-
if (strncmp(line, "currentfile eexec", 17) == 0 && isspace(line[17])) {
139+
if (strncmp(line, "currentfile eexec", 17) == 0 && isspace((unsigned char) line[17])) {
140140
char saved_p;
141141
/* assert(line == buffer); */
142-
for (line += 18; isspace(*line); line++)
142+
for (line += 18; isspace((unsigned char) *line); line++)
143143
/* nada */;
144144
saved_p = *line;
145145
*line = 0;
@@ -158,12 +158,14 @@ process_pfa(FILE *ifp, const char *ifp_filename, struct font_reader *fr)
158158
if (blocktyp == PFA_EEXEC_TEST) {
159159
/* 8.Feb.2004: fix bug if first character in a binary eexec block
160160
is 0, reported by Werner Lemberg */
161-
for (; line < last && isspace(*line); line++)
161+
for (; line < last && isspace((unsigned char) *line); line++)
162162
/* nada */;
163163
if (line == last)
164164
continue;
165-
else if (last >= line + 4 && isxdigit(line[0]) && isxdigit(line[1])
166-
&& isxdigit(line[2]) && isxdigit(line[3]))
165+
else if (last >= line + 4 && isxdigit((unsigned char) line[0])
166+
&& isxdigit((unsigned char) line[1])
167+
&& isxdigit((unsigned char) line[2])
168+
&& isxdigit((unsigned char) line[3]))
167169
blocktyp = PFA_HEX;
168170
else
169171
blocktyp = PFA_BINARY;

Diff for: t1mac.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -370,10 +370,11 @@ t1mac_output_ascii(char *s, int len)
370370
s[len-1] = '\r';
371371
t1mac_output_data((byte *)s, len);
372372
if (strncmp(s, "/FontName", 9) == 0) {
373-
for (s += 9; isspace(*s); s++) ;
373+
for (s += 9; isspace((unsigned char) *s); s++)
374+
/* skip */;
374375
if (*s == '/') {
375376
const char *t = ++s;
376-
while (*t && !isspace(*t)) t++;
377+
while (*t && !isspace((unsigned char) *t)) t++;
377378
free(font_name);
378379
font_name = (char *)malloc(t - s + 1);
379380
memcpy(font_name, s, t - s);
@@ -994,11 +995,11 @@ particular purpose.\n");
994995
int part = 0, len = 0;
995996
char *x, *s;
996997
for (x = s = font_name; *s; s++)
997-
if (isupper(*s) || isdigit(*s)) {
998+
if (isupper((unsigned char) *s) || isdigit((unsigned char) *s)) {
998999
*x++ = *s;
9991000
part++;
10001001
len = 1;
1001-
} else if (islower(*s)) {
1002+
} else if (islower((unsigned char) *s)) {
10021003
if (len < (part <= 1 ? 5 : 3))
10031004
*x++ = *s;
10041005
len++;

0 commit comments

Comments
 (0)