sigactsunshare(): set reference count in a case of new sigacts allocation.
Bug (e.g. memory leak) can happen when using clone(2) call.
This commit is contained in:
parent
2faaca9342
commit
ffb9a7ee3c
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_sig.c,v 1.301 2009/12/20 04:49:09 rmind Exp $ */
|
||||
/* $NetBSD: kern_sig.c,v 1.302 2009/12/30 23:31:56 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -66,7 +66,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.301 2009/12/20 04:49:09 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.302 2009/12/30 23:31:56 rmind Exp $");
|
||||
|
||||
#include "opt_ptrace.h"
|
||||
#include "opt_compat_sunos.h"
|
||||
|
@ -230,24 +230,19 @@ sigacts_poolpage_free(struct pool *pp, void *v)
|
|||
struct sigacts *
|
||||
sigactsinit(struct proc *pp, int share)
|
||||
{
|
||||
struct sigacts *ps, *ps2;
|
||||
struct sigacts *ps = pp->p_sigacts, *ps2;
|
||||
|
||||
ps = pp->p_sigacts;
|
||||
|
||||
if (share) {
|
||||
if (__predict_false(share)) {
|
||||
atomic_inc_uint(&ps->sa_refcnt);
|
||||
ps2 = ps;
|
||||
} else {
|
||||
ps2 = pool_cache_get(sigacts_cache, PR_WAITOK);
|
||||
/* XXXAD get rid of this */
|
||||
mutex_init(&ps2->sa_mutex, MUTEX_DEFAULT, IPL_SCHED);
|
||||
mutex_enter(&ps->sa_mutex);
|
||||
memcpy(&ps2->sa_sigdesc, ps->sa_sigdesc,
|
||||
sizeof(ps2->sa_sigdesc));
|
||||
mutex_exit(&ps->sa_mutex);
|
||||
ps2->sa_refcnt = 1;
|
||||
return ps;
|
||||
}
|
||||
ps2 = pool_cache_get(sigacts_cache, PR_WAITOK);
|
||||
mutex_init(&ps2->sa_mutex, MUTEX_DEFAULT, IPL_SCHED);
|
||||
ps2->sa_refcnt = 1;
|
||||
|
||||
mutex_enter(&ps->sa_mutex);
|
||||
memcpy(ps2->sa_sigdesc, ps->sa_sigdesc, sizeof(ps2->sa_sigdesc));
|
||||
mutex_exit(&ps->sa_mutex);
|
||||
return ps2;
|
||||
}
|
||||
|
||||
|
@ -259,15 +254,16 @@ sigactsinit(struct proc *pp, int share)
|
|||
void
|
||||
sigactsunshare(struct proc *p)
|
||||
{
|
||||
struct sigacts *ps, *oldps;
|
||||
struct sigacts *ps, *oldps = p->p_sigacts;
|
||||
|
||||
oldps = p->p_sigacts;
|
||||
if (oldps->sa_refcnt == 1)
|
||||
if (__predict_true(oldps->sa_refcnt == 1))
|
||||
return;
|
||||
|
||||
ps = pool_cache_get(sigacts_cache, PR_WAITOK);
|
||||
/* XXXAD get rid of this */
|
||||
mutex_init(&ps->sa_mutex, MUTEX_DEFAULT, IPL_SCHED);
|
||||
memset(&ps->sa_sigdesc, 0, sizeof(ps->sa_sigdesc));
|
||||
memset(ps->sa_sigdesc, 0, sizeof(ps->sa_sigdesc));
|
||||
ps->sa_refcnt = 1;
|
||||
|
||||
p->p_sigacts = ps;
|
||||
sigactsfree(oldps);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue