diff options
author | alfred <alfred@FreeBSD.org> | 2000-06-22 22:27:16 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2000-06-22 22:27:16 +0000 |
commit | 7f71a1a09199f766bb8569761d4cb15d13abdc22 (patch) | |
tree | 331e9f18a5ec115951f1cd9af64ffd33f945ed61 /sys/kern/uipc_socket.c | |
parent | 8b986caf33fc972c768af8986cc1cec3e794a9d4 (diff) | |
download | FreeBSD-src-7f71a1a09199f766bb8569761d4cb15d13abdc22.zip FreeBSD-src-7f71a1a09199f766bb8569761d4cb15d13abdc22.tar.gz |
fix races in the uidinfo subsystem, several problems existed:
1) while allocating a uidinfo struct malloc is called with M_WAITOK,
it's possible that while asleep another process by the same user
could have woken up earlier and inserted an entry into the uid
hash table. Having redundant entries causes inconsistancies that
we can't handle.
fix: do a non-waiting malloc, and if that fails then do a blocking
malloc, after waking up check that no one else has inserted an entry
for us already.
2) Because many checks for sbsize were done as "test then set" in a non
atomic manner it was possible to exceed the limits put up via races.
fix: instead of querying the count then setting, we just attempt to
set the count and leave it up to the function to return success or
failure.
3) The uidinfo code was inlining and repeating, lookups and insertions
and deletions needed to be in their own functions for clarity.
Reviewed by: green
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r-- | sys/kern/uipc_socket.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index c2d0ad7..4dffd3a 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -191,10 +191,10 @@ sodealloc(so) so->so_gencnt = ++so_gencnt; if (so->so_rcv.sb_hiwat) (void)chgsbsize(so->so_cred->cr_uid, - -(rlim_t)so->so_rcv.sb_hiwat); + -(rlim_t)so->so_rcv.sb_hiwat, RLIM_INFINITY); if (so->so_snd.sb_hiwat) (void)chgsbsize(so->so_cred->cr_uid, - -(rlim_t)so->so_snd.sb_hiwat); + -(rlim_t)so->so_snd.sb_hiwat, RLIM_INFINITY); if (so->so_accf != NULL) { if (so->so_accf->so_accept_filter != NULL && so->so_accf->so_accept_filter->accf_destroy != NULL) { |