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
|
Fix directory traversals issues.
Since .dz files normally just have relative directory trees:
pak/
pak/file
pak/subdir/file
we strip out all the components which ascend in the directory tree
http://bugs.gentoo.org/93079
--- a/main.c
+++ b/main.c
@@ -77,6 +77,48 @@ int dzRead (int inlen)
return 1;
}
+#define IS_SEP(c) (c == '/' || c == ':' || c == '\\')
+void scrub_name(char *smee)
+{
+ char *paths[] = { "../", "..\\", "..:", NULL};
+ size_t p, i, len;
+ char scrubit, scrubbed;
+
+ scrubbed = 0;
+ len = strlen(smee);
+ i = 0;
+ scrubit = 1;
+
+ /* search the path and scrub out all relative paths */
+ while (i + 3 < len) {
+ for (p = 0; paths[p]; ++p) {
+ if (scrubit && !strncmp(paths[p], smee+i, 3)) {
+ scrubbed = 1;
+ memset(smee+i, '\0', 3);
+ i += 2;
+ break;
+ }
+ }
+ scrubit = IS_SEP(smee[i]) || smee[i] == '\0';
+ ++i;
+ }
+
+ if (!scrubbed)
+ return;
+
+ /* condense the string over all the scrubbed bits */
+ p = 0;
+ for (i = 0; i < len; ++i) {
+ while (p < len && smee[p] == '\0')
+ ++p;
+ if (p == len) {
+ smee[i] = '\0';
+ break;
+ }
+ smee[i] = smee[p++];
+ }
+}
+
int dzReadDirectoryEntry (direntry_t *de)
{
char *s;
@@ -102,6 +144,7 @@ int dzReadDirectoryEntry (direntry_t *de
s = Dzip_malloc(de->len);
dzFile_Read(s, de->len);
de->name = s;
+ scrub_name(de->name);
if (de->pak && de->type != TYPE_PAK)
return 1; /* dont mess with dirchar inside pakfiles */
do
--- a/v1code.c
+++ b/v1code.c
@@ -201,6 +201,7 @@ void demv1_dxentities(void)
}
+extern void scrub_name(char *smee);
void dzUncompressV1 (int testing)
{
int i, inlen = 0;
@@ -221,6 +222,7 @@ void dzUncompressV1 (int testing)
{
de = directory + i;
crcval = INITCRC;
+ scrub_name(de->name);
printf("%s %s",action,de->name);
fflush(stdout);
|