svn commit: r324597 - head/sys/compat/linuxkpi/common/src
Hans Petter Selasky
hselasky at FreeBSD.org
Fri Oct 13 14:14:47 UTC 2017
Author: hselasky
Date: Fri Oct 13 14:14:46 2017
New Revision: 324597
URL: https://svnweb.freebsd.org/changeset/base/324597
Log:
Don't call selrecord() outside the select system call in the LinuxKPI, because
then td->td_sel is NULL and this will result in a segfault inside selrecord().
This happens when only using kqueue() to poll for read and write events.
If select() and kqueue() is mixed there won't be a segfault.
Reported by: Johannes Lundberg
MFC after: 1 week
Sponsored by: Mellanox Technologies
Modified:
head/sys/compat/linuxkpi/common/src/linux_compat.c
Modified: head/sys/compat/linuxkpi/common/src/linux_compat.c
==============================================================================
--- head/sys/compat/linuxkpi/common/src/linux_compat.c Fri Oct 13 13:56:44 2017 (r324596)
+++ head/sys/compat/linuxkpi/common/src/linux_compat.c Fri Oct 13 14:14:46 2017 (r324597)
@@ -1021,6 +1021,8 @@ linux_dev_write(struct cdev *dev, struct uio *uio, int
return (error);
}
+#define LINUX_POLL_TABLE_NORMAL ((poll_table *)1)
+
static int
linux_dev_poll(struct cdev *dev, int events, struct thread *td)
{
@@ -1037,7 +1039,7 @@ linux_dev_poll(struct cdev *dev, int events, struct th
filp->f_flags = file->f_flag;
linux_set_current(td);
if (filp->f_op->poll != NULL)
- revents = filp->f_op->poll(filp, NULL) & events;
+ revents = filp->f_op->poll(filp, LINUX_POLL_TABLE_NORMAL) & events;
else
revents = 0;
@@ -1094,7 +1096,9 @@ linux_poll_wait(struct linux_file *filp, wait_queue_he
[LINUX_FWQ_STATE_READY] = LINUX_FWQ_STATE_QUEUED,
};
- selrecord(curthread, &filp->f_selinfo);
+ /* check if we are called inside the select system call */
+ if (p == LINUX_POLL_TABLE_NORMAL)
+ selrecord(curthread, &filp->f_selinfo);
switch (linux_poll_wakeup_state(&filp->f_wait_queue.state, state)) {
case LINUX_FWQ_STATE_INIT:
@@ -1438,10 +1442,9 @@ linux_file_poll(struct file *file, int events, struct
filp = (struct linux_file *)file->f_data;
filp->f_flags = file->f_flag;
linux_set_current(td);
- if (filp->f_op->poll != NULL) {
- selrecord(td, &filp->f_selinfo);
- revents = filp->f_op->poll(filp, NULL) & events;
- } else
+ if (filp->f_op->poll != NULL)
+ revents = filp->f_op->poll(filp, LINUX_POLL_TABLE_NORMAL) & events;
+ else
revents = 0;
return (revents);
More information about the svn-src-all
mailing list