In an SMP environment post-Giant it is no longer safe to blindly
dereference the struct sigio pointer without any locking. Change fgetown() to take a reference to the pointer instead of a copy of the pointer and call SIGIO_LOCK() before copying the pointer and dereferencing it. Reviewed by: rwatson
This commit is contained in:
parent
5da2b58aeb
commit
91e97a8266
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=104393
@ -1203,7 +1203,7 @@ int DRM(ioctl)( DRM_OS_IOCTL )
|
||||
|
||||
case FIOGETOWN:
|
||||
atomic_dec(&dev->ioctl_count);
|
||||
*(int *) data = fgetown(dev->buf_sigio);
|
||||
*(int *) data = fgetown(&dev->buf_sigio);
|
||||
return 0;
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
|
@ -775,10 +775,15 @@ fsetown(pgid, sigiop)
|
||||
* This is common code for FIOGETOWN ioctl called by fcntl(fd, F_GETOWN, arg).
|
||||
*/
|
||||
pid_t
|
||||
fgetown(sigio)
|
||||
struct sigio *sigio;
|
||||
fgetown(sigiop)
|
||||
struct sigio **sigiop;
|
||||
{
|
||||
return (sigio != NULL ? sigio->sio_pgid : 0);
|
||||
pid_t pgid;
|
||||
|
||||
SIGIO_LOCK();
|
||||
pgid = (*sigiop != NULL) ? (*sigiop)->sio_pgid : 0;
|
||||
SIGIO_UNLOCK();
|
||||
return (pgid);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -239,7 +239,7 @@ logioctl(dev_t dev, u_long com, caddr_t data, int flag, struct thread *td)
|
||||
return (fsetown(*(int *)data, &logsoftc.sc_sigio));
|
||||
|
||||
case FIOGETOWN:
|
||||
*(int *)data = fgetown(logsoftc.sc_sigio);
|
||||
*(int *)data = fgetown(&logsoftc.sc_sigio);
|
||||
break;
|
||||
|
||||
/* This is deprecated, FIOSETOWN should be used instead. */
|
||||
@ -248,7 +248,7 @@ logioctl(dev_t dev, u_long com, caddr_t data, int flag, struct thread *td)
|
||||
|
||||
/* This is deprecated, FIOGETOWN should be used instead */
|
||||
case TIOCGPGRP:
|
||||
*(int *)data = -fgetown(logsoftc.sc_sigio);
|
||||
*(int *)data = -fgetown(&logsoftc.sc_sigio);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1204,7 +1204,7 @@ pipe_ioctl(fp, cmd, data, active_cred, td)
|
||||
|
||||
case FIOGETOWN:
|
||||
PIPE_UNLOCK(mpipe);
|
||||
*(int *)data = fgetown(mpipe->pipe_sigio);
|
||||
*(int *)data = fgetown(&mpipe->pipe_sigio);
|
||||
return (0);
|
||||
|
||||
/* This is deprecated, FIOSETOWN should be used instead. */
|
||||
@ -1215,7 +1215,7 @@ pipe_ioctl(fp, cmd, data, active_cred, td)
|
||||
/* This is deprecated, FIOGETOWN should be used instead. */
|
||||
case TIOCGPGRP:
|
||||
PIPE_UNLOCK(mpipe);
|
||||
*(int *)data = -fgetown(mpipe->pipe_sigio);
|
||||
*(int *)data = -fgetown(&mpipe->pipe_sigio);
|
||||
return (0);
|
||||
|
||||
}
|
||||
|
@ -131,14 +131,14 @@ soo_ioctl(fp, cmd, data, active_cred, td)
|
||||
return (fsetown(*(int *)data, &so->so_sigio));
|
||||
|
||||
case FIOGETOWN:
|
||||
*(int *)data = fgetown(so->so_sigio);
|
||||
*(int *)data = fgetown(&so->so_sigio);
|
||||
return (0);
|
||||
|
||||
case SIOCSPGRP:
|
||||
return (fsetown(-(*(int *)data), &so->so_sigio));
|
||||
|
||||
case SIOCGPGRP:
|
||||
*(int *)data = -fgetown(so->so_sigio);
|
||||
*(int *)data = -fgetown(&so->so_sigio);
|
||||
return (0);
|
||||
|
||||
case SIOCATMARK:
|
||||
|
@ -827,7 +827,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
|
||||
case FIOGETOWN:
|
||||
if (tp->t_session != NULL && !isctty(p, tp))
|
||||
return (ENOTTY);
|
||||
*(int *)data = fgetown(tp->t_sigio);
|
||||
*(int *)data = fgetown(&tp->t_sigio);
|
||||
break;
|
||||
|
||||
case TIOCEXCL: /* set exclusive use of tty */
|
||||
|
@ -247,6 +247,7 @@ accept1(td, uap, compat)
|
||||
struct socket *head, *so;
|
||||
int fd;
|
||||
u_int fflag;
|
||||
pid_t pgid;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
fdp = td->td_proc->p_fd;
|
||||
@ -324,8 +325,9 @@ accept1(td, uap, compat)
|
||||
|
||||
so->so_state &= ~SS_COMP;
|
||||
so->so_head = NULL;
|
||||
if (head->so_sigio != NULL)
|
||||
fsetown(fgetown(head->so_sigio), &so->so_sigio);
|
||||
pgid = fgetown(&head->so_sigio);
|
||||
if (pgid != 0)
|
||||
fsetown(pgid, &so->so_sigio);
|
||||
|
||||
FILE_LOCK(nfp);
|
||||
soref(so); /* file descriptor reference */
|
||||
|
@ -866,7 +866,7 @@ bpfioctl(dev, cmd, addr, flags, td)
|
||||
break;
|
||||
|
||||
case FIOGETOWN:
|
||||
*(int *)addr = fgetown(d->bd_sigio);
|
||||
*(int *)addr = fgetown(&d->bd_sigio);
|
||||
break;
|
||||
|
||||
/* This is deprecated, FIOSETOWN should be used instead. */
|
||||
@ -876,7 +876,7 @@ bpfioctl(dev, cmd, addr, flags, td)
|
||||
|
||||
/* This is deprecated, FIOGETOWN should be used instead. */
|
||||
case TIOCGPGRP:
|
||||
*(int *)addr = -fgetown(d->bd_sigio);
|
||||
*(int *)addr = -fgetown(&d->bd_sigio);
|
||||
break;
|
||||
|
||||
case BIOCSRSIG: /* Set receive signal */
|
||||
|
@ -709,7 +709,7 @@ tapioctl(dev, cmd, data, flag, td)
|
||||
return (fsetown(*(int *)data, &tp->tap_sigio));
|
||||
|
||||
case FIOGETOWN:
|
||||
*(int *)data = fgetown(tp->tap_sigio);
|
||||
*(int *)data = fgetown(&tp->tap_sigio);
|
||||
return (0);
|
||||
|
||||
/* this is deprecated, FIOSETOWN should be used instead */
|
||||
@ -718,7 +718,7 @@ tapioctl(dev, cmd, data, flag, td)
|
||||
|
||||
/* this is deprecated, FIOGETOWN should be used instead */
|
||||
case TIOCGPGRP:
|
||||
*(int *)data = -fgetown(tp->tap_sigio);
|
||||
*(int *)data = -fgetown(&tp->tap_sigio);
|
||||
return (0);
|
||||
|
||||
/* VMware/VMnet port ioctl's */
|
||||
|
@ -622,7 +622,7 @@ tunioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
|
||||
return (fsetown(*(int *)data, &tp->tun_sigio));
|
||||
|
||||
case FIOGETOWN:
|
||||
*(int *)data = fgetown(tp->tun_sigio);
|
||||
*(int *)data = fgetown(&tp->tun_sigio);
|
||||
return (0);
|
||||
|
||||
/* This is deprecated, FIOSETOWN should be used instead. */
|
||||
@ -631,7 +631,7 @@ tunioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
|
||||
|
||||
/* This is deprecated, FIOGETOWN should be used instead. */
|
||||
case TIOCGPGRP:
|
||||
*(int *)data = -fgetown(tp->tun_sigio);
|
||||
*(int *)data = -fgetown(&tp->tun_sigio);
|
||||
return (0);
|
||||
|
||||
default:
|
||||
|
@ -154,7 +154,7 @@ struct filedesc *fdinit(struct thread *td);
|
||||
struct filedesc *fdshare(struct proc *p);
|
||||
void ffree(struct file *fp);
|
||||
static __inline struct file * fget_locked(struct filedesc *fdp, int fd);
|
||||
pid_t fgetown(struct sigio *sigio);
|
||||
pid_t fgetown(struct sigio **sigiop);
|
||||
int fsetown(pid_t pgid, struct sigio **sigiop);
|
||||
void funsetown(struct sigio **sigiop);
|
||||
void funsetownlst(struct sigiolst *sigiolst);
|
||||
|
Loading…
Reference in New Issue
Block a user