ports/113628: [patch] Security update for archivers/lha
E. Barnes
sbbbsd at gmail.com
Tue Jun 12 16:50:03 UTC 2007
>Number: 113628
>Category: ports
>Synopsis: [patch] Security update for archivers/lha
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-ports-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Tue Jun 12 16:50:02 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: E. Barnes
>Release: 6.2-RELEASE-p2 i386
>Organization:
>Environment:
FreeBSD 6.2-RELEASE-p2 FreeBSD 6.2-RELEASE-p2 #1: Mon Mar 12 21:58:25 UTC 2007 i386
>Description:
lha doesn't open temporary files exclusively, which makes it possible for an
attacker to conduct a time-dependent attack by creating the file in advance.
See https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=236585 for more details and patch.
>How-To-Repeat:
>Fix:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=236585
Patch attached with submission follows:
diff -burp FC-5/lha-114i/src/lhadd.c /home/lkundrak/lha-114i-SUSE/src/lhadd.c
--- FC-5/lha-114i/src/lhadd.c 2000-10-04 16:57:38.000000000 +0200
+++ /home/lkundrak/lha-114i-SUSE/src/lhadd.c 2007-04-16 15:57:10.000000000 +0200
@@ -35,6 +36,8 @@ add_one(fp, nafp, hdr)
if ((hdr->unix_mode & UNIX_FILE_SYMLINK) == UNIX_FILE_SYMLINK) {
char buf[256], *b1, *b2;
if (!quiet) {
+ /* make sure we use a zero-terminated buffer */
+ hdr->name[255] = 0;
strcpy(buf, hdr->name);
b1 = strtok(buf, "|");
b2 = strtok(NULL, "|");
@@ -211,8 +214,11 @@ find_update_files(oafp)
add_sp(&sp, hdr.name, strlen(hdr.name) + 1);
}
else if ((hdr.unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_DIRECTORY) {
+ /* make sure we use a zero-terminated buffer */
+ hdr.name[sizeof(hdr.name)-1] = 0;
strcpy(name, hdr.name);
len = strlen(name);
+ /* XXX thomas: what about multiple '/' or about ".." */
if (len > 0 && name[len - 1] == '/')
name[--len] = '\0'; /* strip tail '/' */
if (stat(name, &stbuf) >= 0) /* exist ? */
@@ -237,17 +243,21 @@ delete(oafp, nafp)
old_header_pos = ftell(oafp);
while (get_header(oafp, &ahdr)) {
+ /* make sure we use a zero-terminated buffer */
+ ahdr.name[sizeof(ahdr.name)-1] = 0;
strcpy(lpath, ahdr.name);
b1 = strtok(lpath, "|");
b2 = strtok(NULL, "|");
if (need_file(b1)) { /* skip */
fseek(oafp, ahdr.packed_size, SEEK_CUR);
if (noexec || !quiet)
+ {
if (b2 != NULL)
printf("delete %s -> %s\n", b1, b2);
else
printf("delete %s\n", b1);
}
+ }
else { /* copy */
if (noexec) {
fseek(oafp, ahdr.packed_size, SEEK_CUR);
@@ -276,7 +286,7 @@ build_temporary_file()
signal(SIGHUP, interrupt);
old_umask = umask(077);
- afp = xfopen(temporary_name, WRITE_BINARY);
+ afp = xfopen(temporary_name, "!" WRITE_BINARY);
remove_temporary_at_error = TRUE;
temporary_fp = afp;
umask(old_umask);
diff -burp FC-5/lha-114i/src/lharc.c /home/lkundrak/lha-114i-SUSE/src/lharc.c
--- FC-5/lha-114i/src/lharc.c 2007-04-16 15:20:23.000000000 +0200
+++ /home/lkundrak/lha-114i-SUSE/src/lharc.c 2007-04-16 15:57:10.000000000 +0200
@@ -1005,10 +1009,18 @@ FILE *
xfopen(name, mode)
char *name, *mode;
{
- FILE *fp;
+ FILE *fp = NULL;
+
+ if (mode[0] == '!') {
+ int fd;
+ fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (fd < 0 || (fp = fdopen(fd, mode + 1)) == NULL)
+ fatal_error(name);
+ } else {
if ((fp = fopen(name, mode)) == NULL)
fatal_error(name);
+ }
return fp;
}
@@ -1066,6 +1079,12 @@ open_old_archive()
if (open_old_archive_1(archive_name, &fp))
return fp;
snprintf(expanded_archive_name, sizeof(expanded_archive_name),
+ "%s." ARCHIVEEXT_OLD, archive_name);
+ if (open_old_archive_1(expanded_archive_name, &fp)) {
+ archive_name = expanded_archive_name;
+ return fp;
+ }
+ snprintf(expanded_archive_name, sizeof(expanded_archive_name),
"%s.lzh", archive_name);
if (open_old_archive_1(expanded_archive_name, &fp)) {
archive_name = expanded_archive_name;
diff -burp FC-5/lha-114i/src/lhext.c /home/lkundrak/lha-114i-SUSE/src/lhext.c
--- FC-5/lha-114i/src/lhext.c 2007-04-16 15:20:23.000000000 +0200
+++ /home/lkundrak/lha-114i-SUSE/src/lhext.c 2007-04-16 15:57:10.000000000 +0200
@@ -360,7 +361,6 @@ extract_one(afp, hdr)
}
unlink(bb1);
- make_parent_path(bb1);
l_code = symlink(bb2, bb1);
if (l_code < 0) {
if (quiet != TRUE)
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-ports-bugs
mailing list