{"push_id":1212517788,"size":1,"distinct_size":1,"ref":"refs/heads/6.0.1","head":"21d1296f50cb817110dc0fb99d3447f5367ba672","before":"d04ffcfa65b5a25914387287f6d790e534b512d5","commits":[{"sha":"21d1296f50cb817110dc0fb99d3447f5367ba672","author":{"name":"Daniel Borkmann","email":"9e2dfb17275f5090f9361bcf2ab5dba6b506e7e6@redhat.com"},"message":"net: sctp: test if association is dead in sctp_wake_up_waiters\n\n[ Upstream commit 1e1cdf8ac78793e0875465e98a648df64694a8d0 ]\n\nIn function sctp_wake_up_waiters(), we need to involve a test\nif the association is declared dead. If so, we don't have any\nreference to a possible sibling association anymore and need\nto invoke sctp_write_space() instead, and normally walk the\nsocket's associations and notify them of new wmem space. The\nreason for special casing is that otherwise, we could run\ninto the following issue when a sctp_primitive_SEND() call\nfrom sctp_sendmsg() fails, and tries to flush an association's\noutq, i.e. in the following way:\n\nsctp_association_free()\n`-> list_del(&asoc->asocs)         <-- poisons list pointer\n    asoc->base.dead = true\n    sctp_outq_free(&asoc->outqueue)\n    `-> __sctp_outq_teardown()\n     `-> sctp_chunk_free()\n      `-> consume_skb()\n       `-> sctp_wfree()\n        `-> sctp_wake_up_waiters() <-- dereferences poisoned pointers\n                                       if asoc->ep->sndbuf_policy=0\n\nTherefore, only walk the list in an 'optimized' way if we find\nthat the current association is still active. We could also use\nlist_del_init() in addition when we call sctp_association_free(),\nbut as Vlad suggests, we want to trap such bugs and thus leave\nit poisoned as is.\n\nWhy is it safe to resolve the issue by testing for asoc->base.dead?\nParallel calls to sctp_sendmsg() are protected under socket lock,\nthat is lock_sock()/release_sock(). Only within that path under\nlock held, we're setting skb/chunk owner via sctp_set_owner_w().\nEventually, chunks are freed directly by an association still\nunder that lock. So when traversing association list on destruction\ntime from sctp_wake_up_waiters() via sctp_wfree(), a different\nCPU can't be running sctp_wfree() while another one calls\nsctp_association_free() as both happens under the same lock.\nTherefore, this can also not race with setting/testing against\nasoc->base.dead as we are guaranteed for this to happen in order,\nunder lock. Further, Vlad says: the times we check asoc->base.dead\nis when we've cached an association pointer for later processing.\nIn between cache and processing, the association may have been\nfreed and is simply still around due to reference counts. We check\nasoc->base.dead under a lock, so it should always be safe to check\nand not race against sctp_association_free(). Stress-testing seems\nfine now, too.\n\nFixes: cd253f9f357d (\"net: sctp: wake up all assocs if sndbuf policy is per socket\")\nSigned-off-by: Daniel Borkmann <dborkman@redhat.com>\nCc: Vlad Yasevich <vyasevic@redhat.com>\nAcked-by: Neil Horman <nhorman@tuxdriver.com>\nAcked-by: Vlad Yasevich <vyasevic@redhat.com>\nSigned-off-by: David S. Miller <davem@davemloft.net>\nSigned-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>","distinct":true,"url":"https://api.github.com/repos/dblockopp/G3_CooCoo_Kernel/commits/21d1296f50cb817110dc0fb99d3447f5367ba672"}]}
{"actor":{"display_login":"dblockopp"}}