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