Package: fig2dev / 1:3.2.7a-5+deb10u1

33_hardeninput.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
From: Thomas Loimer <thomas.loimer@tuwien.ac.at>
Date: Sat, 25 Aug 2018 20:46:45 +0200
Bug: https://sourceforge.net/p/mcj/tickets/27
Bug: https://sourceforge.net/p/mcj/tickets/28
Bug-Debian: https://bugs.debian.org/907660
Origin: https://sourceforge.net/p/mcj/fig2dev/ci/e0c4b02
Subject: Harden input in read.c, fixes tickets #27 and #28
 o Allow one char without newline in the last line of an input file.
   Fixes ticket #28.
 o Harden input, mainly against files in which an incomplete object would
   be created and freeing the object would violate memory, i.e, it may
   cause segfault. See, e.g., ticket #27.
 This fixes CVE-2018-16140

--- a/fig2dev/dev/readpcx.c
+++ b/fig2dev/dev/readpcx.c
@@ -96,8 +96,6 @@ _read_pcx(FILE *pcxfile, F_pic *pic)
 	fprintf(tfp, "%% Begin Imported PCX File: %s\n\n", pic->file);
 	pic->subtype = P_PCX;
 
-	pic->bitmap=NULL;
-
 	fread(&header,1,sizeof(struct pcxhed),pcxfile);
 	if (header.manuf!=10 || header.encod!=1)
 	    return 0;
--- a/fig2dev/read.c
+++ b/fig2dev/read.c
@@ -188,12 +188,24 @@ read_objects(FILE *fp, F_compound *obj)
 	int		object, coord_sys, len;
 
 	memset((char*)obj, '\0', COMOBJ_SIZE);
+
 	(void) fgets(buf, BUFSIZ, fp);	/* get the version line */
+	if (strncmp(buf, "#FIG ", 5)) {
+		put_msg("Incorrect format string in first line of input file.");
+		return -1;
+	}
+
+	/* remove newline and any carriage return (from a PC, perhaps) */
 	len = strlen(buf);
-	if (len > 0)
-	    buf[len-1] = '\0';			/* remove newline */
-	if (len > 1 && buf[len-2] == '\r')
-	    buf[len-2] = '\0';			/* and any CR (from a PC perhaps) */
+	if (buf[len-1] == '\n') {
+		if (buf[len-2] == '\r')
+			buf[len-2] = '\0';
+		else
+			buf[len-1] = '\0';
+	} else {	/* fgets() only stops at newline and end-of-file */
+		put_msg("File is truncated at first line.");
+		return -1;
+	}
 
 	/* v2_flag is for version 2 or higher */
 	v2_flag = (!strncmp(buf, "#FIG 2", 6) || !strncmp(buf, "#FIG 3", 6));
@@ -886,6 +898,8 @@ read_lineobject(FILE *fp)
 	l->next = NULL;
 	l->join_style = 0;
 	l->cap_style = 0;        /* butt line cap */
+	l->pic = NULL;
+	l->comments = NULL;
 
 	sscanf(buf,"%*d%d",&l->type);	/* get the line type */
 
@@ -968,12 +982,18 @@ read_lineobject(FILE *fp)
 	    char	file[BUFSIZ], *c;
 	    size_t	len;
 
-	    Pic_malloc(l->pic);
-	    l->pic->transp = -1;
-	    if (l->pic  == NULL) {
+	    if ((Pic_malloc(l->pic)) == NULL) {
 		free(l);
 		return NULL;
 	    }
+	    l->pic->transp = -1;
+	    l->pic->bitmap = NULL;
+#ifdef HAVE_X11_XPM_H
+	    /* initialize l->pic->xpmimage by (ab)using a
+	       public libxpm-function */
+	    XpmCreateXpmImageFromBuffer("", &l->pic->xpmimage, NULL);
+#endif
+
 			/* %[^\n]: really, read until first '\0' in buf */
 	    if (get_line(fp) < 0 || sscanf(buf, "%d %[^\n]",
 					&l->pic->flipped, file) != 2) {
@@ -1000,8 +1020,7 @@ read_lineobject(FILE *fp)
 		l->pic->file = malloc(len = strlen(file) + 1);
 		memcpy(l->pic->file, file, len);
 	    }
-	} else
-	    l->pic = NULL;
+	}
 
 	if (NULL == (l->points = Point_malloc(p))) {
 	    put_msg(Err_mem);
@@ -1082,6 +1101,7 @@ read_splineobject(FILE *fp)
 	s->fill_style = 0;
 	s->for_arrow = NULL;
 	s->back_arrow = NULL;
+	s->comments = NULL;
 	s->next = NULL;
 
 	if (v30_flag) {
@@ -1270,6 +1290,7 @@ read_textobject(FILE *fp)
 	Text_malloc(t);
 	t->font = 0;
 	t->size = 0.0;
+	t->comments = NULL;
 	t->next = NULL;
 
 	if (v30_flag) {	/* order of parms is more like other objects now,
@@ -1464,11 +1485,12 @@ get_line(FILE *fp)
 		if (*buf == '#') {			/* save any comments */
 			if (save_comment() < 0)
 				return -1;
-		} else if (*buf != '\n') {		/* Skip empty lines */
+			/* skip empty lines */
+		} else if (*buf != '\n' || !(*buf == '\r' && buf[1] == '\n')) {
 			len = strlen(buf);
-			buf[len-1] = '\0';	    /* strip trailing newline */
-			if (buf[len-2] == '\r')
-				buf[len-2] = '\0';	/* strip trailing CRs */
+			/* remove newline and possibly a carriage return */
+			if (buf[len-1] == '\n')
+				buf[len - (buf[len-2] == '\r' ? 2 : 1)] = '\0';
 			return 1;
 		}
 	}