If sa_upcall() fails (which is always going to be due to resource exhaustion),

do not leak siginfo structures.

Note that in the cases of trap signals and timer events, losing this
information could be very bad; right now it will cause us to spin until the
process is SIGKILLed.

"Needs work."
This commit is contained in:
mycroft 2005-01-06 19:26:41 +00:00
parent 7035be17ff
commit 13495aa242
3 changed files with 21 additions and 13 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_sa.c,v 1.55 2004/10/23 21:27:34 yamt Exp $ */
/* $NetBSD: kern_sa.c,v 1.56 2005/01/06 19:26:41 mycroft Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_sa.c,v 1.55 2004/10/23 21:27:34 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_sa.c,v 1.56 2005/01/06 19:26:41 mycroft Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -773,9 +773,7 @@ sa_upcall0(struct lwp *l, int type, struct lwp *event, struct lwp *interrupted,
KDASSERT((event == NULL) || (event != interrupted));
sau->sau_flags = 0;
sau->sau_type = type & SA_UPCALL_TYPE_MASK;
sau->sau_argsize = argsize;
sau->sau_arg = arg;
sau->sau_arg = 0;
if (type & SA_UPCALL_DEFER_EVENT) {
sau->sau_event.ss_deferred.ss_lwp = event;
@ -788,6 +786,10 @@ sa_upcall0(struct lwp *l, int type, struct lwp *event, struct lwp *interrupted,
} else
sa_upcall_getstate(&sau->sau_interrupted, interrupted);
sau->sau_type = type & SA_UPCALL_TYPE_MASK;
sau->sau_argsize = argsize;
sau->sau_arg = arg;
return (0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_sig.c,v 1.199 2004/10/01 16:30:55 yamt Exp $ */
/* $NetBSD: kern_sig.c,v 1.200 2005/01/06 19:26:41 mycroft Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.199 2004/10/01 16:30:55 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.200 2005/01/06 19:26:41 mycroft Exp $");
#include "opt_ktrace.h"
#include "opt_compat_sunos.h"
@ -1390,9 +1390,12 @@ kpsendsig(struct lwp *l, const ksiginfo_t *ksi, const sigset_t *mask)
le = l;
else
li = l;
sa_upcall(l, SA_UPCALL_SIGNAL | SA_UPCALL_DEFER, le, li,
sizeof(siginfo_t), si);
if (sa_upcall(l, SA_UPCALL_SIGNAL | SA_UPCALL_DEFER, le, li,
sizeof(*si), si) != 0) {
pool_put(&siginfo_pool, si);
if (KSI_TRAP_P(ksi))
/* XXX What do we do here?? */;
}
l->l_flag |= f;
return;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_time.c,v 1.85 2004/11/14 03:30:09 atatat Exp $ */
/* $NetBSD: kern_time.c,v 1.86 2005/01/06 19:26:41 mycroft Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.85 2004/11/14 03:30:09 atatat Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.86 2005/01/06 19:26:41 mycroft Exp $");
#include "fs_nfs.h"
#include "opt_nfs.h"
@ -879,7 +879,10 @@ timerupcall(struct lwp *l, void *arg)
si = pool_get(&siginfo_pool, PR_WAITOK);
si->_info = pt->pts_timers[i]->pt_info.ksi_info;
if (sa_upcall(l, SA_UPCALL_SIGEV | SA_UPCALL_DEFER, NULL, l,
sizeof(*si), si) == 0)
sizeof(*si), si) != 0) {
pool_put(&siginfo_pool, si);
/* XXX What do we do here?? */
} else
done |= mask;
fired &= ~mask;
l->l_flag |= f;