summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrmind <rmind@NetBSD.org>2009-12-19 18:25:54 +0000
committerrmind <rmind@NetBSD.org>2009-12-19 18:25:54 +0000
commitebd0ab14ab46adc1921e4064e294e9ed62301fe6 (patch)
tree811ceca41dd80d607cae3b8df96fde0a2c73404f
parentc0bd792af4c5e9fee0f19f8dc987fc77380cf0a7 (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.c25
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;
}