From 2f6bb57841c5e23ce4344092bd23a3181aa1e14b Mon Sep 17 00:00:00 2001 From: jhb Date: Fri, 28 Jul 2006 16:56:17 +0000 Subject: - 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. --- sys/compat/svr4/svr4_stream.c | 38 +++++++++++++++++++++++++++++++++----- sys/compat/svr4/svr4_stropts.h | 12 ++++++++---- sys/compat/svr4/syscalls.master | 6 +++--- 3 files changed, 44 insertions(+), 12 deletions(-) (limited to 'sys/compat') diff --git a/sys/compat/svr4/svr4_stream.c b/sys/compat/svr4/svr4_stream.c index 23ec484..6ae5c1c 100644 --- a/sys/compat/svr4/svr4_stream.c +++ b/sys/compat/svr4/svr4_stream.c @@ -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); diff --git a/sys/compat/svr4/svr4_stropts.h b/sys/compat/svr4/svr4_stropts.h index c7847a6..a96c24d 100644 --- a/sys/compat/svr4/svr4_stropts.h +++ b/sys/compat/svr4/svr4_stropts.h @@ -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 */ }; /* diff --git a/sys/compat/svr4/syscalls.master b/sys/compat/svr4/syscalls.master index b407c12..58ae297 100644 --- a/sys/compat/svr4/syscalls.master +++ b/sys/compat/svr4/syscalls.master @@ -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, \ -- cgit v1.1