]> git.hungrycats.org Git - linux/commitdiff
[AF_PACKET]: Fix bind()/setsockopt(PACKET_RX_RING) bug and socket leak.
authorHirofumi Ogawa <hirofumi@mail.parknet.co.jp>
Thu, 15 Jan 2004 04:00:37 +0000 (20:00 -0800)
committerDavid S. Miller <davem@nuts.ninka.net>
Thu, 15 Jan 2004 04:00:37 +0000 (20:00 -0800)
This problem was the bug of packet_set_ring(). packet_set_ring()
removes the hook for preparation of ring buffer, but it didn't
restore.

Also it's leaking the refcount of sk.

net/packet/af_packet.c

index 3b1e907174e080223c704329c1a1880df2c7b1b0..3b01f540b652652a948e6c929eef9f81a01ea136 100644 (file)
@@ -1550,7 +1550,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
        unsigned long *pg_vec = NULL;
        struct tpacket_hdr **io_vec = NULL;
        struct packet_opt *po = pkt_sk(sk);
-       int order = 0;
+       int was_running, num, order = 0;
        int err = 0;
 
        if (req->tp_block_nr) {
@@ -1623,10 +1623,13 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
 
        /* Detach socket from network */
        spin_lock(&po->bind_lock);
-       if (po->running) {
+       was_running = po->running;
+       num = po->num;
+       if (was_running) {
                __dev_remove_pack(&po->prot_hook);
                po->num = 0;
                po->running = 0;
+               __sock_put(sk);
        }
        spin_unlock(&po->bind_lock);
                
@@ -1657,8 +1660,12 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
        }
 
        spin_lock(&po->bind_lock);
-       if (po->running)
+       if (was_running && !po->running) {
+               sock_hold(sk);
+               po->running = 1;
+               po->num = num;
                dev_add_pack(&po->prot_hook);
+       }
        spin_unlock(&po->bind_lock);
 
        release_sock(sk);