From 374458b3fe4288f820dbf3de0728e314d969f9e4 Mon Sep 17 00:00:00 2001 From: Dmitry Tarnyagin Date: Sun, 11 Mar 2012 10:28:31 +0000 Subject: caif: Fix for a race in socket transmit with flow control. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kill faulty checks on flow-off leading to connection drop at race conditions. caif_socket checks for flow-on before transmitting and goes to sleep or return -EAGAIN upon flow stop. Remove faulty subsequent checks on flow-off leading to connection drop. Also fix memory leaks on some of the errors paths. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- net/caif/cfrfml.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'net/caif/cfrfml.c') diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index 6dc75d4f8d9..2b563ad0459 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c @@ -184,6 +184,11 @@ out: rfml->serv.dev_info.id); } spin_unlock(&rfml->sync); + + if (unlikely(err == -EAGAIN)) + /* It is not possible to recover after drop of a fragment */ + err = -EIO; + return err; } @@ -218,7 +223,7 @@ static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt) caif_assert(layr->dn->transmit != NULL); if (!cfsrvl_ready(&rfml->serv, &err)) - return err; + goto out; err = -EPROTO; if (cfpkt_getlen(pkt) <= RFM_HEAD_SIZE-1) @@ -251,8 +256,11 @@ static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt) err = cfrfml_transmit_segment(rfml, frontpkt); - if (err != 0) + if (err != 0) { + frontpkt = NULL; goto out; + } + frontpkt = rearpkt; rearpkt = NULL; @@ -286,19 +294,8 @@ out: if (rearpkt) cfpkt_destroy(rearpkt); - if (frontpkt && frontpkt != pkt) { - + if (frontpkt) cfpkt_destroy(frontpkt); - /* - * Socket layer will free the original packet, - * but this packet may already be sent and - * freed. So we have to return 0 in this case - * to avoid socket layer to re-free this packet. - * The return of shutdown indication will - * cause connection to be invalidated anyhow. - */ - err = 0; - } } return err; -- cgit v1.2.3