Add mutex to protect the ucred reference counter.

This commit is contained in:
pk 2004-05-02 12:36:55 +00:00
parent 4a04452106
commit 7d0afa7f41
2 changed files with 29 additions and 10 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_prot.c,v 1.82 2004/04/25 16:42:41 simonb Exp $ */
/* $NetBSD: kern_prot.c,v 1.83 2004/05/02 12:36:55 pk Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_prot.c,v 1.82 2004/04/25 16:42:41 simonb Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_prot.c,v 1.83 2004/05/02 12:36:55 pk Exp $");
#include "opt_compat_43.h"
@ -620,6 +620,7 @@ crget(void)
cr = pool_get(&cred_pool, PR_WAITOK);
memset(cr, 0, sizeof(*cr));
simple_lock_init(&cr->cr_lock);
cr->cr_ref = 1;
return (cr);
}
@ -631,8 +632,12 @@ crget(void)
void
crfree(struct ucred *cr)
{
int n;
if (--cr->cr_ref == 0)
simple_lock(&cr->cr_lock);
n = --cr->cr_ref;
simple_unlock(&cr->cr_lock);
if (n == 0)
pool_put(&cred_pool, cr);
}
@ -655,13 +660,18 @@ struct ucred *
crcopy(struct ucred *cr)
{
struct ucred *newcr;
int n;
if (cr->cr_ref == 1)
simple_lock(&cr->cr_lock);
n = cr->cr_ref;
simple_unlock(&cr->cr_lock);
if (n == 1)
return (cr);
newcr = crget();
*newcr = *cr;
memcpy(&newcr->cr_startcopy, &cr->cr_startcopy,
sizeof(struct ucred) - offsetof(struct ucred, cr_startcopy));
crfree(cr);
newcr->cr_ref = 1;
return (newcr);
}
@ -674,8 +684,8 @@ crdup(const struct ucred *cr)
struct ucred *newcr;
newcr = crget();
*newcr = *cr;
newcr->cr_ref = 1;
memcpy(&newcr->cr_startcopy, &cr->cr_startcopy,
sizeof(struct ucred) - offsetof(struct ucred, cr_startcopy));
return (newcr);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ucred.h,v 1.18 2003/08/07 16:34:21 agc Exp $ */
/* $NetBSD: ucred.h,v 1.19 2004/05/02 12:36:55 pk Exp $ */
/*
* Copyright (c) 1989, 1993
@ -34,6 +34,8 @@
#ifndef _SYS_UCRED_H_
#define _SYS_UCRED_H_
#include <sys/lock.h>
/*
* Credentials.
*/
@ -48,7 +50,9 @@ struct uucred {
};
struct ucred {
struct simplelock cr_lock; /* mutex for ref count */
u_int32_t cr_ref; /* reference count */
#define cr_startcopy cr_uid /* for dup & copy */
uid_t cr_uid; /* effective user id */
gid_t cr_gid; /* effective group id */
u_int32_t cr_ngroups; /* number of groups */
@ -59,7 +63,12 @@ struct ucred {
#define FSCRED ((struct ucred *)-2) /* filesystem credential */
#ifdef _KERNEL
#define crhold(cr) (cr)->cr_ref++
static void __inline__ crhold(struct ucred *cr)
{
simple_lock(&cr->cr_lock);
cr->cr_ref++;
simple_unlock(&cr->cr_lock);
}
/* flags that control when do_setres{u,g}id will do anything */
#define ID_E_EQ_E 0x001 /* effective equals effective */