Subject: kern/18751: struct secashead underalloc'd
To: None <gnats-bugs@gnats.netbsd.org>
From: None <seanb@qnx.com>
List: netbsd-bugs
Date: 10/21/2002 07:26:51
>Number:         18751
>Category:       kern
>Synopsis:       struct secashead underalloc'd
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Oct 21 07:27:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Sean Boudreau
>Release:        1-5
>Organization:
QNX
>Environment:
NetBSD fili 1.5.1 NetBSD 1.5.1 (ker.xtang) #2: Mon Jul 30 09:33:07 EDT 2001     root@fili:/usr/src/sys/arch/i386/compile/ker.xtang i386
>Description:
Think struct secashead should look something like:


struct secashead {
    LIST_ENTRY(secashead) chain;

    struct secasindex saidx;

    struct sadb_ident *idents;  /* source identity */
    struct sadb_ident *identd;  /* destination identity */
                    /* XXX I don't know how to use them. */

    uint8_t state;          /* MATURE or DEAD. */
    LIST_HEAD(_satree, secasvar) savtree[SADB_SASTATE_MAX+1];
                    /* SA chain */
                    /* The first of this list is newer SA */

    union {
        struct route sau_route; /* route cache */
#ifdef INET6
        struct route_in6 sau_route6;
#endif
    } sa_u;
};

Otherwise, the following block of code from ipsec6_output_tunnel()
has issues: the cast in the assignment of dst6 is invalid and the
subsequent dereference of dst6 walks off the end of the struct
struct secashead.

state->ro = &isr->sav->sah->sa_route;
state->dst = (struct sockaddr *)&state->ro->ro_dst;
dst6 = (struct sockaddr_in6 *)state->dst;
if (state->ro->ro_rt
 && ((state->ro->ro_rt->rt_flags & RTF_UP) == 0
  || !IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ip6->ip6_dst))) {
    RTFREE(state->ro->ro_rt);
    bzero((caddr_t)state->ro, sizeof (*state->ro));
}
if (state->ro->ro_rt == 0) {
    bzero(dst6, sizeof(*dst6));
    dst6->sin6_family = AF_INET6;
    dst6->sin6_len = sizeof(*dst6);
    dst6->sin6_addr = ip6->ip6_dst;
    rtalloc(state->ro);
}
>How-To-Repeat:
Use ipsec tunnel over ipv6.
>Fix:
See description.
>Release-Note:
>Audit-Trail:
>Unformatted: