Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Mar 2002 02:04:26 -0800 (PST)
From:      Lamont Granquist <lamont@scriptkiddie.org>
To:        <hackers@freebsd.org>
Subject:   jail bug with ircd-hybrid in_pcbconnect()?
Message-ID:  <20020318015154.X831-100000@coredump.scriptkiddie.org>
In-Reply-To: <20020318103038.A9497@cobweb.example.org>

next in thread | previous in thread | raw e-mail | index | archive | help

I've been digging through kernel sources trying to figure out this bug
with ircd-hybrid in the ports tree against 4.5-STABLE.  The symptom is
that in ircd-hybrid there's a sequence of system calls like this:

sendto(2, "\252D\1\0\0\1\0\0\0\0\0\0\00238\003142\003162\003209\7"..., 45,
0, {sin_family=AF_INET, sin_port=htons(53),
sin_addr=inet_addr("63.102.48.45")}}, 16) = 45

sendto(2, "\370N\1\0\0\1\0\0\0\0\0\0\21uswest-dsl-142-38\10c"..., 48, 0,
{sin_family=AF_INET, sin_port=htons(53),
sin_addr=inet_addr("63.102.48.45")}}, 16) = -1 EINVAL (Invalid argument)

sendto(2, "\221\343\1\0\0\1\0\0\0\0\0\0\21uswest-dsl-142-38\10c"..., 48,
0, {sin_family=AF_INET, sin_port=htons(53),
sin_addr=inet_addr("63.102.48.45")}}, 16) = -1 EINVAL (Invalid argument)

sendto(2, "\221\343\1\0\0\1\0\0\0\0\0\0\21uswest-dsl-142-38\10c"..., 48,
0, {sin_family=AF_INET, sin_port=htons(53),
sin_addr=inet_addr("216.17.175.159")}}, 16) = -1 EINVAL (Invalid argument)

(This is obviously a sendto() on a UDP socket that is talking to a DNS
server to do name resolution)

Now, that's inside of a jail.  Outside of a jail all of those succeed.  I
don't see any reason for those latter 3 to fail inside of jail for any
reasons having to do with the security of the jail.  There's also nothing
relevant happening to descriptor 2 in between those system calls.

The latter 3 sendto()s fail in in_pcbconnect() right in the beginning when
it calls in_pcbbind():

in_pcbconnect(inp, nam, p)
        register struct inpcb *inp;
        struct sockaddr *nam;
        struct proc *p;
{
        struct sockaddr_in *ifaddr;
        struct sockaddr_in *sin = (struct sockaddr_in *)nam;
        struct sockaddr_in sa;
        int error;

        if (inp->inp_laddr.s_addr == INADDR_ANY && p->p_prison != NULL) {
                bzero(&sa, sizeof (sa));
                sa.sin_addr.s_addr = htonl(p->p_prison->pr_ip);
                sa.sin_len=sizeof (sa);
                sa.sin_family = AF_INET;
                error = in_pcbbind(inp, (struct sockaddr *)&sa, p);
                if (error) {
                        printf("in_pcbconnect error 1\n");
                        return (error);
                }
        }
[...snippage...]

And its failing this test in in_pcbbind():

in_pcbbind(inp, nam, p)
        register struct inpcb *inp;
        struct sockaddr *nam;
        struct proc *p;
{
[...]
        if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY) {
                printf("in_pcbbind error 4\n");
                return (EINVAL);
        }
[...]

I'm guessing right now that inp_lport in the pcb is getting set during the
first system call, and causing the subsequent ones to fail.  I don't have
all the answers though, and I need to get some sleep...  Hoping someone
who understands the pcb functions can point out exactly what the error is
in here -- this is the first time i've ever looked at them...


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020318015154.X831-100000>