diff options
| author | rmind <rmind@NetBSD.org> | 2009-12-19 18:25:54 +0000 |
|---|---|---|
| committer | rmind <rmind@NetBSD.org> | 2009-12-19 18:25:54 +0000 |
| commit | ebd0ab14ab46adc1921e4064e294e9ed62301fe6 (patch) | |
| tree | 811ceca41dd80d607cae3b8df96fde0a2c73404f | |
| parent | c0bd792af4c5e9fee0f19f8dc987fc77380cf0a7 (diff) | |
sigtimedwait: fix a memory leak (which happens since newlock2 times).
Allocate ksiginfo on stack since it is safe and sigget() assumes that it is
not allocated from pool (pending signals via sigput()/sigget() "mill" should
be dynamically allocated, however). Might be useful to revisit later.
Likely the cause of PR/40750 and indirect cause of PR/39283.
| -rw-r--r-- | sys/kern/sys_sig.c | 25 |
1 files changed, 8 insertions, 17 deletions
diff --git a/sys/kern/sys_sig.c b/sys/kern/sys_sig.c index 4269cdb6d9c..c7b75fe1f48 100644 --- a/sys/kern/sys_sig.c +++ b/sys/kern/sys_sig.c @@ -1,4 +1,4 @@ -/* $NetBSD: sys_sig.c,v 1.23 2009/03/29 17:54:12 christos Exp $ */ +/* $NetBSD: sys_sig.c,v 1.24 2009/12/19 18:25:54 rmind Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sys_sig.c,v 1.23 2009/03/29 17:54:12 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_sig.c,v 1.24 2009/12/19 18:25:54 rmind Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -636,7 +636,7 @@ __sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap, int error, signum; int timo = 0; struct timespec ts, tsstart, tsnow; - ksiginfo_t *ksi; + ksiginfo_t ksi; memset(&tsstart, 0, sizeof tsstart); /* XXX gcc */ @@ -674,13 +674,6 @@ __sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap, */ sigminusset(&sigcantmask, &l->l_sigwaitset); - /* - * Allocate a ksi up front. We can't sleep with the mutex held. - */ - ksi = ksiginfo_alloc(p, NULL, PR_WAITOK); - if (ksi == NULL) - return (ENOMEM); - mutex_enter(p->p_lock); /* @@ -692,8 +685,8 @@ __sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap, goto out; } - if ((signum = sigget(&p->p_sigpend, ksi, 0, &l->l_sigwaitset)) == 0) - signum = sigget(&l->l_sigpend, ksi, 0, &l->l_sigwaitset); + if ((signum = sigget(&p->p_sigpend, &ksi, 0, &l->l_sigwaitset)) == 0) + signum = sigget(&l->l_sigpend, &ksi, 0, &l->l_sigwaitset); if (signum != 0) { /* @@ -706,7 +699,7 @@ __sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap, /* * Set up the sigwait list. */ - l->l_sigwaited = ksi; + l->l_sigwaited = &ksi; LIST_INSERT_HEAD(&p->p_sigwaiters, l, l_sigwaiter); /* @@ -761,10 +754,8 @@ __sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap, */ out: if (error == 0) - error = (*put_info)(&ksi->ksi_info, SCARG(uap, info), - sizeof(ksi->ksi_info)); - - ksiginfo_free(ksi); + error = (*put_info)(&ksi.ksi_info, SCARG(uap, info), + sizeof(ksi.ksi_info)); return error; } |
