fix out-of-bounds access to ifindex2ifnet[]. found by iij seil team.

This commit is contained in:
itojun 2003-10-01 04:22:33 +00:00
parent 0545d82fe3
commit ae7fc0a7d4
1 changed files with 10 additions and 6 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if.c,v 1.130 2003/08/14 07:39:22 itojun Exp $ */ /* $NetBSD: if.c,v 1.131 2003/10/01 04:22:33 itojun Exp $ */
/*- /*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc. * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -97,7 +97,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.130 2003/08/14 07:39:22 itojun Exp $"); __KERNEL_RCSID(0, "$NetBSD: if.c,v 1.131 2003/10/01 04:22:33 itojun Exp $");
#include "opt_inet.h" #include "opt_inet.h"
@ -365,7 +365,8 @@ if_attach(ifp)
if (ifindex2ifnet == 0) if (ifindex2ifnet == 0)
if_index++; if_index++;
else else
while (ifindex2ifnet[ifp->if_index] != NULL) { while (ifp->if_index < if_indexlim &&
ifindex2ifnet[ifp->if_index] != NULL) {
++if_index; ++if_index;
if (if_index == 0) if (if_index == 0)
if_index = 1; if_index = 1;
@ -400,28 +401,31 @@ if_attach(ifp)
*/ */
if (ifnet_addrs == 0 || ifindex2ifnet == 0 || if (ifnet_addrs == 0 || ifindex2ifnet == 0 ||
ifp->if_index >= if_indexlim) { ifp->if_index >= if_indexlim) {
size_t n; size_t m, n, oldlim;
caddr_t q; caddr_t q;
oldlim = if_indexlim;
while (ifp->if_index >= if_indexlim) while (ifp->if_index >= if_indexlim)
if_indexlim <<= 1; if_indexlim <<= 1;
/* grow ifnet_addrs */ /* grow ifnet_addrs */
m = oldlim * sizeof(struct ifaddr *);
n = if_indexlim * sizeof(struct ifaddr *); n = if_indexlim * sizeof(struct ifaddr *);
q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK); q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
memset(q, 0, n); memset(q, 0, n);
if (ifnet_addrs) { if (ifnet_addrs) {
bcopy((caddr_t)ifnet_addrs, q, n/2); bcopy((caddr_t)ifnet_addrs, q, m);
free((caddr_t)ifnet_addrs, M_IFADDR); free((caddr_t)ifnet_addrs, M_IFADDR);
} }
ifnet_addrs = (struct ifaddr **)q; ifnet_addrs = (struct ifaddr **)q;
/* grow ifindex2ifnet */ /* grow ifindex2ifnet */
m = oldlim * sizeof(struct ifnet *);
n = if_indexlim * sizeof(struct ifnet *); n = if_indexlim * sizeof(struct ifnet *);
q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK); q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
memset(q, 0, n); memset(q, 0, n);
if (ifindex2ifnet) { if (ifindex2ifnet) {
bcopy((caddr_t)ifindex2ifnet, q, n/2); bcopy((caddr_t)ifindex2ifnet, q, m);
free((caddr_t)ifindex2ifnet, M_IFADDR); free((caddr_t)ifindex2ifnet, M_IFADDR);
} }
ifindex2ifnet = (struct ifnet **)q; ifindex2ifnet = (struct ifnet **)q;