summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey A. Chernov <ache@FreeBSD.org>2004-11-29 21:28:13 +0000
committerAndrey A. Chernov <ache@FreeBSD.org>2004-11-29 21:28:13 +0000
commitfc11092ea427ce0f75beab4af5cd01c8eddda29d (patch)
tree7e7d23913747eb56c329425a3a76847ac3769711
parentFix build with native java. (diff)
Close two vulnerabilities
Submitted by: simon
-rw-r--r--archivers/unarj/Makefile4
-rw-r--r--archivers/unarj/files/patch-00-over-unarj.c47
-rw-r--r--archivers/unarj/files/patch-01-path-Makefile13
-rw-r--r--archivers/unarj/files/patch-01-path-unarj.c25
-rw-r--r--archivers/unarj/files/sanitize.c81
5 files changed, 170 insertions, 0 deletions
diff --git a/archivers/unarj/Makefile b/archivers/unarj/Makefile
index d5b32a108228..dbea2f03571d 100644
--- a/archivers/unarj/Makefile
+++ b/archivers/unarj/Makefile
@@ -7,6 +7,7 @@
PORTNAME= unarj
PORTVERSION= 2.65
+PORTREVISION= 1
CATEGORIES= archivers
MASTER_SITES= ${MASTER_SITE_LOCAL}
MASTER_SITE_SUBDIR= ache
@@ -15,6 +16,9 @@ EXTRACT_SUFX= .tgz
MAINTAINER= ache@FreeBSD.org
COMMENT= Allows files to be extracted from ARJ archives
+post-patch:
+ ${CP} ${FILESDIR}/sanitize.c ${WRKSRC}
+
do-install:
${INSTALL} -d -m 755 -o ${SHAREOWN} -g ${SHAREGRP} \
${PREFIX}/share/doc/unarj
diff --git a/archivers/unarj/files/patch-00-over-unarj.c b/archivers/unarj/files/patch-00-over-unarj.c
new file mode 100644
index 000000000000..3a9426f21932
--- /dev/null
+++ b/archivers/unarj/files/patch-00-over-unarj.c
@@ -0,0 +1,47 @@
+--- unarj-2.65.orig/unarj.c
++++ unarj.c
+@@ -217,7 +217,7 @@ static uchar arj_flags;
+ static short method;
+ static uint file_mode;
+ static ulong time_stamp;
+-static short entry_pos;
++static ushort entry_pos;
+ static ushort host_data;
+ static uchar *get_ptr;
+ static UCRC file_crc;
+@@ -608,6 +608,7 @@ char *name;
+ error(M_BADHEADR, "");
+
+ crc = CRC_MASK;
++ memset(header, 0, sizeof(header));
+ fread_crc(header, (int) headersize, fd);
+ header_crc = fget_crc(fd);
+ if ((crc ^ CRC_MASK) != header_crc)
+@@ -632,9 +633,13 @@ char *name;
+
+ if (origsize < 0 || compsize < 0)
+ error(M_HEADRCRC, "");
++ if(first_hdr_size > headersize-2) /* need two \0 for file and comment */
++ error(M_BADHEADR, "");
+
+ hdr_filename = (char *)&header[first_hdr_size];
+ strncopy(filename, hdr_filename, sizeof(filename));
++ if(entry_pos >= strlen(filename))
++ error(M_BADHEADR, "");
+ if (host_os != OS)
+ strparity((uchar *)filename);
+ if ((arj_flags & PATHSYM_FLAG) != 0)
+@@ -733,11 +738,11 @@ extract()
+
+ no_output = 0;
+ if (command == 'E')
+- strcpy(name, &filename[entry_pos]);
++ strncopy(name, &filename[entry_pos], sizeof(name));
+ else
+ {
+ strcpy(name, DEFAULT_DIR);
+- strcat(name, filename);
++ strncopy(name+strlen(name), filename, sizeof(name)-strlen(name));
+ }
+
+ if (host_os != OS)
diff --git a/archivers/unarj/files/patch-01-path-Makefile b/archivers/unarj/files/patch-01-path-Makefile
new file mode 100644
index 000000000000..942f2ea7ee86
--- /dev/null
+++ b/archivers/unarj/files/patch-01-path-Makefile
@@ -0,0 +1,13 @@
+--- Makefile.orig Mon Nov 29 16:47:24 2004
++++ Makefile Mon Nov 29 22:46:56 2004
+@@ -9,7 +9,9 @@
+
+ decode.o: decode.c unarj.h
+
+-OBJS = unarj.o decode.o environ.o
++sanitize.o: sanitize.c unarj.h
++
++OBJS = unarj.o decode.o environ.o sanitize.o
+
+ unarj: $(OBJS)
+ $(CC) $(LDFLAGS) $(OBJS) -o unarj
diff --git a/archivers/unarj/files/patch-01-path-unarj.c b/archivers/unarj/files/patch-01-path-unarj.c
new file mode 100644
index 000000000000..c727acb2d8d3
--- /dev/null
+++ b/archivers/unarj/files/patch-01-path-unarj.c
@@ -0,0 +1,25 @@
+--- unarj-2.65.orig/unarj.c
++++ unarj.c
+@@ -235,6 +235,8 @@ static UCRC crctable[UCHAR_MAX + 1];
+
+ /* Functions */
+
++void copy_path_relative(char *dest, char *src, size_t len);
++
+ static void
+ make_crctable()
+ {
+@@ -738,11 +740,11 @@ extract()
+
+ no_output = 0;
+ if (command == 'E')
+- strncopy(name, &filename[entry_pos], sizeof(name));
++ copy_path_relative(name, &filename[entry_pos], sizeof(name));
+ else
+ {
+ strcpy(name, DEFAULT_DIR);
+- strncopy(name+strlen(name), filename, sizeof(name)-strlen(name));
++ copy_path_relative(name+strlen(name), filename, sizeof(name)-strlen(name));
+ }
+
+ if (host_os != OS)
diff --git a/archivers/unarj/files/sanitize.c b/archivers/unarj/files/sanitize.c
new file mode 100644
index 000000000000..dc698b60eb8b
--- /dev/null
+++ b/archivers/unarj/files/sanitize.c
@@ -0,0 +1,81 @@
+/*
+ * Path sanitation code by Ludwig Nussel <ludwig.nussel@suse.de>. Public Domain.
+ */
+
+#include "unarj.h"
+
+#include <string.h>
+#include <limits.h>
+#include <stdio.h>
+
+#ifndef PATH_CHAR
+#define PATH_CHAR '/'
+#endif
+#ifndef MIN
+#define MIN(x,y) ((x)<(y)?(x):(y))
+#endif
+
+/* copy src into dest converting the path to a relative one inside the current
+ * directory. dest must hold at least len bytes */
+void copy_path_relative(char *dest, char *src, size_t len)
+{
+ char* o = dest;
+ char* p = src;
+
+ *o = '\0';
+
+ while(*p && *p == PATH_CHAR) ++p;
+ for(; len && *p;)
+ {
+ src = p;
+ p = strchr(src, PATH_CHAR);
+ if(!p) p = src+strlen(src);
+
+ /* . => skip */
+ if(p-src == 1 && *src == '.' )
+ {
+ if(*p) src = ++p;
+ }
+ /* .. => pop one */
+ else if(p-src == 2 && *src == '.' && src[1] == '.')
+ {
+ if(o != dest)
+ {
+ char* tmp;
+ *o = '\0';
+ tmp = strrchr(dest, PATH_CHAR);
+ if(!tmp)
+ {
+ len += o-dest;
+ o = dest;
+ if(*p) ++p;
+ }
+ else
+ {
+ len += o-tmp;
+ o = tmp;
+ if(*p) ++p;
+ }
+ }
+ else /* nothing to pop */
+ if(*p) ++p;
+ }
+ else
+ {
+ size_t copy;
+ if(o != dest)
+ {
+ --len;
+ *o++ = PATH_CHAR;
+ }
+ copy = MIN(p-src,len);
+ memcpy(o, src, copy);
+ len -= copy;
+ src += copy;
+ o += copy;
+ if(*p) ++p;
+ }
+ while(*p && *p == PATH_CHAR) ++p;
+ }
+ o[len?0:-1] = '\0';
+}