diff options
author | rsc <devnull@localhost> | 2007-04-08 01:30:26 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2007-04-08 01:30:26 +0000 |
commit | 4f6d2bb1e8e38aaeeeabb159272da19718bfb05d (patch) | |
tree | 100758b863425d60071fea95e1ffb3a6ed0ada15 /src/libventi/send.c | |
parent | 8ecb4ffe4c618bb484299a4a3b29f2a991903e53 (diff) | |
download | plan9port-4f6d2bb1e8e38aaeeeabb159272da19718bfb05d.tar.gz plan9port-4f6d2bb1e8e38aaeeeabb159272da19718bfb05d.tar.bz2 plan9port-4f6d2bb1e8e38aaeeeabb159272da19718bfb05d.zip |
correct dangling pointer race (Bakul Shah)
Diffstat (limited to 'src/libventi/send.c')
-rw-r--r-- | src/libventi/send.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/libventi/send.c b/src/libventi/send.c index 7ada51af..70cc8272 100644 --- a/src/libventi/send.c +++ b/src/libventi/send.c @@ -147,7 +147,7 @@ vtrecvproc(void *v) _vtqhangup(q); while((p = _vtnbqrecv(q)) != nil) packetfree(p); - _vtqfree(q); + _vtqdecref(q); z->readq = nil; rwakeup(&z->rpcfork); qunlock(&z->lk); @@ -178,7 +178,7 @@ vtsendproc(void *v) _vtqhangup(q); while((p = _vtnbqrecv(q)) != nil) packetfree(p); - _vtqfree(q); + _vtqdecref(q); z->writeq = nil; rwakeup(&z->rpcfork); qunlock(&z->lk); @@ -189,6 +189,7 @@ Packet* vtrecv(VtConn *z) { Packet *p; + Queue *q; qlock(&z->lk); if(z->state != VtStateConnected){ @@ -197,8 +198,11 @@ vtrecv(VtConn *z) return nil; } if(z->readq){ + q = _vtqincref(z->readq); qunlock(&z->lk); - return _vtqrecv(z->readq); + p = _vtqrecv(q); + _vtqdecref(q); + return p; } qlock(&z->inlk); @@ -213,6 +217,8 @@ vtrecv(VtConn *z) int vtsend(VtConn *z, Packet *p) { + Queue *q; + qlock(&z->lk); if(z->state != VtStateConnected){ packetfree(p); @@ -221,11 +227,14 @@ vtsend(VtConn *z, Packet *p) return -1; } if(z->writeq){ + q = _vtqincref(z->writeq); qunlock(&z->lk); - if(_vtqsend(z->writeq, p) < 0){ + if(_vtqsend(q, p) < 0){ + _vtqdecref(q); packetfree(p); return -1; } + _vtqdecref(q); return 0; } |