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.
|
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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_ptrace.h"
|
||||||
#include "opt_compat_sunos.h"
|
#include "opt_compat_sunos.h"
|
||||||
|
@ -230,24 +230,19 @@ sigacts_poolpage_free(struct pool *pp, void *v)
|
||||||
struct sigacts *
|
struct sigacts *
|
||||||
sigactsinit(struct proc *pp, int share)
|
sigactsinit(struct proc *pp, int share)
|
||||||
{
|
{
|
||||||
struct sigacts *ps, *ps2;
|
struct sigacts *ps = pp->p_sigacts, *ps2;
|
||||||
|
|
||||||
ps = pp->p_sigacts;
|
if (__predict_false(share)) {
|
||||||
|
|
||||||
if (share) {
|
|
||||||
atomic_inc_uint(&ps->sa_refcnt);
|
atomic_inc_uint(&ps->sa_refcnt);
|
||||||
ps2 = ps;
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
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;
|
return ps2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,15 +254,16 @@ sigactsinit(struct proc *pp, int share)
|
||||||
void
|
void
|
||||||
sigactsunshare(struct proc *p)
|
sigactsunshare(struct proc *p)
|
||||||
{
|
{
|
||||||
struct sigacts *ps, *oldps;
|
struct sigacts *ps, *oldps = p->p_sigacts;
|
||||||
|
|
||||||
oldps = p->p_sigacts;
|
if (__predict_true(oldps->sa_refcnt == 1))
|
||||||
if (oldps->sa_refcnt == 1)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ps = pool_cache_get(sigacts_cache, PR_WAITOK);
|
ps = pool_cache_get(sigacts_cache, PR_WAITOK);
|
||||||
/* XXXAD get rid of this */
|
|
||||||
mutex_init(&ps->sa_mutex, MUTEX_DEFAULT, IPL_SCHED);
|
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;
|
p->p_sigacts = ps;
|
||||||
sigactsfree(oldps);
|
sigactsfree(oldps);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue