mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-16 15:11:52 +00:00
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
This commit is contained in:
parent
6e309d75d2
commit
627ac5b4e3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=324597
@ -1021,6 +1021,8 @@ linux_dev_write(struct cdev *dev, struct uio *uio, int ioflag)
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define LINUX_POLL_TABLE_NORMAL ((poll_table *)1)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
linux_dev_poll(struct cdev *dev, int events, struct thread *td)
|
linux_dev_poll(struct cdev *dev, int events, struct thread *td)
|
||||||
{
|
{
|
||||||
@ -1037,7 +1039,7 @@ linux_dev_poll(struct cdev *dev, int events, struct thread *td)
|
|||||||
filp->f_flags = file->f_flag;
|
filp->f_flags = file->f_flag;
|
||||||
linux_set_current(td);
|
linux_set_current(td);
|
||||||
if (filp->f_op->poll != NULL)
|
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
|
else
|
||||||
revents = 0;
|
revents = 0;
|
||||||
|
|
||||||
@ -1094,7 +1096,9 @@ linux_poll_wait(struct linux_file *filp, wait_queue_head_t *wqh, poll_table *p)
|
|||||||
[LINUX_FWQ_STATE_READY] = LINUX_FWQ_STATE_QUEUED,
|
[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)) {
|
switch (linux_poll_wakeup_state(&filp->f_wait_queue.state, state)) {
|
||||||
case LINUX_FWQ_STATE_INIT:
|
case LINUX_FWQ_STATE_INIT:
|
||||||
@ -1438,10 +1442,9 @@ linux_file_poll(struct file *file, int events, struct ucred *active_cred,
|
|||||||
filp = (struct linux_file *)file->f_data;
|
filp = (struct linux_file *)file->f_data;
|
||||||
filp->f_flags = file->f_flag;
|
filp->f_flags = file->f_flag;
|
||||||
linux_set_current(td);
|
linux_set_current(td);
|
||||||
if (filp->f_op->poll != NULL) {
|
if (filp->f_op->poll != NULL)
|
||||||
selrecord(td, &filp->f_selinfo);
|
revents = filp->f_op->poll(filp, LINUX_POLL_TABLE_NORMAL) & events;
|
||||||
revents = filp->f_op->poll(filp, NULL) & events;
|
else
|
||||||
} else
|
|
||||||
revents = 0;
|
revents = 0;
|
||||||
|
|
||||||
return (revents);
|
return (revents);
|
||||||
|
Loading…
Reference in New Issue
Block a user