As requested; in order attached to this mail: 1) 1.10.18.1 NMU changes as a patch against CVS v1_10 branch 2) Patch to fix tar bug, against CVS v1_10 branch. 3) 1.10.18.1 NMU changes as a patch against CVS HEAD, a couple of the changes aren't required here. 4) Patch to fix tar bug, against CVS HEAD. Scott -- Have you ever, ever felt like this? Had strange things happen? Are you going round the twist?
diff -ruNp cvs-dpkg-1.10~/ChangeLog cvs-dpkg-1.10/ChangeLog
--- cvs-dpkg-1.10~/ChangeLog 2004-01-28 02:06:41.000000000 +0000
+++ cvs-dpkg-1.10/ChangeLog 2004-03-04 13:22:45.000000000 +0000
@@ -0,0 +1,25 @@
+Thu Feb 26 01:48:15 GMT 2004 Scott James Remnant <scott@netsplit.com>
+
+ * main/processarc.c (process_archive): Copy code from main/remove.c
+ to ensure that hardlinks to devices, setuid files or setgid files
+ cannot be stashed away in the hope that they become compromisable
+ in the future. This was handled when removing a package, but not
+ when upgrading one.
+
+Thu Feb 26 01:23:13 GMT 2004 Scott James Remnant <scott@netsplit.com>
+
+ * version-nr: Bump to 1.10.18.1
+
+Mon Feb 23 22:46:21 GMT 2004 Scott James Remnant <scott@netsplit.com>
+
+ * dpkg-deb/main.c: Clean up previous badly applied multiline string
+ patch.
+
+Mon Feb 23 01:30:13 CET 2004 Steinar H. Gunderson <sesse@debian.org>
+
+ * main/remove.c: Terminate string buffer correctly.
+
+Fri Feb 20 10:22:24 CET 2004 Colin Watson <cjwatson@debian.org>
+
+ * dpkg-deb/main.c: Don't use multiline strings (a removed GCC extension).
+
diff -ruNp cvs-dpkg-1.10~/debian/changelog cvs-dpkg-1.10/debian/changelog
--- cvs-dpkg-1.10~/debian/changelog 2004-01-28 02:06:41.000000000 +0000
+++ cvs-dpkg-1.10/debian/changelog 2004-03-04 13:21:41.000000000 +0000
@@ -1,8 +1,14 @@
-dpkg (1.10.19) unstable; urgency=medium
-
- * Update dpkg conflicts to << 1.10, instead of 1.9. Closes: #190611.
+dpkg (1.10.18.1) unstable; urgency=medium
+
+ * Non-maintainer upload to fix release-critical bugs.
+ * Terminate string buffer in main/remove.c. Closes: #228379.
+ * Prevent stashing of hardlinked devices and setuid or setgid binaries
+ by removing permissions on upgrade as well as on remove.
+ Closes: #225692.
+ * Update dpkg conflicts to << 1.10, instead of 1.9.
+ Closes: #190611, #221989, #222760.
- -- Adam Heath <doogie@debian.org> UNRELEASED
+ -- Scott James Remnant <scott@netsplit.com> Thu, 26 Feb 2004 01:17:27 +0000
dpkg (1.10.18) unstable; urgency=medium
diff -ruNp cvs-dpkg-1.10~/dpkg-deb/main.c cvs-dpkg-1.10/dpkg-deb/main.c
--- cvs-dpkg-1.10~/dpkg-deb/main.c 2003-10-25 21:03:20.000000000 +0100
+++ cvs-dpkg-1.10/dpkg-deb/main.c 2004-03-04 13:20:21.000000000 +0000
@@ -54,42 +54,42 @@ static void printversion(void) {
}
static void usage(void) {
- if (fputs(_("\
-Command:\n\
- -b|--build <directory> [<deb>] build an archive.\n\
- -c|--contents <deb> list contents.\n\
- -I|--info <deb> [<cfile>...] show info to stdout.\n\
- -W|--show <deb> show information on package(s)\n\
- -f|--field <deb> [<cfield>...] show field(s) to stdout.\n\
- -e|--control <deb> [<directory>] extract control info.\n\
- -x|--extract <deb> <directory> extract files.\n\
- -X|--vextract <deb> <directory> extract & list files.\n\
- --fsys-tarfile <deb> output filesystem tarfile.\n\
- -h|--help display this message.\n\
- --version | --licence show version/licence.\n\
-\n\
-<deb> is the filename of a Debian format archive.\n\
-<cfile> is the name of an administrative file component.\n\
-<cfield> is the name of a field in the main `control' file.\n\
-\n\
-Options:\n\
- --showformat=<format> use alternative format for --show\n\
- -D enable debugging output\n\
- --old, --new select archive format\n\
- --nocheck suppress control file check (build bad package).\n\
- -z# to set the compression when building\n\
-\n\
-Format syntax:\n\
- A format is a string that will be output for each package. The format\n\
- can include the standard escape sequences \\n (newline), \\r (carriage\n\
- return) or \\\\ (plain backslash). Package information can be included\n\
- by inserting variable references to package fields using the ${var[;width]}\n\
- syntax. Fields will be right-aligned unless the width is negative in which\n\
- case left alignment will be used. \n\
-\n\
-Use `dpkg' to install and remove packages from your system, or\n\
-`dselect' for user-friendly package management. Packages unpacked\n\
-using `dpkg-deb --extract' will be incorrectly installed !\n"),
+ if (fputs(_(
+"Command:\n"
+" -b|--build <directory> [<deb>] build an archive.\n"
+" -c|--contents <deb> list contents.\n"
+" -I|--info <deb> [<cfile>...] show info to stdout.\n"
+" -W|--show <deb> show information on package(s)\n"
+" -f|--field <deb> [<cfield>...] show field(s) to stdout.\n"
+" -e|--control <deb> [<directory>] extract control info.\n"
+" -x|--extract <deb> <directory> extract files.\n"
+" -X|--vextract <deb> <directory> extract & list files.\n"
+" --fsys-tarfile <deb> output filesystem tarfile.\n"
+" -h|--help display this message.\n"
+" --version | --licence show version/licence.\n"
+"\n"
+"<deb> is the filename of a Debian format archive.\n"
+"<cfile> is the name of an administrative file component.\n"
+"<cfield> is the name of a field in the main `control' file.\n"
+"\n"
+"Options:\n"
+" --showformat=<format> use alternative format for --show\n"
+" -D enable debugging output\n"
+" --old, --new select archive format\n"
+" --nocheck suppress control file check (build bad package).\n"
+" -z# to set the compression when building\n"
+"\n"
+"Format syntax:\n"
+" A format is a string that will be output for each package. The format\n"
+" can include the standard escape sequences \\n (newline), \\r (carriage\n"
+" return) or \\\\ (plain backslash). Package information can be included\n"
+" by inserting variable references to package fields using the ${var[;width]}\n"
+" syntax. Fields will be right-aligned unless the width is negative in which\n"
+" case left alignment will be used. \n"
+"\n"
+"Use `dpkg' to install and remove packages from your system, or\n"
+"`dselect' for user-friendly package management. Packages unpacked\n"
+"using `dpkg-deb --extract' will be incorrectly installed !\n"),
stdout) < 0) werr("stdout");
}
diff -ruNp cvs-dpkg-1.10~/main/processarc.c cvs-dpkg-1.10/main/processarc.c
--- cvs-dpkg-1.10~/main/processarc.c 2003-10-25 21:03:21.000000000 +0100
+++ cvs-dpkg-1.10/main/processarc.c 2004-03-04 13:20:21.000000000 +0000
@@ -639,6 +639,20 @@ void process_archive(const char *filenam
} else
debug(dbg_eachfile, "process_archive: could not stat %s, skipping", fnamevb.buf);
if (donotrm) continue;
+ {
+ /*
+ * If file to remove is a device or s[gu]id, change its mode
+ * so that a malicious user cannot use it even if it's linked
+ * to another file.
+ */
+ struct stat stat_buf;
+ if (stat(fnamevb.buf,&stat_buf)==0) {
+ if (S_ISCHR(stat_buf.st_mode) || S_ISBLK(stat_buf.st_mode))
+ chmod(fnamevb.buf, 0);
+ if (stat_buf.st_mode & (S_ISUID|S_ISGID))
+ chmod(fnamevb.buf, stat_buf.st_mode & ~(S_ISUID|S_ISGID));
+ }
+ }
if (!unlink(fnamevb.buf)) continue;
if (errno == ENOTDIR) continue;
}
diff -ruNp cvs-dpkg-1.10~/main/remove.c cvs-dpkg-1.10/main/remove.c
--- cvs-dpkg-1.10~/main/remove.c 2003-10-25 21:03:21.000000000 +0100
+++ cvs-dpkg-1.10/main/remove.c 2004-03-04 13:20:21.000000000 +0000
@@ -339,6 +339,7 @@ static void removal_bulk_remove_leftover
varbufreset(&fnvb);
varbufaddstr(&fnvb,instdir);
varbufaddstr(&fnvb,namenodetouse(namenode,pkg)->name);
+ varbufaddc(&fnvb,0);
if (!stat(fnvb.buf,&stab) && S_ISDIR(stab.st_mode)) {
debug(dbg_eachfiledetail, "removal_bulk is a directory");
diff -ruNp cvs-dpkg-1.10~/version-nr cvs-dpkg-1.10/version-nr
--- cvs-dpkg-1.10~/version-nr 2003-10-27 19:42:05.000000000 +0000
+++ cvs-dpkg-1.10/version-nr 2004-03-04 13:20:21.000000000 +0000
@@ -1 +1 @@
-1.10.18
+1.10.18.1
diff -ruNp cvs-dpkg-1.10~/ChangeLog cvs-dpkg-1.10/ChangeLog
--- cvs-dpkg-1.10~/ChangeLog 2004-03-04 13:27:24.000000000 +0000
+++ cvs-dpkg-1.10/ChangeLog 2004-03-04 13:29:51.000000000 +0000
@@ -0,0 +1,7 @@
+Thu Mar 4 13:28:11 GMT 2004 Scott James Remnant <scott@netsplit.com>
+
+ * lib/tarfn.c: Copy the Name and LinkName elements and ensure they
+ are NULL-terminated, freeing these copies before returning. The
+ tar spec doesn't require a NULL byte if the filename is exactly
+ 100 characters long.
+
diff -ruNp cvs-dpkg-1.10~/debian/changelog cvs-dpkg-1.10/debian/changelog
--- cvs-dpkg-1.10~/debian/changelog 2004-03-04 13:27:24.000000000 +0000
+++ cvs-dpkg-1.10/debian/changelog 2004-03-04 13:30:42.000000000 +0000
@@ -0,0 +1,7 @@
+dpkg (1.10.18.2) unstable; urgency=high
+
+ * Non-maintainer upload.
+ * Force NULL-termination of all tar file entry names. Closes: #232025.
+
+ -- Scott James Remnant <scott@netsplit.com> Thu, 4 Mar 2004 13:29:53 +0000
+
diff -ruNp cvs-dpkg-1.10~/lib/tarfn.c cvs-dpkg-1.10/lib/tarfn.c
--- cvs-dpkg-1.10~/lib/tarfn.c 2002-08-29 20:58:11.000000000 +0100
+++ cvs-dpkg-1.10/lib/tarfn.c 2004-03-04 13:31:12.000000000 +0000
@@ -51,6 +51,21 @@ OtoL(const char * s, int size)
return n;
}
+/* String block to C null-terminated string */
+char *
+StoC(const char *s, int size)
+{
+ int len;
+ char * str;
+
+ len = strnlen(s, size);
+ str = malloc(len + 1);
+ memcpy(str, s, len);
+ str[len] = 0;
+
+ return str;
+}
+
static int
DecodeTarHeader(char * block, TarInfo * d)
{
@@ -67,8 +82,8 @@ DecodeTarHeader(char * block, TarInfo *
if ( *h->GroupName )
group = getgrnam(h->GroupName);
- d->Name = h->Name;
- d->LinkName = h->LinkName;
+ d->Name = StoC(h->Name, sizeof(h->Name));
+ d->LinkName = StoC(h->LinkName, sizeof(h->LinkName));
d->Mode = (mode_t)OtoL(h->Mode, sizeof(h->Mode));
d->Size = (size_t)OtoL(h->Size, sizeof(h->Size));
d->ModTime = (time_t)OtoL(h->ModificationTime
@@ -267,6 +282,8 @@ TarExtractor(
symListPointer = symListBottom;
}
free(symListPointer);
+ free(h.Name);
+ free(h.LinkName);
if ( status > 0 ) { /* Read partial header record */
errno = 0; /* Indicates broken tarfile */
return -1;
diff -ruNp cvs-dpkg~/ChangeLog cvs-dpkg/ChangeLog
--- cvs-dpkg~/ChangeLog 2003-10-18 10:52:16.000000000 +0100
+++ cvs-dpkg/ChangeLog 2004-03-04 13:24:13.000000000 +0000
@@ -0,0 +1,12 @@
+Thu Feb 26 01:48:15 GMT 2004 Scott James Remnant <scott@netsplit.com>
+
+ * main/processarc.c (process_archive): Copy code from main/remove.c
+ to ensure that hardlinks to devices, setuid files or setgid files
+ cannot be stashed away in the hope that they become compromisable
+ in the future. This was handled when removing a package, but not
+ when upgrading one.
+
+Fri Feb 20 10:22:24 CET 2004 Colin Watson <cjwatson@debian.org>
+
+ * dpkg-deb/main.c: Don't use multiline strings (a removed GCC extension).
+
diff -ruNp cvs-dpkg~/dpkg-deb/main.c cvs-dpkg/dpkg-deb/main.c
--- cvs-dpkg~/dpkg-deb/main.c 2002-09-12 04:48:26.000000000 +0100
+++ cvs-dpkg/dpkg-deb/main.c 2004-03-04 13:25:55.000000000 +0000
@@ -60,45 +60,44 @@ static void printversion(void) {
}
static void usage(void) {
- if (fputs(_("\
-Command:\n\
- -b|--build <directory> [<deb>] build an archive.\n\
- -c|--contents <deb> list contents.\n\
- -I|--info <deb> [<cfile>...] show info to stdout.\n\
- -W|--show <deb> Show information on package(s)\n\
- -f|--field <deb> [<cfield>...] show field(s) to stdout.\n\
- -e|--control <deb> [<directory>] extract control info.\n\
- -x|--extract <deb> <directory> extract files.\n\
- -X|--vextract <deb> <directory> extract & list files.\n\
- --fsys-tarfile <deb> output filesystem tarfile.\n\
- -h|--help display this message.\n\
- --version | --licence show version/licence.\n\
-\n\
-<deb> is the filename of a Debian format archive.\n\
-<cfile> is the name of an administrative file component.\n\
-<cfield> is the name of a field in the main `control' file.\n\
-\n\
-Options:\n\
- --showformat=<format> Use alternative format for --show\n\
- -D Enable debugging output\n\
- --old, --new select archive format\n\
- --nocheck suppress control file check (build bad package).\n\
- -z# to set the compression when building\n\
- -Z Set the compression type to use when building.\n\
- Allowed values: gzip, bzip2, stored\n\
-\n\
-Format syntax:\n\
- A format is a string that will be output for each package. The format\n\
- can include the standard escape sequences \\n (newline), \\r (carriage\n\
- return) or \\\\ (plain backslash). Package information can be included\n\
- by inserting variable references to package fields using the ${var[;width]}\n\
- syntax. Fields will be right-aligned unless the width is negative in which\n\
- case left aligenment will be used. \n\
-\n\
-
-Use `dpkg' to install and remove packages from your system, or\n\
-`dselect' for user-friendly package management. Packages unpacked\n\
-using `dpkg-deb --extract' will be incorrectly installed !\n"),
+ if (fputs(_(
+"Command:\n"
+" -b|--build <directory> [<deb>] build an archive.\n"
+" -c|--contents <deb> list contents.\n"
+" -I|--info <deb> [<cfile>...] show info to stdout.\n"
+" -W|--show <deb> Show information on package(s)\n"
+" -f|--field <deb> [<cfield>...] show field(s) to stdout.\n"
+" -e|--control <deb> [<directory>] extract control info.\n"
+" -x|--extract <deb> <directory> extract files.\n"
+" -X|--vextract <deb> <directory> extract & list files.\n"
+" --fsys-tarfile <deb> output filesystem tarfile.\n"
+" -h|--help display this message.\n"
+" --version | --licence show version/licence.\n"
+"\n"
+"<deb> is the filename of a Debian format archive.\n"
+"<cfile> is the name of an administrative file component.\n"
+"<cfield> is the name of a field in the main `control' file.\n"
+"\n"
+"Options:\n"
+" --showformat=<format> Use alternative format for --show\n"
+" -D Enable debugging output\n"
+" --old, --new select archive format\n"
+" --nocheck suppress control file check (build bad package).\n"
+" -z# to set the compression when building\n"
+" -Z Set the compression type to use when building.\n"
+" Allowed values: gzip, bzip2, stored\n"
+"\n"
+"Format syntax:\n"
+" A format is a string that will be output for each package. The format\n"
+" can include the standard escape sequences \\n (newline), \\r (carriage\n"
+" return) or \\\\ (plain backslash). Package information can be included\n"
+" by inserting variable references to package fields using the ${var[;width]}\n"
+" syntax. Fields will be right-aligned unless the width is negative in which\n"
+" case left aligenment will be used. \n"
+"\n"
+"Use `dpkg' to install and remove packages from your system, or\n"
+"`dselect' for user-friendly package management. Packages unpacked\n"
+"using `dpkg-deb --extract' will be incorrectly installed !\n"),
stdout) < 0) werr("stdout");
}
diff -ruNp cvs-dpkg~/main/processarc.c cvs-dpkg/main/processarc.c
--- cvs-dpkg~/main/processarc.c 2002-09-11 03:08:00.000000000 +0100
+++ cvs-dpkg/main/processarc.c 2004-03-04 13:23:32.000000000 +0000
@@ -647,6 +647,20 @@ void process_archive(const char *filenam
} else
debug(dbg_eachfile, "process_archive: could not stat %s, skipping", fnamevb.buf);
if (donotrm) continue;
+ {
+ /*
+ * If file to remove is a device or s[gu]id, change its mode
+ * so that a malicious user cannot use it even if it's linked
+ * to another file.
+ */
+ struct stat stat_buf;
+ if (stat(fnamevb.buf,&stat_buf)==0) {
+ if (S_ISCHR(stat_buf.st_mode) || S_ISBLK(stat_buf.st_mode))
+ chmod(fnamevb.buf, 0);
+ if (stat_buf.st_mode & (S_ISUID|S_ISGID))
+ chmod(fnamevb.buf, stat_buf.st_mode & ~(S_ISUID|S_ISGID));
+ }
+ }
if (!unlink(fnamevb.buf)) continue;
if (errno == ENOTDIR) continue;
}
diff -ruNp cvs-dpkg~/ChangeLog cvs-dpkg/ChangeLog
--- cvs-dpkg~/ChangeLog 2004-03-04 13:31:57.000000000 +0000
+++ cvs-dpkg/ChangeLog 2004-03-04 13:32:05.000000000 +0000
@@ -0,0 +1,7 @@
+Thu Mar 4 13:28:11 GMT 2004 Scott James Remnant <scott@netsplit.com>
+
+ * lib/tarfn.c: Copy the Name and LinkName elements and ensure they
+ are NULL-terminated, freeing these copies before returning. The
+ tar spec doesn't require a NULL byte if the filename is exactly
+ 100 characters long.
+
diff -ruNp cvs-dpkg~/lib/tarfn.c cvs-dpkg/lib/tarfn.c
--- cvs-dpkg~/lib/tarfn.c 2002-09-09 02:50:14.000000000 +0100
+++ cvs-dpkg/lib/tarfn.c 2004-03-04 13:32:05.000000000 +0000
@@ -51,6 +51,21 @@ OtoL(const char * s, int size)
return n;
}
+/* String block to C null-terminated string */
+char *
+StoC(const char *s, int size)
+{
+ int len;
+ char * str;
+
+ len = strnlen(s, size);
+ str = malloc(len + 1);
+ memcpy(str, s, len);
+ str[len] = 0;
+
+ return str;
+}
+
static int
DecodeTarHeader(char * block, TarInfo * d)
{
@@ -67,8 +82,8 @@ DecodeTarHeader(char * block, TarInfo *
if ( *h->GroupName )
group = getgrnam(h->GroupName);
- d->Name = h->Name;
- d->LinkName = h->LinkName;
+ d->Name = StoC(h->Name, sizeof(h->Name));
+ d->LinkName = StoC(h->LinkName, sizeof(h->LinkName));
d->Mode = (mode_t)OtoL(h->Mode, sizeof(h->Mode));
d->Size = (size_t)OtoL(h->Size, sizeof(h->Size));
d->ModTime = (time_t)OtoL(h->ModificationTime
@@ -269,6 +284,8 @@ TarExtractor(
symListPointer = symListBottom;
}
free(symListPointer);
+ free(h.Name);
+ free(h.LinkName);
if ( status > 0 ) { /* Read partial header record */
errno = 0; /* Indicates broken tarfile */
return -1;
Attachment:
signature.asc
Description: This is a digitally signed message part