summaryrefslogtreecommitdiff
path: root/archivers/unace/patches/patch-ae
blob: 46757179e945adc5b5b37139c60dbad567424b27 (plain)
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
$NetBSD: patch-ae,v 1.1 2005/03/01 14:53:41 wiz Exp $

--- uac_crt.c.orig	1998-07-01 10:29:00.000000000 +0200
+++ uac_crt.c
@@ -33,12 +33,15 @@
 
 /* gets file name from header
  */
-CHAR *ace_fname(CHAR * s, thead * head, INT nopath)
+CHAR *ace_fname(CHAR * s, thead * head, INT nopath, unsigned int size)
 {
-   INT  i;
+   unsigned int i;
    char *cp;
 
-   strncpy(s, (*(tfhead *) head).FNAME, i = (*(tfhead *) head).FNAME_SIZE);
+   i = (*(tfhead *) head).FNAME_SIZE;
+   if (i > (size - 1))
+     i = size - 1;
+   strncpy(s, (*(tfhead *) head).FNAME, i);
    s[i] = 0;
 
    if (nopath)
@@ -56,22 +59,72 @@ CHAR *ace_fname(CHAR * s, thead * head, 
    }
 #endif
 
+   cp = s;
+   while (*cp == '/') cp++;
+   if (cp != s)
+     memmove(s, cp, strlen(cp) + 1);
+
    return s;
 }
 
+int is_directory_traversal(char *str)
+{
+  unsigned int mode, countdots;
+  /* mode 0 = fresh, 1 = just dots, 2 = not just dots */
+  char ch;
+
+  mode = countdots = 0;
+
+  while (ch = *str++)
+  {
+    if ((ch == '/') && (mode == 1) && (countdots > 1))
+      return 1;
+
+    if (ch == '/')
+    {
+       mode = countdots = 0;
+       continue;
+    }
+
+    if (ch == '.')
+    {
+      if (mode == 0)
+        mode = 1;
+
+      countdots++;
+    }
+    else
+      mode = 2;
+  }
+
+  if ((mode == 1) && (countdots > 1))
+    return 1;
+
+  return 0;
+}
+
 void check_ext_dir(CHAR * f)        // checks/creates path of file
 {
    CHAR *cp,
         d[PATH_MAX];
-   INT  i;
+   unsigned int i;
 
    d[0] = 0;
 
+   if (is_directory_traversal(f))
+   {
+      f_err = ERR_WRITE;
+      printf("\n    Directory traversal attempt:  %s\n", f);
+      return;
+   }
+
    for (;;)
    {
       if ((cp = (CHAR *) strchr(&f[strlen(d) + 1], DIRSEP))!=NULL)
       {
          i = cp - f;
+         if (i > (PATH_MAX - 1))
+           i = PATH_MAX - 1;
          strncpy(d, f, i);
          d[i] = 0;
       }