Re: [PATCH v2 3/3] pppoatm: protect against freeing of vcc

From: chas williams - CONTRACTOR
Date: Thu Nov 29 2012 - 13:29:12 EST


On Thu, 29 Nov 2012 18:11:48 +0000
David Woodhouse <dwmw2@xxxxxxxxxxxxx> wrote:

> We do see the 'packet received for unknown VCC' complaint, after we
> reboot the host without resetting the card. And as shown in the commit I
> just referenced, we rely on the !ATM_VF_READY check in order to prevent
> a use-after-free when the tasklet is sending packets up a VCC that's
> just been closed.

well that behavior is just crap. why is it delivering cells for a
vpi/vci pair that is not open? regardless, i pointed out the behavior
of find_vcc() just in case you need to do some clean up on data that is
coming back while you are attempting to finish operations during your
driver's close() but this cleanup might not be happening since you
arent able to get a reference to the vcc so you can pop() the data or
whatever you might need to do.

> > again part of this is poor synchronization. the detach protocol (i.e.
> > push of a NULL skb) should be flushing any pending transmits and
> > shutting down whatever in the protocol is doing any sending and
> > receiving. however, i release this might be difficult to do since the
> > detach protocol is invoked in such a strange way.
>
> You mean that (e.g.) pppoatm_push(vcc, NULL) should be waiting for any
> pending TX skb (that has already been passed off to the driver) to
> *complete*? How would it even do that?

i think the order of the vcc_destroy_socket() operations is a bit
wrong. it should call detach protocol (i.e. push a NULL). this should
cause the attached protocol to stop any future sends and receives, and
it CAN sleep in this context (and only this context -- generally
sending cannot sleep which is why this might seem confusing) to do
whatever it needs to do to wait for the attached protocol to clean up
queues, flush data etc.

then the driver close() should be called. this takes care of cleaning
up any pending tx or rx that is in the hardware. and of course,
close() can sleep since it will be in a interrutible context.

the pop() might be screwed up here though. you might have skb's in the
driver that should be pop()'ed with the formerly attached protocol.

you could wait for pending tx's sent to the driver. you know that your
attached protocol's pop() will be called. keep count of the
outstanding transmit skb's. you cant do this though if you close() the
vcc before you detach the protocol.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/