summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_usrreq.c
diff options
context:
space:
mode:
authorgreen <green@FreeBSD.org>2000-08-29 11:28:06 +0000
committergreen <green@FreeBSD.org>2000-08-29 11:28:06 +0000
commit0fa5ae2859837ce45dfa1d212731cbed7a6bf037 (patch)
treea0487072d9e3fda944c9970116207cd67e21e923 /sys/kern/uipc_usrreq.c
parent0290d697a80874eccbc3e0228ae5f2acb2b7522c (diff)
downloadFreeBSD-src-0fa5ae2859837ce45dfa1d212731cbed7a6bf037.zip
FreeBSD-src-0fa5ae2859837ce45dfa1d212731cbed7a6bf037.tar.gz
Remove any possibility of hiwat-related race conditions by changing
the chgsbsize() call to use a "subject" pointer (&sb.sb_hiwat) and a u_long target to set it to. The whole thing is splnet(). This fixes a problem that jdp has been able to provoke.
Diffstat (limited to 'sys/kern/uipc_usrreq.c')
-rw-r--r--sys/kern/uipc_usrreq.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index a0b4072..c4a3326 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -217,6 +217,7 @@ uipc_rcvd(struct socket *so, int flags)
{
struct unpcb *unp = sotounpcb(so);
struct socket *so2;
+ u_long newhiwat;
if (unp == 0)
return EINVAL;
@@ -235,9 +236,10 @@ uipc_rcvd(struct socket *so, int flags)
*/
so2->so_snd.sb_mbmax += unp->unp_mbcnt - so->so_rcv.sb_mbcnt;
unp->unp_mbcnt = so->so_rcv.sb_mbcnt;
- so2->so_snd.sb_hiwat += unp->unp_cc - so->so_rcv.sb_cc;
- (void)chgsbsize(so2->so_cred->cr_uid,
- (rlim_t)unp->unp_cc - so->so_rcv.sb_cc, RLIM_INFINITY);
+ newhiwat = so2->so_snd.sb_hiwat + unp->unp_cc -
+ so->so_rcv.sb_cc;
+ (void)chgsbsize(so2->so_cred->cr_uid, &so2->so_snd.sb_hiwat,
+ newhiwat, RLIM_INFINITY);
unp->unp_cc = so->so_rcv.sb_cc;
sowwakeup(so2);
break;
@@ -257,6 +259,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
int error = 0;
struct unpcb *unp = sotounpcb(so);
struct socket *so2;
+ u_long newhiwat;
if (unp == 0) {
error = EINVAL;
@@ -342,10 +345,10 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
so->so_snd.sb_mbmax -=
so2->so_rcv.sb_mbcnt - unp->unp_conn->unp_mbcnt;
unp->unp_conn->unp_mbcnt = so2->so_rcv.sb_mbcnt;
- so->so_snd.sb_hiwat -=
- so2->so_rcv.sb_cc - unp->unp_conn->unp_cc;
- (void)chgsbsize(so->so_cred->cr_uid,
- (rlim_t)unp->unp_conn->unp_cc - so2->so_rcv.sb_cc, RLIM_INFINITY);
+ newhiwat = so->so_snd.sb_hiwat -
+ (so2->so_rcv.sb_cc - unp->unp_conn->unp_cc);
+ (void)chgsbsize(so->so_cred->cr_uid, &so->so_snd.sb_hiwat,
+ newhiwat, RLIM_INFINITY);
unp->unp_conn->unp_cc = so2->so_rcv.sb_cc;
sorwakeup(so2);
m = 0;
OpenPOWER on IntegriCloud