VNET mismanagement in bpf(4) ?

Arnaud Lacombe lacombar at gmail.com
Sat Sep 24 08:19:55 UTC 2011


Hi,

It seems to me there is a VNET mismanagement in `net/bpf.c'; we have:

static void
bpf_detachd(struct bpf_d *d)
{
[...]
    if (d->bd_promisc) {
        d->bd_promisc = 0;
        CURVNET_SET(ifp->if_vnet);
        error = ifpromisc(ifp, 0);
        CURVNET_RESTORE();
[...]
}

which is called by either bpfdetach() or bpf_setdlt(). Here is the
relevant code block of the latter:

static int
bpf_setdlt(struct bpf_d *d, u_int dlt)
{
[...]
    if (bp != NULL) {
        opromisc = d->bd_promisc;
        bpf_detachd(d);
        bpf_attachd(d, bp);
        BPFD_LOCK(d);
        reset_d(d);
        BPFD_UNLOCK(d);
        if (opromisc) {
            error = ifpromisc(bp->bif_ifp, 1);
            if (error)
                if_printf(bp->bif_ifp,
                    "bpf_setdlt: ifpromisc failed (%d)\n",
                    error);
            else
                d->bd_promisc = 1;
        }
[...]
}

I would guess that there is no need to `CURVNET_SET(ifp->if_vnet);'
before calling `ifpromisc()' because it has already been done in
`bpfioctl()':

static  int
bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
    struct thread *td)
{
[...]
    CURVNET_SET(TD_TO_VNET(td));
[...]
    /*
     * Set data link type.
     */
    case BIOCSDLT:
        if (d->bd_bif == NULL)
            error = EINVAL;
        else
            error = bpf_setdlt(d, *(u_int *)addr);
        break;
[...]
    CURVNET_RESTORE();
    return (error);
}

However, the following call path:

bpfioctl() ->
  bpf_setdlt() ->
    bpf_detachd() ->
    [ret]
  bpf_setdlt() ->
  [ret]
bpfioctl()
[ret]

will end up in the following sequence of VNET setting/restore:

bpfioctl():CURVNET_SET(TD_TO_VNET(td)) ->
  bpf_detachd():CURVNET_SET(ifp->if_vnet) ->
  bpf_detachd():CURVNET_RESTORE() ->
bpfioctl():CURVNET_RESTORE()

leading to the lost of the original VNET, from bpfioctl().

Am I missing something ?

Thanks,
 - Arnaud


More information about the freebsd-net mailing list