forked from Minki/linux
atm: fix a UAF in lec_arp_clear_vccs()
Gengming reported a UAF in lec_arp_clear_vccs(), where we add a vcc socket to an entry in a per-device list but free the socket without removing it from the list when vcc->dev is NULL. We need to call lec_vcc_close() to search and remove those entries contain the vcc being destroyed. This can be done by calling vcc->push(vcc, NULL) unconditionally in vcc_destroy_socket(). Another issue discovered by Gengming's reproducer is the vcc->dev may point to the static device lecatm_dev, for which we don't need to register/unregister device, so we can just check for vcc->dev->ops->owner. Reported-by: Gengming Liu <l.dmxcsnsbh@gmail.com> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
44d95cc6b1
commit
93a2014afb
@ -177,18 +177,18 @@ static void vcc_destroy_socket(struct sock *sk)
|
|||||||
|
|
||||||
set_bit(ATM_VF_CLOSE, &vcc->flags);
|
set_bit(ATM_VF_CLOSE, &vcc->flags);
|
||||||
clear_bit(ATM_VF_READY, &vcc->flags);
|
clear_bit(ATM_VF_READY, &vcc->flags);
|
||||||
if (vcc->dev) {
|
if (vcc->dev && vcc->dev->ops->close)
|
||||||
if (vcc->dev->ops->close)
|
vcc->dev->ops->close(vcc);
|
||||||
vcc->dev->ops->close(vcc);
|
if (vcc->push)
|
||||||
if (vcc->push)
|
vcc->push(vcc, NULL); /* atmarpd has no push */
|
||||||
vcc->push(vcc, NULL); /* atmarpd has no push */
|
module_put(vcc->owner);
|
||||||
module_put(vcc->owner);
|
|
||||||
|
|
||||||
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
|
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
|
||||||
atm_return(vcc, skb->truesize);
|
atm_return(vcc, skb->truesize);
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vcc->dev && vcc->dev->ops->owner) {
|
||||||
module_put(vcc->dev->ops->owner);
|
module_put(vcc->dev->ops->owner);
|
||||||
atm_dev_put(vcc->dev);
|
atm_dev_put(vcc->dev);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user