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).
This commit is contained in:
cinap_lenrek 2013-04-02 01:40:29 +02:00
parent e8a0276090
commit e8c1d0fe7c
5 changed files with 47 additions and 28 deletions

View file

@ -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;
}

View file

@ -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;

View file

@ -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){

View file

@ -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;
}

View file

@ -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;
}