summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2010-01-17 19:47:59 +0000
committerrrs <rrs@FreeBSD.org>2010-01-17 19:47:59 +0000
commite0b03cdcce8c6f73185aabff2687bd9540f20989 (patch)
tree540690d5fecff3032c6c80c5f07d59105d79261a /sys/netinet
parent8ec113acf70c73e9fa54d44332162294213d3ccd (diff)
downloadFreeBSD-src-e0b03cdcce8c6f73185aabff2687bd9540f20989.zip
FreeBSD-src-e0b03cdcce8c6f73185aabff2687bd9540f20989.tar.gz
Bug fix: If the allocation of a socket failed and we
freed the inpcb, it was possible to not set the proper flags on the pcb (i.e. the socket is not there). This is HIGHLY unlikely since no one else should be able to find the socket.. but for consistency we do the proper loop thing to make sure that we mark the socket as gone on the PCB.
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/sctp_usrreq.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 676e575..71f5f65 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -551,6 +551,7 @@ sctp_attach(struct socket *so, int proto, struct thread *p)
sctp_log_closing(inp, NULL, 17);
#endif
if (error != 0) {
+try_again:
flags = inp->sctp_flags;
if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
@@ -561,7 +562,12 @@ sctp_attach(struct socket *so, int proto, struct thread *p)
sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
} else {
- SCTP_INP_WUNLOCK(inp);
+ flags = inp->sctp_flags;
+ if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
+ goto try_again;
+ } else {
+ SCTP_INP_WUNLOCK(inp);
+ }
}
return error;
}
OpenPOWER on IntegriCloud