Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sctp: allow authenticating DATA chunks that are bundled with COOKIE_ECHO

Currently, we can ask to authenticate DATA chunks and we can send DATA
chunks on the same packet as COOKIE_ECHO, but if you try to combine
both, the DATA chunk will be sent unauthenticated and peer won't accept
it, leading to a communication failure.

This happens because even though the data was queued after it was
requested to authenticate DATA chunks, it was also queued before we
could know that remote peer can handle authenticating, so
sctp_auth_send_cid() returns false.

The fix is whenever we set up an active key, re-check send queue for
chunks that now should be authenticated. As a result, such packet will
now contain COOKIE_ECHO + AUTH + DATA chunks, in that order.

Reported-by: Liu Wei <weliu@redhat.com>
Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Acked-by: Vlad Yasevich <vyasevich@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Marcelo Ricardo Leitner and committed by
David S. Miller
ae36806a fb05e7a8

+10 -1
+10 -1
net/sctp/auth.c
··· 381 381 } 382 382 383 383 384 - /* Public interface to creat the association shared key. 384 + /* Public interface to create the association shared key. 385 385 * See code above for the algorithm. 386 386 */ 387 387 int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp) 388 388 { 389 389 struct sctp_auth_bytes *secret; 390 390 struct sctp_shared_key *ep_key; 391 + struct sctp_chunk *chunk; 391 392 392 393 /* If we don't support AUTH, or peer is not capable 393 394 * we don't need to do anything. ··· 410 409 411 410 sctp_auth_key_put(asoc->asoc_shared_key); 412 411 asoc->asoc_shared_key = secret; 412 + 413 + /* Update send queue in case any chunk already in there now 414 + * needs authenticating 415 + */ 416 + list_for_each_entry(chunk, &asoc->outqueue.out_chunk_list, list) { 417 + if (sctp_auth_send_cid(chunk->chunk_hdr->type, asoc)) 418 + chunk->auth = 1; 419 + } 413 420 414 421 return 0; 415 422 }