ref: 3b82afa72f80a73ea1a801cd1ff3def12cb0bc1d
parent: 115d9b1eb6364756376df73804205c1ab679964f
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Fri Mar 29 16:49:49 EDT 2013
ape: fix potential double close in socket() and protect rock chain with spinlock
--- a/sys/src/ape/lib/bsd/socket.c
+++ b/sys/src/ape/lib/bsd/socket.c
@@ -14,8 +14,11 @@
#include "priv.h"
-Rock *_sock_rock;
+#include <lock.h>
+static Lock _sock_lock;
+static Rock *_sock_rock;
+
Rock*
_sock_findrock(int fd, struct stat *dp)
{@@ -24,12 +27,15 @@
if(dp == 0)
dp = &d;
- fstat(fd, dp);
+ if(fstat(fd, dp) < 0)
+ return 0;
+ lock(&_sock_lock);
for(r = _sock_rock; r; r = r->next){if(r->inode == dp->st_ino
&& r->dev == dp->st_dev)
break;
}
+ unlock(&_sock_lock);
return r;
}
@@ -39,22 +45,29 @@
Rock *r;
struct stat d;
- r = _sock_findrock(fd, &d);
+ if(fstat(fd, &d) < 0)
+ return 0;
+ lock(&_sock_lock);
+ for(r = _sock_rock; r; r = r->next){+ if(r->inode == d.st_ino
+ && r->dev == d.st_dev)
+ break;
+ }
if(r == 0){r = malloc(sizeof(Rock));
- if(r == 0)
+ if(r == 0){+ unlock(&_sock_lock);
return 0;
+ }
r->dev = d.st_dev;
r->inode = d.st_ino;
- r->other = -1;
r->next = _sock_rock;
_sock_rock = r;
}
+ unlock(&_sock_lock);
memset(&r->raddr, 0, sizeof(r->raddr));
memset(&r->addr, 0, sizeof(r->addr));
r->reserved = 0;
- r->dev = d.st_dev;
- r->inode = d.st_ino;
r->other = -1;
return r;
}
@@ -81,7 +94,6 @@
fd = open(name, O_RDWR);
close(cfd);
if(fd < 0){- close(cfd);
errno = ENOBUFS;
return -1;
}
@@ -90,18 +102,16 @@
snprintf(name, sizeof name, "/net/%s/%d/ctl", net, n);
r = _sock_newrock(fd);
if(r == 0){- errno = ENOBUFS;
close(fd);
+ errno = ENOBUFS;
return -1;
}
- if(rp)
- *rp = r;
- memset(&r->raddr, 0, sizeof(r->raddr));
- memset(&r->addr, 0, sizeof(r->addr));
r->domain = domain;
r->stype = stype;
r->protocol = protocol;
strcpy(r->ctl, name);
+ if(rp)
+ *rp = r;
return fd;
}
@@ -140,6 +150,12 @@
return -1;
}
r = _sock_newrock(pfd[0]);
+ if(r == 0){+ close(pfd[0]);
+ close(pfd[1]);
+ errno = ENOBUFS;
+ return -1;
+ }
r->domain = domain;
r->stype = stype;
r->protocol = protocol;
--
⑨