Date: Wed, 22 Jan 2003 19:55:30 +0200 From: Giorgos Keramidas <keramida@freebsd.org> To: freebsd-audit@freebsd.org Subject: Re: hopefully, a fix for an old uncompress(1) bug Message-ID: <20030122175530.GA2026@gothmog.gr> In-Reply-To: <20030107040216.GB4071@gothmog.gr> References: <20030106062309.GA37109@gothmog.gr> <20030106080949.GA382@straylight.oblivion.bg> <20030106082154.GE1094@gothmog.gr> <20030107040216.GB4071@gothmog.gr>
index | next in thread | previous in thread | raw e-mail
I have tested the patch in the post quoted below and it seems to work
around the bugs in uncompress(1). What do I need to do to get
approval for commiting this or a "no, this is not good because [foo]"
type of review?
- Giorgos
On 2003-01-07 06:02, Giorgos Keramidas <keramida@FreeBSD.ORG> wrote:
> [...]
> The first problem is that decompress() tries to open the output file
> first and then notice that its input file (foo.Z) fails to zopen().
> When this happens, it promptly goes ahead and tries to unlink `foo'
> which is supposed to be the outfile. If a file happens to be named
> `foo' it is unconditionally removed. This is the behavior shown
> below:
>
> % ls -l
> -rw-rw-r-- 1 giorgos wheel - 0 Jan 6 08:04 lala
> % uncompress -f lala
> uncompress: lala.Z: No such file or directory
> % ls -l
> %
>
> Reversing the order of `in' and `out' file opening fixes this problem,
> but there is one more which is a bit more difficult to notice.
>
> The second problem. If the input file of decompress() does exist but
> is not a valid .Z file the zopen() call will work fine only to fail
> later on when we try to fread() data from it. This is shown below:
>
> $ cp /COPYRIGHT lala.Z
> $ touch lala
> $ ls -l lala*
> -rw-rw-r-- 1 giorgos giorgos - 0 Jan 7 05:42 lala
> -r--r--r-- 1 giorgos giorgos - 4735 Jan 7 05:42 lala.Z
> $ ./uncompress -f lala
> uncompress: lala.Z: Inappropriate file type or format
> $ ls -l lala*
> -r--r--r-- 1 giorgos giorgos - 4735 Jan 7 05:42 lala.Z
> $
>
> I tried to solve this, by attempting to successfully read at least one
> byte of data from the .Z file before even attempting to open the
> output file. I also changed all the `goto err' parts before the
> output file is opened to avoid unlinking() a file that we haven't
> previously fopen()ed.
>
> Hopefully, this fixes both the problems :-/
>
> %%%
> Index: compress.c
> ===================================================================
> RCS file: /home/ncvs/src/usr.bin/compress/compress.c,v
> retrieving revision 1.20
> diff -u -r1.20 compress.c
> --- compress.c 28 Jul 2002 15:32:17 -0000 1.20
> +++ compress.c 7 Jan 2003 03:57:26 -0000
> @@ -300,14 +300,9 @@
> isreg = oreg = !exists || S_ISREG(sb.st_mode);
>
> ifp = ofp = NULL;
> - if ((ofp = fopen(out, "w")) == NULL) {
> - cwarn("%s", out);
> - return;
> - }
> -
> if ((ifp = zopen(in, "r", bits)) == NULL) {
> cwarn("%s", in);
> - goto err;
> + return;
> }
> if (stat(in, &sb)) {
> cwarn("%s", in);
> @@ -315,6 +310,18 @@
> }
> if (!S_ISREG(sb.st_mode))
> isreg = 0;
> +
> + /*
> + * Try to read the first few uncompressed bytes from the input file
> + * before blindly truncating the output file.
> + */
> + if ((nr = fread(buf, 1, sizeof(buf), ifp)) == 0 ||
> + (ofp = fopen(out, "w")) == NULL ||
> + (nr != 0 && fwrite(buf, 1, nr, ofp) != nr)) {
> + cwarn("%s", out);
> + (void)fclose(ifp);
> + return;
> + }
>
> while ((nr = fread(buf, 1, sizeof(buf), ifp)) != 0)
> if (fwrite(buf, 1, nr, ofp) != nr) {
> %%%
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030122175530.GA2026>
