summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-04-02 01:40:29 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2013-04-02 01:40:29 +0200
commite8c1d0fe7cdfcbf0d913b5091a33a14da561f976 (patch)
treea04271094793b14bcd1bd5050afc7c90399b6fe7
parente8a02760901e0b700ba845c9f57601f662e0e0aa (diff)
downloadplan9front-e8c1d0fe7cdfcbf0d913b5091a33a14da561f976.tar.xz
ape: check *alen before copying in getpeername(), getsockname() and accept()
*alen has to be initialized to the size of the buffer by the caller, and we are supposed to put the real size of the address in there, but not copy more than the original *alen value (truncate).
-rw-r--r--sys/src/ape/lib/bsd/accept.c19
-rw-r--r--sys/src/ape/lib/bsd/bind.c6
-rw-r--r--sys/src/ape/lib/bsd/connect.c8
-rw-r--r--sys/src/ape/lib/bsd/getpeername.c22
-rw-r--r--sys/src/ape/lib/bsd/getsockname.c20
5 files changed, 47 insertions, 28 deletions
diff --git a/sys/src/ape/lib/bsd/accept.c b/sys/src/ape/lib/bsd/accept.c
index 4f6203652..7a087c590 100644
--- a/sys/src/ape/lib/bsd/accept.c
+++ b/sys/src/ape/lib/bsd/accept.c
@@ -62,14 +62,8 @@ accept(int fd, void *a, int *alen)
close(nfd);
return -1;
}
- /* get remote address */
- _sock_ingetaddr(nr, &nr->raddr, &n, "remote");
- if(a != 0){
- if(n > 0)
- memmove(a, &nr->raddr, n);
- *alen = n;
- }
- return nfd;
+ _sock_ingetaddr(nr, &nr->raddr, 0, "remote");
+ break;
case PF_UNIX:
if(r->other >= 0){
errno = EGREG;
@@ -106,10 +100,15 @@ accept(int fd, void *a, int *alen)
nr->domain = r->domain;
nr->stype = r->stype;
nr->protocol = r->protocol;
-
- return nfd;
+ nr->raddr = r->addr;
+ break;
default:
errno = EOPNOTSUPP;
return -1;
}
+
+ if(a != 0)
+ getpeername(nfd, a, alen);
+
+ return nfd;
}
diff --git a/sys/src/ape/lib/bsd/bind.c b/sys/src/ape/lib/bsd/bind.c
index 902fbcd46..a4c7ae573 100644
--- a/sys/src/ape/lib/bsd/bind.c
+++ b/sys/src/ape/lib/bsd/bind.c
@@ -25,6 +25,7 @@ int
bind(int fd, void *a, int alen)
{
int n, len, cfd, port;
+ struct sockaddr *sa;
Rock *r;
char msg[128];
@@ -34,6 +35,11 @@ bind(int fd, void *a, int alen)
errno = ENOTSOCK;
return -1;
}
+ sa = (struct sockaddr*)a;
+ if(sa->sa_family != r->domain){
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
if(alen > sizeof(r->addr)){
errno = ENAMETOOLONG;
return -1;
diff --git a/sys/src/ape/lib/bsd/connect.c b/sys/src/ape/lib/bsd/connect.c
index ebc63182a..dd6510c01 100644
--- a/sys/src/ape/lib/bsd/connect.c
+++ b/sys/src/ape/lib/bsd/connect.c
@@ -30,15 +30,15 @@ connect(int fd, void *a, int alen)
errno = ENOTSOCK;
return -1;
}
- if(alen > sizeof(r->raddr)){
- errno = ENAMETOOLONG;
- return -1;
- }
sa = (struct sockaddr*)a;
if(sa->sa_family != r->domain){
errno = EAFNOSUPPORT;
return -1;
}
+ if(alen > sizeof(r->raddr)){
+ errno = ENAMETOOLONG;
+ return -1;
+ }
memmove(&r->raddr, a, alen);
switch(r->domain){
diff --git a/sys/src/ape/lib/bsd/getpeername.c b/sys/src/ape/lib/bsd/getpeername.c
index 55b4f8eb3..cec7a057a 100644
--- a/sys/src/ape/lib/bsd/getpeername.c
+++ b/sys/src/ape/lib/bsd/getpeername.c
@@ -19,7 +19,7 @@ int
getpeername(int fd, struct sockaddr *addr, int *alen)
{
Rock *r;
- int i;
+ int olen, len;
struct sockaddr_un *runix;
r = _sock_findrock(fd, 0);
@@ -30,22 +30,28 @@ getpeername(int fd, struct sockaddr *addr, int *alen)
switch(r->domain){
case PF_INET:
- memmove(addr, &r->raddr, sizeof(struct sockaddr_in));
- *alen = sizeof(struct sockaddr_in);
+ len = sizeof(struct sockaddr_in);
break;
case PF_INET6:
- memmove(addr, &r->raddr, sizeof(struct sockaddr_in6));
- *alen = sizeof(struct sockaddr_in6);
+ len = sizeof(struct sockaddr_in6);
break;
case PF_UNIX:
runix = (struct sockaddr_un*)&r->raddr;
- i = &runix->sun_path[strlen(runix->sun_path)] - (char*)runix;
- memmove(addr, runix, i);
- *alen = i;
+ len = &runix->sun_path[strlen(runix->sun_path)] - (char*)runix;
break;
default:
errno = EAFNOSUPPORT;
return -1;
}
+
+ if(alen != 0){
+ olen = *alen;
+ *alen = len;
+ if(olen < len)
+ len = olen;
+ }
+ if(addr != 0 && len > 0)
+ memmove(addr, &r->raddr, len);
+
return 0;
}
diff --git a/sys/src/ape/lib/bsd/getsockname.c b/sys/src/ape/lib/bsd/getsockname.c
index cdf149779..87177228a 100644
--- a/sys/src/ape/lib/bsd/getsockname.c
+++ b/sys/src/ape/lib/bsd/getsockname.c
@@ -19,7 +19,7 @@ int
getsockname(int fd, struct sockaddr *addr, int *alen)
{
Rock *r;
- int i;
+ int len, olen;
struct sockaddr_un *lunix;
r = _sock_findrock(fd, 0);
@@ -28,21 +28,29 @@ getsockname(int fd, struct sockaddr *addr, int *alen)
return -1;
}
+ len = 0;
switch(r->domain){
case PF_INET:
case PF_INET6:
- _sock_ingetaddr(r, addr, alen, "local");
+ _sock_ingetaddr(r, &r->addr, &len, "local");
break;
case PF_UNIX:
lunix = (struct sockaddr_un*)&r->addr;
- i = &lunix->sun_path[strlen(lunix->sun_path)] - (char*)lunix;
- memmove(addr, lunix, i);
- if(alen != 0)
- *alen = i;
+ len = &lunix->sun_path[strlen(lunix->sun_path)] - (char*)lunix;
break;
default:
errno = EAFNOSUPPORT;
return -1;
}
+
+ if(alen != 0){
+ olen = *alen;
+ *alen = len;
+ if(olen < len)
+ len = olen;
+ }
+ if(addr != 0 && len > 0)
+ memmove(addr, &r->addr, len);
+
return 0;
}