[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: /dev/fd/n bug in gawk 3.1.5
From: |
Aharon Robbins |
Subject: |
Re: /dev/fd/n bug in gawk 3.1.5 |
Date: |
Thu, 15 Jun 2006 06:00:59 +0300 |
Andrew,
I think your analysis is pretty much on target. I rearranged some of
this code some time back. I will take a hard look at this as soon
as I can.
The reuse of the buffer is important for things like /dev/user.
John, thanks for the report and the test case.
Arnold
> Date: Wed, 14 Jun 2006 09:12:44 -0400
> From: "Andrew J. Schorr" <address@hidden>
> Subject: Re: /dev/fd/n bug in gawk 3.1.5
> To: "John H. DuBois III" <address@hidden>
> Cc: address@hidden
>
> On Tue, Jun 13, 2006 at 05:49:58PM -0700, John H. DuBois III wrote:
> > $ cat /dev/fd/4 /dev/fd/5 4<tm1 5<tm2
> > Contents of tm1
> > Contents of tm2
> > $ gawk 1 /dev/fd/4 /dev/fd/5 4<tm1 5<tm2
> > Contents of tm1
> > Contents of tm1
> >
> >
> > gawk: (FILENAME=/dev/fd/5 FNR=3) fatal: error reading input file
> > `/dev/fd/4': Bad file number
>
> This looks like a bug in iop_open to me. On linux, valgrind shows:
>
> ==4785== Conditional jump or move depends on uninitialised value(s)
> ==4785== at 0x4A1F3D7: strlen (mac_replace_strmem.c:243)
> ==4785== by 0x42206E: spec_setup (io.c:1433)
> ==4785== by 0x423251: iop_open (io.c:1576)
> ==4785== by 0x4234A2: nextfile (io.c:280)
> ==4785== by 0x4241A6: do_input (io.c:445)
> ==4785== by 0x4282A3: main (main.c:595)
> ==4785==
> ==4785== Invalid write of size 1
> ==4785== at 0x422082: spec_setup (io.c:1435)
> ==4785== by 0x423251: iop_open (io.c:1576)
> ==4785== by 0x4234A2: nextfile (io.c:280)
> ==4785== by 0x4241A6: do_input (io.c:445)
> ==4785== by 0x4282A3: main (main.c:595)
> ==4785== Address 0x4FE4A8A is 0 bytes after a block of size 18 alloc'd
> ==4785== at 0x4A1D9D6: malloc (vg_replace_malloc.c:149)
> ==4785== by 0x422ECF: iop_alloc (io.c:2509)
> ==4785== by 0x424C26: specfdopen (io.c:1457)
> ==4785== by 0x423297: iop_open (io.c:1578)
> ==4785== by 0x4234A2: nextfile (io.c:280)
> ==4785== by 0x4241A6: do_input (io.c:445)
> ==4785== by 0x4282A3: main (main.c:595)
> ...
>
> And this logic seems problematic to me:
>
> tatic IOBUF *
> iop_open(const char *name, const char *mode, IOBUF *iop)
> {
> int openfd = INVALID_HANDLE;
> int flag = 0;
> static struct internal {
> const char *name;
> int compare;
> int (*fp) P((IOBUF *, const char *, const char *));
> IOBUF iob;
> } table[] = {
> { "/dev/fd/", 8, specfdopen },
> { "/dev/stdin", 10, specfdopen },
> { "/dev/stdout", 11, specfdopen },
> { "/dev/stderr", 11, specfdopen },
> { "/inet/", 6, specfdopen },
> { "/dev/pid", 8, pidopen },
> { "/dev/ppid", 9, pidopen },
> { "/dev/pgrpid", 11, pidopen },
> { "/dev/user", 9, useropen },
> };
> int devcount = sizeof(table) / sizeof(table[0]);
> ...
> if (STREQN(name, table[i].name, table[i].compare)) {
> iop = & table[i].iob;
>
> if (iop->buf != NULL) {
> spec_setup(iop, 0, FALSE);
> return iop;
> } else if ((*table[i].fp)(iop, name, mode) ==
> 0)
> return iop;
> else {
> warning(_("could not open `%s', mode
> `%s
> '"),
> name, mode);
> return NULL;
> }
> }
> ...
>
> If I'm not misreading this, it looks like the attempt to open /dev/fd/5 will
> end up using the same static IOBUF that was previously used for /dev/fd/4, and
> I think that iop->buf will not be NULL, since iop_close will not free iop->buf
> (since specfdopen sets the IOP_NO_FREE flag). And I don't think the
> spec_setup
> call is doing what's needed (it looks like devopen is not getting called for
> the new file, etc.). I'm not quite sure how to fix this, since I'm not quite
> understanding at the moment why the static IOBUF is being used in the first
> place. Is the goal here to handle correctly the case where the same special
> file name is used more than once? It looks to me like these problems may also
> affect /inet filenames. Or perhaps I'm just totally confused.
>
> Regards,
> Andy