Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153066609
D35987.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D35987.diff
View Options
Index: sys/kern/kern_descrip.c
===================================================================
--- sys/kern/kern_descrip.c
+++ sys/kern/kern_descrip.c
@@ -2153,6 +2153,9 @@
if (fcaps != NULL)
filecaps_validate(fcaps, __func__);
FILEDESC_XLOCK_ASSERT(fdp);
+ KASSERT(refcount_load(&fdp->fd_refcnt) == 1 ||
+ (fp->f_ops->fo_flags & DFLAG_PASSABLE) != 0,
+ ("%s: file %p cannot be shared", __func__, fp));
fde = &fdp->fd_ofiles[fd];
#ifdef CAPABILITIES
@@ -2179,10 +2182,13 @@
MPASS(fd != NULL);
FILEDESC_XLOCK(fdp);
- error = fdalloc(td, 0, fd);
- if (__predict_true(error == 0)) {
+ if (__predict_false(refcount_load(&fdp->fd_refcnt) > 1) &&
+ (fp->f_ops->fo_flags & DFLAG_PASSABLE) == 0)
+ error = EOPNOTSUPP;
+ else
+ error = fdalloc(td, 0, fd);
+ if (__predict_true(error == 0))
_finstall(fdp, fp, *fd, flags, fcaps);
- }
FILEDESC_XUNLOCK(fdp);
return (error);
}
@@ -2336,14 +2342,38 @@
}
/*
- * Share a filedesc structure.
+ * Share a filedesc structure (among multiple processes). Descriptors that
+ * cannot be passed among processes may not exist in a shared table.
*/
struct filedesc *
fdshare(struct filedesc *fdp)
{
+ struct file *fp;
+ int i;
+ bool ok;
- refcount_acquire(&fdp->fd_refcnt);
- return (fdp);
+ ok = true;
+ FILEDESC_SLOCK(fdp);
+ FILEDESC_FOREACH_FP(fdp, i, fp) {
+ if ((fp->f_ops->fo_flags & DFLAG_PASSABLE) == 0) {
+ ok = false;
+ break;
+ }
+ }
+ if (ok)
+ refcount_acquire(&fdp->fd_refcnt);
+ FILEDESC_SUNLOCK(fdp);
+ return (ok ? fdp : NULL);
+}
+
+void
+fdshare_abort(struct filedesc *fdp)
+{
+ bool released __diagused;
+
+ released = refcount_release(&fdp->fd_refcnt);
+ KASSERT(!released,
+ ("fdshare_abort: released last reference on %p", fdp));
}
/*
Index: sys/kern/kern_fork.c
===================================================================
--- sys/kern/kern_fork.c
+++ sys/kern/kern_fork.c
@@ -442,7 +442,9 @@
pd = pdcopy(p1->p_pd);
else
pd = pdshare(p1->p_pd);
- fd = fdshare(p1->p_fd);
+
+ /* FD table is already shared by the caller. */
+ fd = p1->p_fd;
if (p1->p_fdtol == NULL)
p1->p_fdtol = filedesc_to_leader_alloc(NULL, NULL,
p1->p_leader);
@@ -867,6 +869,7 @@
struct vmspace *vm2;
struct ucred *cred;
struct file *fp_procdesc;
+ struct filedesc *fdp;
vm_ooffset_t mem_charged;
int error, nprocs_new;
static int curfail;
@@ -925,10 +928,21 @@
return (fork_norfproc(td, flags));
}
+ fdp = NULL;
fp_procdesc = NULL;
newproc = NULL;
vm2 = NULL;
+ /*
+ * Take an extra reference to the file descriptor table if the table is
+ * to be shared.
+ */
+ if ((flags & RFFDG) == 0) {
+ fdp = fdshare(td->td_proc->p_fd);
+ if (fdp == NULL)
+ return (EOPNOTSUPP);
+ }
+
/*
* Increment the nprocs resource before allocations occur.
* Although process entries are dynamically created, we still
@@ -1060,6 +1074,8 @@
fail2:
if (vm2 != NULL)
vmspace_free(vm2);
+ if (fdp != NULL)
+ fdshare_abort(fdp);
uma_zfree(proc_zone, newproc);
if ((flags & RFPROCDESC) != 0 && fp_procdesc != NULL) {
fdclose(td, fp_procdesc, *fr->fr_pd_fd);
Index: sys/sys/filedesc.h
===================================================================
--- sys/sys/filedesc.h
+++ sys/sys/filedesc.h
@@ -115,7 +115,7 @@
struct fdescenttbl *fd_files; /* open files table */
NDSLOTTYPE *fd_map; /* bitmap of free fds */
int fd_freefile; /* approx. next free file */
- int fd_refcnt; /* thread reference count */
+ int fd_refcnt; /* process reference count */
int fd_holdcnt; /* hold count on structure + mutex */
struct sx fd_sx; /* protects members of this struct */
struct kqlist fd_kqlist; /* list of kqueues on this filedesc */
@@ -267,6 +267,7 @@
int fdlastfile_single(struct filedesc *fdp);
struct filedesc *fdinit(void);
struct filedesc *fdshare(struct filedesc *fdp);
+void fdshare_abort(struct filedesc *fdp);
struct filedesc_to_leader *
filedesc_to_leader_alloc(struct filedesc_to_leader *old,
struct filedesc *fdp, struct proc *leader);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 19, 10:34 PM (12 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31804922
Default Alt Text
D35987.diff (3 KB)
Attached To
Mode
D35987: fork: Disallow sharing of fd tables with non-passable descriptors
Attached
Detach File
Event Timeline
Log In to Comment