A number of functions do not validate the length of arguments passed.
As a result of this a user could supply a bad 'sockaddr' structure to clnp_route() via connect(2). Issue found by Christer Oberg and patch from christos@ (NetBSD-SA2007-004)
This commit is contained in:
parent
a7b58a5e90
commit
b02eb0fb91
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: clnp_subr.c,v 1.26 2007/03/04 06:03:31 christos Exp $ */
|
/* $NetBSD: clnp_subr.c,v 1.27 2007/03/29 08:19:20 adrianp Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1991, 1993
|
* Copyright (c) 1991, 1993
|
||||||
|
@ -59,7 +59,7 @@ SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: clnp_subr.c,v 1.26 2007/03/04 06:03:31 christos Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: clnp_subr.c,v 1.27 2007/03/29 08:19:20 adrianp Exp $");
|
||||||
|
|
||||||
#include "opt_iso.h"
|
#include "opt_iso.h"
|
||||||
|
|
||||||
|
@ -157,27 +157,27 @@ clnp_extract_addr(
|
||||||
struct iso_addr *destp) /* ptr to destination address
|
struct iso_addr *destp) /* ptr to destination address
|
||||||
* buffer */
|
* buffer */
|
||||||
{
|
{
|
||||||
int len; /* argument to bcopy */
|
size_t len; /* argument to memcpy */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check that we have enough data. Plus1 is for length octet
|
* check that we have enough data. Plus1 is for length octet
|
||||||
*/
|
*/
|
||||||
if ((u_char) * bufp + 1 > buflen) {
|
len = (u_char)*bufp++;
|
||||||
return ((void *) 0);
|
if (len > buflen)
|
||||||
}
|
return NULL;
|
||||||
len = destp->isoa_len = (u_char) * bufp++;
|
destp->isoa_len = len;
|
||||||
(void) bcopy(bufp, (void *) destp, len);
|
(void)memcpy(destp, bufp, len);
|
||||||
buflen -= len;
|
buflen -= len;
|
||||||
bufp += len;
|
bufp += len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check that we have enough data. Plus1 is for length octet
|
* check that we have enough data. Plus1 is for length octet
|
||||||
*/
|
*/
|
||||||
if ((u_char) * bufp + 1 > buflen) {
|
len = (u_char)*bufp++;
|
||||||
return ((void *) 0);
|
if (len > buflen)
|
||||||
}
|
return NULL;
|
||||||
len = srcp->isoa_len = (u_char) * bufp++;
|
srcp->isoa_len = len;
|
||||||
(void) bcopy(bufp, (void *) srcp, len);
|
(void)memcpy(srcp, bufp, len);
|
||||||
bufp += len;
|
bufp += len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -186,7 +186,7 @@ clnp_extract_addr(
|
||||||
if (iso_ck_addr(srcp) && iso_ck_addr(destp))
|
if (iso_ck_addr(srcp) && iso_ck_addr(destp))
|
||||||
return bufp;
|
return bufp;
|
||||||
else
|
else
|
||||||
return (void *) 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif /* notdef */
|
#endif /* notdef */
|
||||||
|
|
||||||
|
@ -424,11 +424,11 @@ clnp_insert_addr(
|
||||||
struct iso_addr *dstp) /* ptr to dst addr */
|
struct iso_addr *dstp) /* ptr to dst addr */
|
||||||
{
|
{
|
||||||
*bufp++ = dstp->isoa_len;
|
*bufp++ = dstp->isoa_len;
|
||||||
(void) bcopy((void *) dstp, bufp, dstp->isoa_len);
|
(void)memcpy(bufp, dstp, dstp->isoa_len);
|
||||||
bufp += dstp->isoa_len;
|
bufp += dstp->isoa_len;
|
||||||
|
|
||||||
*bufp++ = srcp->isoa_len;
|
*bufp++ = srcp->isoa_len;
|
||||||
(void) bcopy((void *) srcp, bufp, srcp->isoa_len);
|
(void)memcpy(bufp, srcp, srcp->isoa_len);
|
||||||
bufp += srcp->isoa_len;
|
bufp += srcp->isoa_len;
|
||||||
|
|
||||||
return bufp;
|
return bufp;
|
||||||
|
@ -466,10 +466,13 @@ clnp_route(
|
||||||
{
|
{
|
||||||
if (flags & SO_DONTROUTE) {
|
if (flags & SO_DONTROUTE) {
|
||||||
struct iso_ifaddr *ia;
|
struct iso_ifaddr *ia;
|
||||||
|
size_t len = 1 + (unsigned)dst->isoa_len;
|
||||||
|
|
||||||
rtcache_free((struct route *)ro);
|
rtcache_free((struct route *)ro);
|
||||||
memset(&ro->ro_dst, 0, sizeof(ro->ro_dst));
|
if (sizeof(ro->ro_dst.siso_addr) < len)
|
||||||
memcpy(&ro->ro_dst.siso_addr, dst, 1 + (unsigned)dst->isoa_len);
|
return EINVAL;
|
||||||
|
(void)memset(&ro->ro_dst, 0, sizeof(ro->ro_dst));
|
||||||
|
(void)memcpy(&ro->ro_dst.siso_addr, dst, len);
|
||||||
ro->ro_dst.siso_family = AF_ISO;
|
ro->ro_dst.siso_family = AF_ISO;
|
||||||
ro->ro_dst.siso_len = sizeof(ro->ro_dst);
|
ro->ro_dst.siso_len = sizeof(ro->ro_dst);
|
||||||
ia = iso_localifa(&ro->ro_dst);
|
ia = iso_localifa(&ro->ro_dst);
|
||||||
|
@ -488,11 +491,15 @@ clnp_route(
|
||||||
rtcache_check((struct route *)ro);
|
rtcache_check((struct route *)ro);
|
||||||
|
|
||||||
if (ro->ro_rt == NULL) {
|
if (ro->ro_rt == NULL) {
|
||||||
|
size_t len = 1 + (unsigned)dst->isoa_len;
|
||||||
|
|
||||||
/* set up new route structure */
|
/* set up new route structure */
|
||||||
memset(&ro->ro_dst, 0, sizeof(ro->ro_dst));
|
if (sizeof(ro->ro_dst.siso_addr) < len)
|
||||||
|
return EINVAL;
|
||||||
|
(void)memset(&ro->ro_dst, 0, sizeof(ro->ro_dst));
|
||||||
ro->ro_dst.siso_len = sizeof(ro->ro_dst);
|
ro->ro_dst.siso_len = sizeof(ro->ro_dst);
|
||||||
ro->ro_dst.siso_family = AF_ISO;
|
ro->ro_dst.siso_family = AF_ISO;
|
||||||
memcpy(&ro->ro_dst.siso_addr, dst, 1 + dst->isoa_len);
|
(void)memcpy(&ro->ro_dst.siso_addr, dst, len);
|
||||||
/* allocate new route */
|
/* allocate new route */
|
||||||
#ifdef ARGO_DEBUG
|
#ifdef ARGO_DEBUG
|
||||||
if (argo_debug[D_ROUTE]) {
|
if (argo_debug[D_ROUTE]) {
|
||||||
|
@ -554,13 +561,19 @@ clnp_srcroute(
|
||||||
if CLNPSRCRT_TERM
|
if CLNPSRCRT_TERM
|
||||||
(oidx, options) {
|
(oidx, options) {
|
||||||
dst.isoa_len = final_dst->isoa_len;
|
dst.isoa_len = final_dst->isoa_len;
|
||||||
bcopy(final_dst->isoa_genaddr, dst.isoa_genaddr, dst.isoa_len);
|
if (sizeof(dst.isoa_genaddr) < (size_t)dst.isoa_len)
|
||||||
|
return EINVAL;
|
||||||
|
(void)memcpy(dst.isoa_genaddr, final_dst->isoa_genaddr,
|
||||||
|
(size_t)dst.isoa_len);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* setup dst based on src rt specified
|
* setup dst based on src rt specified
|
||||||
*/
|
*/
|
||||||
dst.isoa_len = CLNPSRCRT_CLEN(oidx, options);
|
dst.isoa_len = CLNPSRCRT_CLEN(oidx, options);
|
||||||
bcopy(CLNPSRCRT_CADDR(oidx, options), dst.isoa_genaddr, dst.isoa_len);
|
if (sizeof(dst.isoa_genaddr) < (unsigned)dst.isoa_len)
|
||||||
|
return EINVAL;
|
||||||
|
(void)memcpy(dst.isoa_genaddr, CLNPSRCRT_CADDR(oidx, options),
|
||||||
|
(size_t)dst.isoa_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue