mirror of
https://github.com/opnsense/src.git
synced 2026-04-29 10:11:09 -04:00
- Explicitly lock Giant to protect the fields in the svr4_strm structure
except for s_family (which is read-only once after it is set when the structure is created). - Mark svr4_sys_ioctl(), svr4_sys_getmsg(), and svr4_sys_putmsg() MPSAFE.
This commit is contained in:
parent
096146f88b
commit
95e7d19dfa
3 changed files with 44 additions and 12 deletions
|
|
@ -1041,13 +1041,16 @@ i_fdinsert(fp, td, retval, fd, cmd, dat)
|
|||
return EINVAL;
|
||||
}
|
||||
|
||||
mtx_lock(&Giant);
|
||||
if (st->s_afd == -1) {
|
||||
DPRINTF(("fdinsert: accept fd not found\n"));
|
||||
mtx_unlock(&Giant);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if ((error = copyin(dat, &fdi, sizeof(fdi))) != 0) {
|
||||
DPRINTF(("fdinsert: copyin failed %d\n", error));
|
||||
mtx_unlock(&Giant);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
@ -1057,16 +1060,19 @@ i_fdinsert(fp, td, retval, fd, cmd, dat)
|
|||
if ((error = dup2(td, &d2p)) != 0) {
|
||||
DPRINTF(("fdinsert: dup2(%d, %d) failed %d\n",
|
||||
st->s_afd, fdi.fd, error));
|
||||
mtx_unlock(&Giant);
|
||||
return error;
|
||||
}
|
||||
|
||||
if ((error = kern_close(td, st->s_afd)) != 0) {
|
||||
DPRINTF(("fdinsert: close(%d) failed %d\n",
|
||||
st->s_afd, error));
|
||||
mtx_unlock(&Giant);
|
||||
return error;
|
||||
}
|
||||
|
||||
st->s_afd = -1;
|
||||
mtx_unlock(&Giant);
|
||||
|
||||
*retval = 0;
|
||||
return 0;
|
||||
|
|
@ -1194,6 +1200,7 @@ i_setsig(fp, td, retval, fd, cmd, dat)
|
|||
oflags = td->td_retval[0];
|
||||
|
||||
/* update the flags */
|
||||
mtx_lock(&Giant);
|
||||
if (dat != NULL) {
|
||||
int mask;
|
||||
|
||||
|
|
@ -1212,6 +1219,7 @@ i_setsig(fp, td, retval, fd, cmd, dat)
|
|||
flags = oflags & ~O_ASYNC;
|
||||
st->s_eventmask = 0;
|
||||
}
|
||||
mtx_unlock(&Giant);
|
||||
|
||||
/* set the new flags, if changed */
|
||||
if (flags != oflags) {
|
||||
|
|
@ -1236,7 +1244,7 @@ i_getsig(fp, td, retval, fd, cmd, dat)
|
|||
u_long cmd;
|
||||
caddr_t dat;
|
||||
{
|
||||
int error;
|
||||
int error, eventmask;
|
||||
|
||||
if (dat != NULL) {
|
||||
struct svr4_strm *st = svr4_stream_get(fp);
|
||||
|
|
@ -1245,8 +1253,11 @@ i_getsig(fp, td, retval, fd, cmd, dat)
|
|||
DPRINTF(("i_getsig: bad file descriptor\n"));
|
||||
return EINVAL;
|
||||
}
|
||||
if ((error = copyout(&st->s_eventmask, dat,
|
||||
sizeof(st->s_eventmask))) != 0) {
|
||||
mtx_lock(&Giant);
|
||||
eventmask = st->s_eventmask;
|
||||
mtx_unlock(&Giant);
|
||||
if ((error = copyout(&eventmask, dat,
|
||||
sizeof(eventmask))) != 0) {
|
||||
DPRINTF(("i_getsig: bad eventmask pointer\n"));
|
||||
return error;
|
||||
}
|
||||
|
|
@ -1569,7 +1580,10 @@ svr4_do_putmsg(td, uap, fp)
|
|||
return ENOSYS;
|
||||
}
|
||||
|
||||
switch (st->s_cmd = sc.cmd) {
|
||||
mtx_lock(&Giant);
|
||||
st->s_cmd = sc.cmd;
|
||||
mtx_unlock(&Giant);
|
||||
switch (sc.cmd) {
|
||||
case SVR4_TI_CONNECT_REQUEST: /* connect */
|
||||
{
|
||||
|
||||
|
|
@ -1701,6 +1715,7 @@ svr4_do_getmsg(td, uap, fp)
|
|||
return ENOSYS;
|
||||
}
|
||||
|
||||
mtx_lock(&Giant);
|
||||
switch (st->s_cmd) {
|
||||
case SVR4_TI_CONNECT_REQUEST:
|
||||
DPRINTF(("getmsg: TI_CONNECT_REQUEST\n"));
|
||||
|
|
@ -1726,6 +1741,7 @@ svr4_do_getmsg(td, uap, fp)
|
|||
|
||||
error = kern_getpeername(td, uap->fd, &sa, &sasize);
|
||||
if (error) {
|
||||
mtx_unlock(&Giant);
|
||||
DPRINTF(("getmsg: getpeername failed %d\n", error));
|
||||
return error;
|
||||
}
|
||||
|
|
@ -1748,6 +1764,7 @@ svr4_do_getmsg(td, uap, fp)
|
|||
break;
|
||||
|
||||
default:
|
||||
mtx_unlock(&Giant);
|
||||
free(sa, M_SONAME);
|
||||
return ENOSYS;
|
||||
}
|
||||
|
|
@ -1782,6 +1799,7 @@ svr4_do_getmsg(td, uap, fp)
|
|||
|
||||
error = kern_accept(td, uap->fd, &sa, &sasize, &afp);
|
||||
if (error) {
|
||||
mtx_unlock(&Giant);
|
||||
DPRINTF(("getmsg: accept failed %d\n", error));
|
||||
return error;
|
||||
}
|
||||
|
|
@ -1814,6 +1832,7 @@ svr4_do_getmsg(td, uap, fp)
|
|||
fdclose(td->td_proc->p_fd, afp, st->s_afd, td);
|
||||
fdrop(afp, td);
|
||||
st->s_afd = -1;
|
||||
mtx_unlock(&Giant);
|
||||
free(sa, M_SONAME);
|
||||
return ENOSYS;
|
||||
}
|
||||
|
|
@ -1832,8 +1851,10 @@ svr4_do_getmsg(td, uap, fp)
|
|||
if (ctl.len > sizeof(sc))
|
||||
ctl.len = sizeof(sc);
|
||||
|
||||
if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0)
|
||||
if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0) {
|
||||
mtx_unlock(&Giant);
|
||||
return error;
|
||||
}
|
||||
|
||||
switch (st->s_family) {
|
||||
case AF_INET:
|
||||
|
|
@ -1847,6 +1868,7 @@ svr4_do_getmsg(td, uap, fp)
|
|||
break;
|
||||
|
||||
default:
|
||||
mtx_unlock(&Giant);
|
||||
return ENOSYS;
|
||||
}
|
||||
|
||||
|
|
@ -1862,6 +1884,7 @@ svr4_do_getmsg(td, uap, fp)
|
|||
error = kern_recvit(td, uap->fd, &msg, UIO_SYSSPACE, NULL);
|
||||
|
||||
if (error) {
|
||||
mtx_unlock(&Giant);
|
||||
DPRINTF(("getmsg: recvit failed %d\n", error));
|
||||
return error;
|
||||
}
|
||||
|
|
@ -1880,6 +1903,7 @@ svr4_do_getmsg(td, uap, fp)
|
|||
break;
|
||||
|
||||
default:
|
||||
mtx_unlock(&Giant);
|
||||
return ENOSYS;
|
||||
}
|
||||
|
||||
|
|
@ -1908,6 +1932,7 @@ svr4_do_getmsg(td, uap, fp)
|
|||
ra.buf = dat.buf;
|
||||
ra.nbyte = dat.maxlen;
|
||||
if ((error = read(td, &ra)) != 0) {
|
||||
mtx_unlock(&Giant);
|
||||
return error;
|
||||
}
|
||||
dat.len = *retval;
|
||||
|
|
@ -1915,6 +1940,7 @@ svr4_do_getmsg(td, uap, fp)
|
|||
st->s_cmd = SVR4_TI_SENDTO_REQUEST;
|
||||
break;
|
||||
}
|
||||
mtx_unlock(&Giant);
|
||||
DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd));
|
||||
return EINVAL;
|
||||
}
|
||||
|
|
@ -1945,8 +1971,10 @@ svr4_do_getmsg(td, uap, fp)
|
|||
fdrop(afp, td);
|
||||
st->s_afd = -1;
|
||||
}
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
mtx_unlock(&Giant);
|
||||
if (afp)
|
||||
fdrop(afp, td);
|
||||
|
||||
|
|
|
|||
|
|
@ -116,12 +116,16 @@ struct svr4_strioctl {
|
|||
* Our internal state for the stream
|
||||
* For now we keep almost nothing... In the future we can keep more
|
||||
* streams state.
|
||||
*
|
||||
* Locking key:
|
||||
* r - Read only field only set during creation
|
||||
* G - Giant
|
||||
*/
|
||||
struct svr4_strm {
|
||||
int s_family; /* socket family */
|
||||
int s_cmd; /* last getmsg reply or putmsg request */
|
||||
int s_afd; /* last accepted fd; [for fd_insert] */
|
||||
int s_eventmask; /* state info from I_SETSIG et al */
|
||||
int s_family; /* (r) socket family */
|
||||
int s_cmd; /* (G) last getmsg reply or putmsg request */
|
||||
int s_afd; /* (G) last accepted fd; [for fd_insert] */
|
||||
int s_eventmask; /* (G) state info from I_SETSIG et al */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@
|
|||
int a3, int a4, int a5); }
|
||||
53 AUE_NULL MSTD { int svr4_sys_semsys(int what, int a2, \
|
||||
int a3, int a4, int a5); }
|
||||
54 AUE_NULL STD { int svr4_sys_ioctl(int fd, u_long com, \
|
||||
54 AUE_NULL MSTD { int svr4_sys_ioctl(int fd, u_long com, \
|
||||
caddr_t data); }
|
||||
55 AUE_NULL UNIMPL uadmin
|
||||
56 AUE_NULL UNIMPL exch
|
||||
|
|
@ -141,10 +141,10 @@
|
|||
82 AUE_NULL UNIMPL libattach
|
||||
83 AUE_NULL UNIMPL libdetach
|
||||
84 AUE_NULL UNIMPL sysfs
|
||||
85 AUE_NULL STD { int svr4_sys_getmsg(int fd, \
|
||||
85 AUE_NULL MSTD { int svr4_sys_getmsg(int fd, \
|
||||
struct svr4_strbuf *ctl, \
|
||||
struct svr4_strbuf *dat, int *flags); }
|
||||
86 AUE_NULL STD { int svr4_sys_putmsg(int fd, \
|
||||
86 AUE_NULL MSTD { int svr4_sys_putmsg(int fd, \
|
||||
struct svr4_strbuf *ctl, \
|
||||
struct svr4_strbuf *dat, int flags); }
|
||||
87 AUE_NULL MSTD { int svr4_sys_poll(struct pollfd *fds, \
|
||||
|
|
|
|||
Loading…
Reference in a new issue