Page MenuHomeFreeBSD

D55852.id.diff
No OneTemporary

D55852.id.diff

diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -28,7 +28,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "opt_ktrace.h"
#include "opt_kqueue.h"
@@ -1803,6 +1802,19 @@
error = ENOMEM;
goto done;
}
+
+ /*
+ * Now that the kqueue is locked, make sure the fd
+ * didn't change out from under us.
+ */
+ if (fops->f_isfd &&
+ fget_noref_unlocked(td->td_proc->p_fd,
+ kev->ident) != fp) {
+ KQ_UNLOCK(kq);
+ tkn = kn;
+ error = EBADF;
+ goto done;
+ }
kn->kn_fp = fp;
kn->kn_kq = kq;
kn->kn_fop = fops;
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -212,6 +212,8 @@
#ifdef _KERNEL
+#include <machine/atomic.h>
+
/* Operation types for kern_dup(). */
enum {
FDDUP_NORMAL, /* dup() behavior. */
@@ -303,6 +305,21 @@
MPASS(refcount_load(&fp->f_count) > 0); \
})
+/*
+ * Look up a file description without requiring a lock. In general the result
+ * may be immediately invalidated after the function returns, the caller must
+ * handle this.
+ */
+static inline struct file *
+fget_noref_unlocked(struct filedesc *fdp, int fd)
+{
+ if (__predict_false(
+ (u_int)fd >= (u_int)atomic_load_int(&fdp->fd_nfiles)))
+ return (NULL);
+
+ return (atomic_load_ptr(&fdp->fd_ofiles[fd].fde_file));
+}
+
/* Requires a FILEDESC_{S,X}LOCK held and returns without a ref. */
static __inline struct file *
fget_noref(struct filedesc *fdp, int fd)

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 6, 1:19 PM (10 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30972202
Default Alt Text
D55852.id.diff (1 KB)

Event Timeline