From owner-p4-projects@FreeBSD.ORG Wed Feb 6 18:02:41 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id CBC5A16A469; Wed, 6 Feb 2008 18:02:40 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 78DB616A421 for ; Wed, 6 Feb 2008 18:02:40 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 4216E13C45D for ; Wed, 6 Feb 2008 18:02:40 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m16I2etD081303 for ; Wed, 6 Feb 2008 18:02:40 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m16I2e6Y081300 for perforce@freebsd.org; Wed, 6 Feb 2008 18:02:40 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Wed, 6 Feb 2008 18:02:40 GMT Message-Id: <200802061802.m16I2e6Y081300@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Cc: Subject: PERFORCE change 134913 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Feb 2008 18:02:41 -0000 http://perforce.freebsd.org/chv.cgi?CH=134913 Change 134913 by rwatson@rwatson_freebsd_capabilities on 2008/02/06 18:01:42 For each struct file, maintain a list of the capabilities pointing at it, and for each capability, maintain a pointer back to its own struct file. This is required in order to extend the UNIX domain socket garbage collector to properly handle capabilities being passed over UNIX domain sockets (which may otherwise be leaked in situations where the GC should otherwise find and free them). For now use a global lock to protect these lists, but really what we want is a per-file mutex (not currently present). Affected files ... .. //depot/projects/trustedbsd/capabilities/src/sys/kern/kern_descrip.c#6 edit .. //depot/projects/trustedbsd/capabilities/src/sys/kern/sys_capability.c#14 edit .. //depot/projects/trustedbsd/capabilities/src/sys/sys/file.h#5 edit Differences ... ==== //depot/projects/trustedbsd/capabilities/src/sys/kern/kern_descrip.c#6 (text+ko) ==== @@ -1392,6 +1392,7 @@ fp->f_ops = &badfileops; fp->f_data = NULL; fp->f_vnode = NULL; + LIST_INIT(&fp->f_caps); FILEDESC_XLOCK(p->p_fd); if ((error = fdalloc(td, 0, &i))) { FILEDESC_XUNLOCK(p->p_fd); @@ -2216,6 +2217,8 @@ error = fo_close(fp, td); atomic_subtract_int(&openfiles, 1); crfree(fp->f_cred); + if (!LIST_EMPTY(&fp->f_caps)) + panic("_fdrop: f_caps not empty"); uma_zfree(file_zone, fp); return (error); ==== //depot/projects/trustedbsd/capabilities/src/sys/kern/sys_capability.c#14 (text+ko) ==== @@ -41,7 +41,7 @@ */ #include -__FBSDID("$P4: //depot/projects/trustedbsd/capabilities/src/sys/kern/sys_capability.c#13 $"); +__FBSDID("$P4: //depot/projects/trustedbsd/capabilities/src/sys/kern/sys_capability.c#14 $"); #include #include @@ -59,13 +59,17 @@ /* * struct capability describes a capability, and is hung off of its struct - * file f_data field. All fields are static once hooked up, as neither the - * object it references nor the rights it encapsulates are permitted to - * change. + * file f_data field. cap_file and cap_rightss are static once hooked up, as + * neither the object it references nor the rights it encapsulates are + * permitted to change. cap_filelist may change when other capabilites are + * added or removed from the same file, and is currently protected by + * cap_file_mtx. */ struct capability { - struct file *cap_file; - cap_rights_t cap_rights; + struct file *cap_object; /* Underlying object's file. */ + struct file *cap_file; /* Back-pointer to cap's file. */ + cap_rights_t cap_rights; /* Mask of rights on object. */ + LIST_ENTRY(capability) cap_filelist; /* Object's cap list. */ }; /* @@ -96,6 +100,14 @@ static uma_zone_t capability_zone; +/* + * XXXRW: Each file descriptor contains a list of capabilities pointing at it + * so that we the UNIX domain socket GC routine can calculate whether there + * are external references. Ideally we'd use a per-file lock, but right now + * we don't have one, so use a global mutex for now. + */ +static struct mtx cap_file_mtx; + static void capability_init(void *dummy __unused) { @@ -105,6 +117,7 @@ 0); if (capability_zone == NULL) panic("capability_init: capability_zone not initialized"); + mtx_init(&cap_file_mtx, "cap_file_mtx", NULL, MTX_DEF); } SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_ANY, capability_init, NULL); @@ -142,7 +155,7 @@ error = cap_check(c, rights); if (error) return (error); - *fpp = c->cap_file; + *fpp = c->cap_object; return (0); } @@ -235,13 +248,22 @@ * deal with capability chains. */ if (fp->f_type == DTYPE_CAPABILITY) - fp_object = ((struct capability *)fp->f_data)->cap_file; + fp_object = ((struct capability *)fp->f_data)->cap_object; else fp_object = fp; fhold(fp_object); c->cap_rights = uap->rights; - c->cap_file = fp_object; + c->cap_object = fp_object; + c->cap_file = fp_cap; finit(fp_cap, fp->f_flag, DTYPE_CAPABILITY, c, &capability_ops); + + /* + * Add this capability to the per-file list of referencing + * capabilities. + */ + mtx_lock(&cap_file_mtx); + LIST_INSERT_HEAD(&fp_object->f_caps, c, cap_filelist); + mtx_unlock(&cap_file_mtx); td->td_retval[0] = fd_cap; fdrop(fp, td); fdrop(fp_cap, td); @@ -290,7 +312,10 @@ c = fp->f_data; fp->f_ops = &badfileops; fp->f_data = NULL; - fp_object = c->cap_file; + fp_object = c->cap_object; + mtx_lock(&cap_file_mtx); + LIST_REMOVE(c, cap_filelist); + mtx_unlock(&cap_file_mtx); uma_zfree(capability_zone, c); return (fdrop(fp_object, td)); } ==== //depot/projects/trustedbsd/capabilities/src/sys/sys/file.h#5 (text+ko) ==== @@ -130,6 +130,7 @@ * Mandatory Access control information. */ void *f_label; /* Place-holder for MAC label. */ + LIST_HEAD(, capability) f_caps; /* List of capabilities for file. */ }; #define FOFFSET_LOCKED 0x1