- 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:
John Baldwin 2006-07-28 16:56:17 +00:00
parent 096146f88b
commit 95e7d19dfa
3 changed files with 44 additions and 12 deletions

View file

@ -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);

View file

@ -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 */
};
/*

View file

@ -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, \