- Avoid array overrun in kfilter_byname_user() when all user

kfilter slots are used: no guarantee previously that last
  slot had a NULL name.
- Reuse previously deregistered user kfilter slots in
  kfilter_register().
This commit is contained in:
seanb 2006-09-30 02:39:18 +00:00
parent 18bbc9e1d3
commit dfb8aa55d3
1 changed files with 25 additions and 18 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_event.c,v 1.30 2006/07/23 22:06:11 ad Exp $ */
/* $NetBSD: kern_event.c,v 1.31 2006/09/30 02:39:18 seanb Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.30 2006/07/23 22:06:11 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.31 2006/09/30 02:39:18 seanb Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -173,12 +173,9 @@ kfilter_byname_user(const char *name)
{
int i;
/* user_kfilters[] could be NULL if no filters were registered */
if (!user_kfilters)
return (NULL);
for (i = 0; user_kfilters[i].name != NULL; i++) {
if (user_kfilters[i].name != '\0' &&
/* user filter slots have a NULL name if previously deregistered */
for (i = 0; i < user_kfilterc ; i++) {
if (user_kfilters[i].name != NULL &&
strcmp(name, user_kfilters[i].name) == 0)
return (&user_kfilters[i]);
}
@ -229,6 +226,7 @@ kfilter_register(const char *name, const struct filterops *filtops,
struct kfilter *kfilter;
void *space;
int len;
int i;
if (name == NULL || name[0] == '\0' || filtops == NULL)
return (EINVAL); /* invalid args */
@ -237,6 +235,14 @@ kfilter_register(const char *name, const struct filterops *filtops,
if (user_kfilterc > 0xffffffff - EVFILT_SYSCOUNT)
return (EINVAL); /* too many */
for (i = 0; i < user_kfilterc; i++) {
kfilter = &user_kfilters[i];
if (kfilter->name == NULL) {
/* Previously deregistered slot. Reuse. */
goto reuse;
}
}
/* check if need to grow user_kfilters */
if (user_kfilterc + 1 > user_kfiltermaxc) {
/*
@ -261,21 +267,23 @@ kfilter_register(const char *name, const struct filterops *filtops,
free(user_kfilters, M_KEVENT);
user_kfilters = kfilter;
}
/* Adding new slot */
kfilter = &user_kfilters[user_kfilterc++];
reuse:
len = strlen(name) + 1; /* copy name */
space = malloc(len, M_KEVENT, M_WAITOK);
memcpy(space, name, len);
user_kfilters[user_kfilterc].name = space;
kfilter->name = space;
user_kfilters[user_kfilterc].filter = user_kfilterc + EVFILT_SYSCOUNT;
kfilter->filter = (kfilter - user_kfilters) + EVFILT_SYSCOUNT;
len = sizeof(struct filterops); /* copy filtops */
space = malloc(len, M_KEVENT, M_WAITOK);
memcpy(space, filtops, len);
user_kfilters[user_kfilterc].filtops = space;
kfilter->filtops = space;
if (retfilter != NULL)
*retfilter = user_kfilters[user_kfilterc].filter;
user_kfilterc++; /* finally, increment count */
*retfilter = kfilter->filter;
return (0);
}
@ -300,11 +308,10 @@ kfilter_unregister(const char *name)
if (kfilter == NULL) /* not found */
return (ENOENT);
if (kfilter->name[0] != '\0') {
/* XXXUNCONST Cast away const (but we know it's safe. */
free(__UNCONST(kfilter->name), M_KEVENT);
kfilter->name = ""; /* mark as `not implemented' */
}
/* XXXUNCONST Cast away const (but we know it's safe. */
free(__UNCONST(kfilter->name), M_KEVENT);
kfilter->name = NULL; /* mark as `not implemented' */
if (kfilter->filtops != NULL) {
/* XXXUNCONST Cast away const (but we know it's safe. */
free(__UNCONST(kfilter->filtops), M_KEVENT);