summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_proc.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/kern_proc.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/kern_proc.c')
-rw-r--r--sys/kern/kern_proc.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 9fd0f45..4a4282a 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -194,25 +194,33 @@ chgproccnt(uid, diff, max)
* Change the total socket buffer size a user has used.
*/
int
-chgsbsize(uid, diff, max)
+chgsbsize(uid, hiwat, to, max)
uid_t uid;
- rlim_t diff;
+ u_long *hiwat;
+ u_long to;
rlim_t max;
{
struct uidinfo *uip;
+ rlim_t diff;
+ int s;
uip = uifind(uid);
- if (diff < 0)
- KASSERT(uip != NULL, ("reducing sbsize: lost count, uid = %d", uid));
+ KASSERT(to >= *hiwat || uip != NULL,
+ ("reducing sbsize: lost count, uid = %d", uid));
if (uip == NULL)
uip = uicreate(uid);
+ s = splnet();
+ diff = to - *hiwat;
/* don't allow them to exceed max, but allow subtraction */
if (diff > 0 && uip->ui_sbsize + diff > max) {
(void)uifree(uip);
+ splx(s);
return (0);
}
uip->ui_sbsize += diff;
+ *hiwat = to;
(void)uifree(uip);
+ splx(s);
return (1);
}
OpenPOWER on IntegriCloud