PERFORCE change 134020 for review
Robert Watson
rwatson at FreeBSD.org
Thu Jan 24 10:31:29 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=134020
Change 134020 by rwatson at rwatson_freebsd_capabilities on 2008/01/24 18:30:30
Rework file descriptor close to better understand capabilities:
notifications of close(fd) to file locking and mqueue notification
must happen with the underlying file descriptor and not the
capability.
Properly drop the extra thread-owned reference to a new
capability once cap_new() is done.
Move capability_close() above various implementations of panic()
for fileops.
Affected files ...
.. //depot/projects/trustedbsd/capabilities/src/sys/kern/kern_descrip.c#5 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/kern/sys_capability.c#10 edit
Differences ...
==== //depot/projects/trustedbsd/capabilities/src/sys/kern/kern_descrip.c#5 (text+ko) ====
@@ -1011,7 +1011,7 @@
int fd;
{
struct filedesc *fdp;
- struct file *fp;
+ struct file *fp, *fp_object;
int error;
int holdleaders;
@@ -1046,8 +1046,14 @@
* added, and deleteing a knote for the new fd.
*/
knote_fdclose(td, fd);
- if (fp->f_type == DTYPE_MQUEUE)
- mq_fdclose(td, fd, fp);
+
+ /*
+ * When we're closing an fd with a capability, we need to notify
+ * mqueue if the underlying object is of type mqueue.
+ */
+ (void)cap_fextract(fp, 0, &fp_object);
+ if (fp_object->f_type == DTYPE_MQUEUE)
+ mq_fdclose(td, fd, fp_object);
FILEDESC_XUNLOCK(fdp);
error = closef(fp, td);
@@ -1882,6 +1888,7 @@
struct flock lf;
struct filedesc_to_leader *fdtol;
struct filedesc *fdp;
+ struct file *fp_object;
/*
* POSIX record locking dictates that any close releases ALL
@@ -1894,11 +1901,15 @@
* NULL thread pointer when there really is no owning
* context that might have locks, or the locks will be
* leaked.
+ *
+ * If this is a capability, we do lock processing under the
+ * underyling vnode, not the capability.
*/
- if (fp->f_type == DTYPE_VNODE && td != NULL) {
+ (void)cap_fextract(fp, 0, &fp_object);
+ if (fp_object->f_type == DTYPE_VNODE && td != NULL) {
int vfslocked;
- vp = fp->f_vnode;
+ vp = fp_object->f_vnode;
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
if ((td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0) {
lf.l_whence = SEEK_SET;
@@ -1928,7 +1939,7 @@
lf.l_start = 0;
lf.l_len = 0;
lf.l_type = F_UNLCK;
- vp = fp->f_vnode;
+ vp = fp_object->f_vnode;
(void) VOP_ADVLOCK(vp,
(caddr_t)fdtol->fdl_leader,
F_UNLCK, &lf, F_POSIX);
@@ -2189,6 +2200,9 @@
/*
* Handle the last reference to a file being closed.
+ *
+ * No special capability handling here, as the capability's fo_close will run
+ * instead of the object here, and perform any necessary drop on the object.
*/
int
_fdrop(struct file *fp, struct thread *td)
==== //depot/projects/trustedbsd/capabilities/src/sys/kern/sys_capability.c#10 (text+ko) ====
@@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$P4: //depot/projects/trustedbsd/capabilities/src/sys/kern/sys_capability.c#9 $");
+__FBSDID("$P4: //depot/projects/trustedbsd/capabilities/src/sys/kern/sys_capability.c#10 $");
#include <sys/param.h>
#include <sys/capability.h>
@@ -263,6 +263,7 @@
finit(fp_cap, fp->f_flag, DTYPE_CAPABILITY, c, &capability_ops);
td->td_retval[0] = fd_cap;
fdrop(fp, td);
+ fdrop(fp_cap, td);
return (0);
fail2:
@@ -292,9 +293,31 @@
}
/*
+ * When a capability is closed, simply drop the reference on the underlying
+ * object and free the capability. fdrop() will handle the case where the
+ * underlying object also needs to close, and the caller will have already
+ * performed any object-specific lock or mqueue handling.
+ */
+static int
+capability_close(struct file *fp, struct thread *td)
+{
+ struct capability *c;
+ struct file *fp_object;
+
+ KASSERT(fp->f_type == DTYPE_CAPABILITY,
+ ("capability_close: !capability"));
+ c = fp->f_data;
+ fp->f_ops = &badfileops;
+ fp->f_data = NULL;
+ fp_object = c->cap_file;
+ uma_zfree(capability_zone, c);
+ return (fdrop(fp_object, td));
+}
+
+/*
* In general, file descriptor operations should never make it to the
- * capability, only the underlying file descriptor operation vector, so with
- * the exception of close(), panic if we do turn up here.
+ * capability, only the underlying file descriptor operation vector, so panic
+ * if we do turn up here.
*/
static int
capability_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
@@ -350,19 +373,3 @@
panic("capability_stat");
}
-
-static int
-capability_close(struct file *fp, struct thread *td)
-{
- struct capability *c;
- struct file *fp_object;
-
- KASSERT(fp->f_type == DTYPE_CAPABILITY,
- ("capability_close: !capability"));
- c = fp->f_data;
- fp->f_ops = &badfileops;
- fp->f_data = NULL;
- fp_object = c->cap_file;
- uma_zfree(capability_zone, c);
- return (fdrop(fp_object, td));
-}
More information about the p4-projects
mailing list