Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
The bpf syscall and selftests conflicts were trivial overlapping changes. The r8169 change involved moving the added mdelay from 'net' into a different function. A TLS close bug fix overlapped with the splitting of the TLS state into separate TX and RX parts. I just expanded the tests in the bug fix from "ctx->conf == X" into "ctx->tx_conf == X && ctx->rx_conf == X". Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -986,8 +986,9 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
|
||||
struct sctp_endpoint *ep;
|
||||
struct sctp_chunk *chunk;
|
||||
struct sctp_inq *inqueue;
|
||||
int state;
|
||||
int first_time = 1; /* is this the first time through the loop */
|
||||
int error = 0;
|
||||
int state;
|
||||
|
||||
/* The association should be held so we should be safe. */
|
||||
ep = asoc->ep;
|
||||
@@ -998,6 +999,30 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
|
||||
state = asoc->state;
|
||||
subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
|
||||
|
||||
/* If the first chunk in the packet is AUTH, do special
|
||||
* processing specified in Section 6.3 of SCTP-AUTH spec
|
||||
*/
|
||||
if (first_time && subtype.chunk == SCTP_CID_AUTH) {
|
||||
struct sctp_chunkhdr *next_hdr;
|
||||
|
||||
next_hdr = sctp_inq_peek(inqueue);
|
||||
if (!next_hdr)
|
||||
goto normal;
|
||||
|
||||
/* If the next chunk is COOKIE-ECHO, skip the AUTH
|
||||
* chunk while saving a pointer to it so we can do
|
||||
* Authentication later (during cookie-echo
|
||||
* processing).
|
||||
*/
|
||||
if (next_hdr->type == SCTP_CID_COOKIE_ECHO) {
|
||||
chunk->auth_chunk = skb_clone(chunk->skb,
|
||||
GFP_ATOMIC);
|
||||
chunk->auth = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
normal:
|
||||
/* SCTP-AUTH, Section 6.3:
|
||||
* The receiver has a list of chunk types which it expects
|
||||
* to be received only after an AUTH-chunk. This list has
|
||||
@@ -1036,6 +1061,9 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
|
||||
/* If there is an error on chunk, discard this packet. */
|
||||
if (error && chunk)
|
||||
chunk->pdiscard = 1;
|
||||
|
||||
if (first_time)
|
||||
first_time = 0;
|
||||
}
|
||||
sctp_association_put(asoc);
|
||||
}
|
||||
|
@@ -1131,7 +1131,7 @@ struct sctp_chunk *sctp_make_violation_max_retrans(
|
||||
const struct sctp_association *asoc,
|
||||
const struct sctp_chunk *chunk)
|
||||
{
|
||||
static const char error[] = "Association exceeded its max_retans count";
|
||||
static const char error[] = "Association exceeded its max_retrans count";
|
||||
size_t payload_len = sizeof(error) + sizeof(struct sctp_errhdr);
|
||||
struct sctp_chunk *retval;
|
||||
|
||||
|
@@ -153,10 +153,7 @@ static enum sctp_disposition sctp_sf_violation_chunk(
|
||||
struct sctp_cmd_seq *commands);
|
||||
|
||||
static enum sctp_ierror sctp_sf_authenticate(
|
||||
struct net *net,
|
||||
const struct sctp_endpoint *ep,
|
||||
const struct sctp_association *asoc,
|
||||
const union sctp_subtype type,
|
||||
struct sctp_chunk *chunk);
|
||||
|
||||
static enum sctp_disposition __sctp_sf_do_9_1_abort(
|
||||
@@ -626,6 +623,38 @@ enum sctp_disposition sctp_sf_do_5_1C_ack(struct net *net,
|
||||
return SCTP_DISPOSITION_CONSUME;
|
||||
}
|
||||
|
||||
static bool sctp_auth_chunk_verify(struct net *net, struct sctp_chunk *chunk,
|
||||
const struct sctp_association *asoc)
|
||||
{
|
||||
struct sctp_chunk auth;
|
||||
|
||||
if (!chunk->auth_chunk)
|
||||
return true;
|
||||
|
||||
/* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo
|
||||
* is supposed to be authenticated and we have to do delayed
|
||||
* authentication. We've just recreated the association using
|
||||
* the information in the cookie and now it's much easier to
|
||||
* do the authentication.
|
||||
*/
|
||||
|
||||
/* Make sure that we and the peer are AUTH capable */
|
||||
if (!net->sctp.auth_enable || !asoc->peer.auth_capable)
|
||||
return false;
|
||||
|
||||
/* set-up our fake chunk so that we can process it */
|
||||
auth.skb = chunk->auth_chunk;
|
||||
auth.asoc = chunk->asoc;
|
||||
auth.sctp_hdr = chunk->sctp_hdr;
|
||||
auth.chunk_hdr = (struct sctp_chunkhdr *)
|
||||
skb_push(chunk->auth_chunk,
|
||||
sizeof(struct sctp_chunkhdr));
|
||||
skb_pull(chunk->auth_chunk, sizeof(struct sctp_chunkhdr));
|
||||
auth.transport = chunk->transport;
|
||||
|
||||
return sctp_sf_authenticate(asoc, &auth) == SCTP_IERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Respond to a normal COOKIE ECHO chunk.
|
||||
* We are the side that is being asked for an association.
|
||||
@@ -763,37 +792,9 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
|
||||
if (error)
|
||||
goto nomem_init;
|
||||
|
||||
/* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo
|
||||
* is supposed to be authenticated and we have to do delayed
|
||||
* authentication. We've just recreated the association using
|
||||
* the information in the cookie and now it's much easier to
|
||||
* do the authentication.
|
||||
*/
|
||||
if (chunk->auth_chunk) {
|
||||
struct sctp_chunk auth;
|
||||
enum sctp_ierror ret;
|
||||
|
||||
/* Make sure that we and the peer are AUTH capable */
|
||||
if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) {
|
||||
sctp_association_free(new_asoc);
|
||||
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
|
||||
}
|
||||
|
||||
/* set-up our fake chunk so that we can process it */
|
||||
auth.skb = chunk->auth_chunk;
|
||||
auth.asoc = chunk->asoc;
|
||||
auth.sctp_hdr = chunk->sctp_hdr;
|
||||
auth.chunk_hdr = (struct sctp_chunkhdr *)
|
||||
skb_push(chunk->auth_chunk,
|
||||
sizeof(struct sctp_chunkhdr));
|
||||
skb_pull(chunk->auth_chunk, sizeof(struct sctp_chunkhdr));
|
||||
auth.transport = chunk->transport;
|
||||
|
||||
ret = sctp_sf_authenticate(net, ep, new_asoc, type, &auth);
|
||||
if (ret != SCTP_IERROR_NO_ERROR) {
|
||||
sctp_association_free(new_asoc);
|
||||
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
|
||||
}
|
||||
if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) {
|
||||
sctp_association_free(new_asoc);
|
||||
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
|
||||
}
|
||||
|
||||
repl = sctp_make_cookie_ack(new_asoc, chunk);
|
||||
@@ -1797,13 +1798,15 @@ static enum sctp_disposition sctp_sf_do_dupcook_a(
|
||||
if (sctp_auth_asoc_init_active_key(new_asoc, GFP_ATOMIC))
|
||||
goto nomem;
|
||||
|
||||
if (!sctp_auth_chunk_verify(net, chunk, new_asoc))
|
||||
return SCTP_DISPOSITION_DISCARD;
|
||||
|
||||
/* Make sure no new addresses are being added during the
|
||||
* restart. Though this is a pretty complicated attack
|
||||
* since you'd have to get inside the cookie.
|
||||
*/
|
||||
if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands)) {
|
||||
if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands))
|
||||
return SCTP_DISPOSITION_CONSUME;
|
||||
}
|
||||
|
||||
/* If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes
|
||||
* the peer has restarted (Action A), it MUST NOT setup a new
|
||||
@@ -1912,6 +1915,9 @@ static enum sctp_disposition sctp_sf_do_dupcook_b(
|
||||
if (sctp_auth_asoc_init_active_key(new_asoc, GFP_ATOMIC))
|
||||
goto nomem;
|
||||
|
||||
if (!sctp_auth_chunk_verify(net, chunk, new_asoc))
|
||||
return SCTP_DISPOSITION_DISCARD;
|
||||
|
||||
/* Update the content of current association. */
|
||||
sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
|
||||
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
||||
@@ -2009,6 +2015,9 @@ static enum sctp_disposition sctp_sf_do_dupcook_d(
|
||||
* a COOKIE ACK.
|
||||
*/
|
||||
|
||||
if (!sctp_auth_chunk_verify(net, chunk, asoc))
|
||||
return SCTP_DISPOSITION_DISCARD;
|
||||
|
||||
/* Don't accidentally move back into established state. */
|
||||
if (asoc->state < SCTP_STATE_ESTABLISHED) {
|
||||
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
||||
@@ -4171,10 +4180,7 @@ gen_shutdown:
|
||||
* The return value is the disposition of the chunk.
|
||||
*/
|
||||
static enum sctp_ierror sctp_sf_authenticate(
|
||||
struct net *net,
|
||||
const struct sctp_endpoint *ep,
|
||||
const struct sctp_association *asoc,
|
||||
const union sctp_subtype type,
|
||||
struct sctp_chunk *chunk)
|
||||
{
|
||||
struct sctp_shared_key *sh_key = NULL;
|
||||
@@ -4275,7 +4281,7 @@ enum sctp_disposition sctp_sf_eat_auth(struct net *net,
|
||||
commands);
|
||||
|
||||
auth_hdr = (struct sctp_authhdr *)chunk->skb->data;
|
||||
error = sctp_sf_authenticate(net, ep, asoc, type, chunk);
|
||||
error = sctp_sf_authenticate(asoc, chunk);
|
||||
switch (error) {
|
||||
case SCTP_IERROR_AUTH_BAD_HMAC:
|
||||
/* Generate the ERROR chunk and discard the rest
|
||||
|
@@ -715,7 +715,6 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
|
||||
return event;
|
||||
|
||||
fail_mark:
|
||||
sctp_chunk_put(chunk);
|
||||
kfree_skb(skb);
|
||||
fail:
|
||||
return NULL;
|
||||
|
Reference in New Issue
Block a user