bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: /dev/fd/n bug in gawk 3.1.5


From: Andrew J. Schorr
Subject: Re: /dev/fd/n bug in gawk 3.1.5
Date: Wed, 14 Jun 2006 09:12:44 -0400
User-agent: Mutt/1.4.2.1i

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]