Skip to content

Commit 3a0504d

Browse files
WOnder93kuba-moo
authored andcommitted
sctp: fix association labeling in the duplicate COOKIE-ECHO case
sctp_sf_do_5_2_4_dupcook() currently calls security_sctp_assoc_request() on new_asoc, but as it turns out, this association is always discarded and the LSM labels never get into the final association (asoc). This can be reproduced by having two SCTP endpoints try to initiate an association with each other at approximately the same time and then peel off the association into a new socket, which exposes the unitialized labels and triggers SELinux denials. Fix it by calling security_sctp_assoc_request() on asoc instead of new_asoc. Xin Long also suggested limit calling the hook only to cases A, B, and D, since in cases C and E the COOKIE ECHO chunk is discarded and the association doesn't enter the ESTABLISHED state, so rectify that as well. One related caveat with SELinux and peer labeling: When an SCTP connection is set up simultaneously in this way, we will end up with an association that is initialized with security_sctp_assoc_request() on both sides, so the MLS component of the security context of the association will get swapped between the peers, instead of just one side setting it to the other's MLS component. However, at that point security_sctp_assoc_request() had already been called on both sides in sctp_sf_do_unexpected_init() (on a temporary association) and thus if the exchange didn't fail before due to MLS, it won't fail now either (most likely both endpoints have the same MLS range). Tested by: - reproducer from https://src.fedoraproject.org/tests/selinux/pull-request/530 - selinux-testsuite (https://github.com/SELinuxProject/selinux-testsuite/) - sctp-tests (https://github.com/sctp/sctp-tests) - no tests failed that wouldn't fail also without the patch applied Fixes: c081d53 ("security: pass asoc to sctp_assoc_request and sctp_sk_clone") Suggested-by: Xin Long <[email protected]> Signed-off-by: Ondrej Mosnacek <[email protected]> Acked-by: Xin Long <[email protected]> Acked-by: Paul Moore <[email protected]> (LSM/SELinux) Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 237c385 commit 3a0504d

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

net/sctp/sm_statefuns.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2260,12 +2260,6 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
22602260
}
22612261
}
22622262

2263-
/* Update socket peer label if first association. */
2264-
if (security_sctp_assoc_request(new_asoc, chunk->head_skb ?: chunk->skb)) {
2265-
sctp_association_free(new_asoc);
2266-
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
2267-
}
2268-
22692263
/* Set temp so that it won't be added into hashtable */
22702264
new_asoc->temp = 1;
22712265

@@ -2274,6 +2268,22 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
22742268
*/
22752269
action = sctp_tietags_compare(new_asoc, asoc);
22762270

2271+
/* In cases C and E the association doesn't enter the ESTABLISHED
2272+
* state, so there is no need to call security_sctp_assoc_request().
2273+
*/
2274+
switch (action) {
2275+
case 'A': /* Association restart. */
2276+
case 'B': /* Collision case B. */
2277+
case 'D': /* Collision case D. */
2278+
/* Update socket peer label if first association. */
2279+
if (security_sctp_assoc_request((struct sctp_association *)asoc,
2280+
chunk->head_skb ?: chunk->skb)) {
2281+
sctp_association_free(new_asoc);
2282+
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
2283+
}
2284+
break;
2285+
}
2286+
22772287
switch (action) {
22782288
case 'A': /* Association restart. */
22792289
retval = sctp_sf_do_dupcook_a(net, ep, asoc, chunk, commands,

0 commit comments

Comments
 (0)