Source-Changes-D archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: CVS commit: src/share/man/man4
On Tue, 5 Jan 2016, Christos Zoulas wrote:
| Unless I can reliably determine which fd the program is using for its
| access to /dev/filemon I don't have anything to which I can compare the
| requested activity_log fd.
You could scan the whole fd array and look for DT_MISC with fops ==
filemon ops and if you find one that would cause a deadlock, deny.
Again this is a hack... But at least it should prevent the deadlock.
Yeah, this is workable, even if it is a HACK ! :)
The attached patch borrows extensively from fd_free() routine in
kern/kern_descrip.c
Let me know if this looks "good enough" and I will commit it. (I'll
also update the BUGS section of the man-page to describe the hack.)
FWIW, I have tested with log-file fd values of 1 and 4, while the
/dev/filemon fd is always 3. In the "1" case the patch correctly
returned EINVAL (it would cause a deadlock), while the "4" case
succeeded and no deadlock occurred.
+------------------+--------------------------+------------------------+
| Paul Goyette | PGP Key fingerprint: | E-mail addresses: |
| (Retired) | FA29 0E3B 35AF E8AE 6651 | paul at whooppee.com |
| Kernel Developer | 0786 F758 55DE 53BA 7731 | pgoyette at netbsd.org |
+------------------+--------------------------+------------------------+
Index: filemon.c
===================================================================
RCS file: /cvsroot/src/sys/dev/filemon/filemon.c,v
retrieving revision 1.24
diff -u -p -r1.24 filemon.c
--- filemon.c 5 Jan 2016 22:08:54 -0000 1.24
+++ filemon.c 6 Jan 2016 05:05:04 -0000
@@ -279,8 +279,12 @@ static int
filemon_ioctl(struct file * fp, u_long cmd, void *data)
{
int error = 0;
+ int i, nf, fd;
struct filemon *filemon;
struct proc *tp;
+ fdfile_t *ff;
+ filedesc_t *fdp;
+ fdtab_t *dt;
#ifdef DEBUG
log(logLevel, "filemon_ioctl(%lu)", cmd);;
@@ -303,8 +307,41 @@ filemon_ioctl(struct file * fp, u_long c
if (filemon->fm_fp)
fd_putfile(filemon->fm_fd);
+ /*
+ * XXX HACK XXX
+ *
+ * Due to our taking an extra reference on the
+ * descriptor's struct file, we need to ensure that
+ * the descriptor number is at least as large as
+ * the one used to access /dev/filemon. Otherwise,
+ * we get a deadlock during process exit, waiting
+ * for the output file's reference count.
+ */
+ fd = *((int *) data);
+ fdp = curproc->p_fd;
+ dt = curlwp->l_fd->fd_dt;
+ nf = dt->dt_nfiles;
+ error = EINVAL;
+ for (i = 0; i < nf; i++) {
+ if (i >= fd)
+ break;
+ ff = dt->dt_ff[i];
+ KASSERT(fd >= NDFDFILE ||
+ ff == (fdfile_t *)fdp->fd_dfdfile[i]);
+ if (ff == NULL)
+ continue;
+
+ if (ff->ff_file->f_type == DTYPE_MISC &&
+ ff->ff_file->f_ops == &filemon_fileops) {
+ error = 0;
+ break;
+ }
+ }
+ if (error)
+ break;
+
/* Now set up the new one */
- filemon->fm_fd = *((int *) data);
+ filemon->fm_fd = fd;
if ((filemon->fm_fp = fd_getfile(filemon->fm_fd)) == NULL) {
error = EBADF;
break;
Home |
Main Index |
Thread Index |
Old Index