very good. thanks.

one wired thing is that the string pointer (0xfb900) it 
tried to free (char *domain) points in the middle of the
querylck array of a allocated DN.

thats not a valid alloc block indeed.

there migh'v been a block there, but it got accidently freed
and then the space reused for that DN, or the pointer itself
got corrupted (only possible from our current process as its
stored on the stack which is private to our proc).

theres a block (0xfb9a0) after it that satisfies the requirement
of being the real thing (alloc callerpc is right after the smprint(),
still valid ip address string).

the char *domain pointer is stored on the stack at 0x74(SP).
char conndir[40] starts at 0x4c(SP). 0x4c+40 = 0x74 so if
dial overflows conndir (off by one error?) it could indeed
trash that pointer overriding the lsb of char *domain resulting
in bogus 0xfb900 address instead of 0xfb9a0.

acid: dump(0xdfffc8b4, 44/4, "X")
0xdfffc8b4: 0x74656e2f <- char conndir[40]
0xdfffc8b8: 0x7063742f 
0xdfffc8bc: 0x0000392f 
0xdfffc8c0: 0x00000000 
0xdfffc8c4: 0x00000000 
0xdfffc8c8: 0x00000000 
0xdfffc8cc: 0x00000000 
0xdfffc8d0: 0x00000000 
0xdfffc8d4: 0x00000000 
0xdfffc8d8: 0x00000000 
0xdfffc8dc: 0x000fb900 <- char *domain

/sys/include/libc.h:480: #define NETPATHLEN 40

from sources /sys/src/libc/9sys/dial.c

static int
fillinds(DS *ds, Dest *dp)
{
        Conn *conn;

        if (dp->winner < 0)
                return -1;
        conn = &dp->conn[dp->winner];
        if (ds->cfdp)
                *ds->cfdp = conn->cfd;
        if (ds->dir) {
                strncpy(ds->dir, conn->dir, NETPATHLEN);
                ds->dir[NETPATHLEN] = '\0';     <---- fuck!
        }
        return conn->dfd;
}

this bug was introduced with the new parallel dial implementation.
the old sequential dial doesnt have this bug so 9front systems are
not affected.

someone make a patch.

--
cinap

Reply via email to