diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-05-05 03:56:11 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-05-05 03:56:11 +0200 |
commit | 9500191af630673a28266cab9b4e109275847c90 (patch) | |
tree | 65a9c6d857fcc29eaf0aeda1b360157b83266775 /sys/src/9/ip/devip.c | |
parent | 30d7276d693a45153140248bc4cf09d72c554030 (diff) |
devip: handle malloc errors, fix queue leaks
Fsprotocone():
qopen() and qbypass() can fail and return nil, so make sure
the connection was not partially created by checking if read
and write queues have been setup by the protocol create hanler.
on error, free any resources of the partial connection and
error out.
netlogopen(): check malloc() error.
Diffstat (limited to 'sys/src/9/ip/devip.c')
-rw-r--r-- | sys/src/9/ip/devip.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/sys/src/9/ip/devip.c b/sys/src/9/ip/devip.c index 93a8514b4..74c83ea6d 100644 --- a/sys/src/9/ip/devip.c +++ b/sys/src/9/ip/devip.c @@ -1286,20 +1286,32 @@ retry: c = malloc(sizeof(Conv)); if(c == nil) error(Enomem); - qlock(c); + if(waserror()){ + qfree(c->rq); + qfree(c->wq); + qfree(c->eq); + qfree(c->sq); + free(c->ptcl); + free(c); + nexterror(); + } c->p = p; c->x = pp - p->conv; if(p->ptclsize != 0){ c->ptcl = malloc(p->ptclsize); - if(c->ptcl == nil) { - free(c); + if(c->ptcl == nil) error(Enomem); - } } - *pp = c; - p->ac++; c->eq = qopen(1024, Qmsg, 0, 0); + if(c->eq == nil) + error(Enomem); (*p->create)(c); + if(c->rq == nil || c->wq == nil) + error(Enomem); + poperror(); + qlock(c); + *pp = c; + p->ac++; break; } if(canqlock(c)){ |