Pull up following revision(s) (requested by sborrill in ticket #352):

sys/external/bsd/ipf/netinet/ip_state.c: 1.9-1.10
When growing the state, remember to grow the seed array, otherwise we'll end
up accessing memory we did not allocate.
--
put back the cast.
This commit is contained in:
snj 2017-11-17 20:20:22 +00:00
parent 284701d8e6
commit caade10228
1 changed files with 45 additions and 20 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_state.c,v 1.7 2017/04/23 20:47:22 christos Exp $ */
/* $NetBSD: ip_state.c,v 1.7.4.1 2017/11/17 20:20:22 snj Exp $ */
/*
* Copyright (C) 2012 by Darren Reed.
@ -100,7 +100,7 @@ struct file;
#if !defined(lint)
#if defined(__NetBSD__)
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip_state.c,v 1.7 2017/04/23 20:47:22 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip_state.c,v 1.7.4.1 2017/11/17 20:20:22 snj Exp $");
#else
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)Id: ip_state.c,v 1.1.1.2 2012/07/22 13:45:37 darrenr Exp";
@ -298,6 +298,32 @@ ipf_state_soft_destroy(ipf_main_softc_t *softc, void *arg)
KFREE(softs);
}
static void *
ipf_state_seed_alloc(u_int state_size, u_int state_max)
{
u_int i;
u_long *state_seed;
KMALLOCS(state_seed, u_long *, state_size * sizeof(*state_seed));
if (state_seed == NULL)
return NULL;
for (i = 0; i < state_size; i++) {
/*
* XXX - ipf_state_seed[X] should be a random number of sorts.
*/
#if !defined(NEED_LOCAL_RAND) && defined(_KERNEL)
state_seed[i] = cprng_fast32();
#else
state_seed[i] = ((u_long)state_seed + i) * state_size;
state_seed[i] ^= 0xa5a55a5a;
state_seed[i] *= (u_long)state_seed;
state_seed[i] ^= 0x5a5aa5a5;
state_seed[i] *= state_max;
#endif
}
return state_seed;
}
/* ------------------------------------------------------------------------ */
/* Function: ipf_state_soft_init */
@ -328,27 +354,11 @@ ipf_state_soft_init(ipf_main_softc_t *softc, void *arg)
bzero((char *)softs->ipf_state_table,
softs->ipf_state_size * sizeof(ipstate_t *));
KMALLOCS(softs->ipf_state_seed, u_long *,
softs->ipf_state_size * sizeof(*softs->ipf_state_seed));
softs->ipf_state_seed = ipf_state_seed_alloc(softs->ipf_state_size,
softs->ipf_state_max);
if (softs->ipf_state_seed == NULL)
return -2;
for (i = 0; i < softs->ipf_state_size; i++) {
/*
* XXX - ipf_state_seed[X] should be a random number of sorts.
*/
#if !defined(NEED_LOCAL_RAND) && defined(_KERNEL)
softs->ipf_state_seed[i] = cprng_fast32();
#else
softs->ipf_state_seed[i] = ((u_long)softs->ipf_state_seed + i) *
softs->ipf_state_size;
softs->ipf_state_seed[i] ^= 0xa5a55a5a;
softs->ipf_state_seed[i] *= (u_long)softs->ipf_state_seed;
softs->ipf_state_seed[i] ^= 0x5a5aa5a5;
softs->ipf_state_seed[i] *= softs->ipf_state_max;
#endif
}
KMALLOCS(softs->ipf_state_stats.iss_bucketlen, u_int *,
softs->ipf_state_size * sizeof(u_int));
if (softs->ipf_state_stats.iss_bucketlen == NULL)
@ -5137,6 +5147,7 @@ ipf_state_rehash(ipf_main_softc_t *softc, ipftuneable_t *t, ipftuneval_t *p)
{
ipf_state_softc_t *softs = softc->ipf_state_soft;
ipstate_t **newtab, *is;
u_long *newseed;
u_int *bucketlens;
u_int maxbucket;
u_int newsize;
@ -5163,6 +5174,14 @@ ipf_state_rehash(ipf_main_softc_t *softc, ipftuneable_t *t, ipftuneval_t *p)
return ENOMEM;
}
newseed = ipf_state_seed_alloc(newsize, softs->ipf_state_max);
if (newseed == NULL) {
KFREES(bucketlens, newsize * sizeof(*bucketlens));
KFREES(newtab, newsize * sizeof(*newtab));
IPFERROR(100037);
return ENOMEM;
}
for (maxbucket = 0, i = newsize; i > 0; i >>= 1)
maxbucket++;
maxbucket *= 2;
@ -5178,6 +5197,12 @@ ipf_state_rehash(ipf_main_softc_t *softc, ipftuneable_t *t, ipftuneval_t *p)
}
softs->ipf_state_table = newtab;
if (softs->ipf_state_seed != NULL) {
KFREES(softs->ipf_state_seed,
softs->ipf_state_size * sizeof(*softs->ipf_state_seed));
}
softs->ipf_state_seed = newseed;
if (softs->ipf_state_stats.iss_bucketlen != NULL) {
KFREES(softs->ipf_state_stats.iss_bucketlen,
softs->ipf_state_size * sizeof(u_int));