summaryrefslogtreecommitdiff
path: root/sys/src/ape/lib/bsd/getsockname.c
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 /sys/src/ape/lib/bsd/getsockname.c
parente8a02760901e0b700ba845c9f57601f662e0e0aa (diff)
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).
Diffstat (limited to 'sys/src/ape/lib/bsd/getsockname.c')
-rw-r--r--sys/src/ape/lib/bsd/getsockname.c20
1 files changed, 14 insertions, 6 deletions
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;
}