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:
parent
e8a0276090
commit
e8c1d0fe7c
5 changed files with 47 additions and 28 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue