From fc11092ea427ce0f75beab4af5cd01c8eddda29d Mon Sep 17 00:00:00 2001 From: "Andrey A. Chernov" Date: Mon, 29 Nov 2004 21:28:13 +0000 Subject: Close two vulnerabilities Submitted by: simon --- archivers/unarj/Makefile | 4 ++ archivers/unarj/files/patch-00-over-unarj.c | 47 ++++++++++++++++ archivers/unarj/files/patch-01-path-Makefile | 13 +++++ archivers/unarj/files/patch-01-path-unarj.c | 25 +++++++++ archivers/unarj/files/sanitize.c | 81 ++++++++++++++++++++++++++++ 5 files changed, 170 insertions(+) create mode 100644 archivers/unarj/files/patch-00-over-unarj.c create mode 100644 archivers/unarj/files/patch-01-path-Makefile create mode 100644 archivers/unarj/files/patch-01-path-unarj.c create mode 100644 archivers/unarj/files/sanitize.c (limited to 'archivers') 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 . Public Domain. + */ + +#include "unarj.h" + +#include +#include +#include + +#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'; +} -- cgit v1.2.3