[Lha-users] LHAに脆弱性

Back to archive index

Koji Arai jca02****@gmail*****
2007年 4月 23日 (月) 12:40:31 JST


新井です。

件のパッチについて、現状の調査状況を報告します。

> > <https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=236585>

|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, "|");

★autoconf版では、symlink 名の処理をヘッダ解析部に移しているので該当箇所なし。

|@@ -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 ? */

★get_header() において、hdr.name が '\0' terminate していることを保証
  しているので問題なし。まあ、str_safe_copy() に書き換えてもいいのです
  が。

  thomas さんのコメント部分はもう少し検討した方がよいかも。このパッチでは
  何もしてないのでとりあえず保留。

|@@ -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);

★autoconf版では、symlink 名の処理をヘッダ解析部に移しているので該当箇所なし。

|@@ -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);

★build_temporary_file() において、xfopen() は使用しなくなっているので
  問題なし。

|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;
| }

★build_temporary_file() において、xfopen() は使用しなくなっているので
  この変更も必要ない。

|@@ -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)

★よくわかりません。


-- 
Koji Arai




Lha-users メーリングリストの案内
Back to archive index