mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git
synced 2025-09-30 18:54:15 +10:00
rxrpc: Fix to use conn aborts for conn-wide failures
Fix rxrpc to use connection-level aborts for things that affect the whole
connection, such as the service ID not matching a local service.
Fixes: 57af281e53
("rxrpc: Tidy up abort generation infrastructure")
Reported-by: Jeffrey Altman <jaltman@auristor.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20250717074350.3767366-6-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
e9c0b96ec0
commit
f0295678ad
@ -44,6 +44,7 @@ enum rxrpc_skb_mark {
|
|||||||
RXRPC_SKB_MARK_SERVICE_CONN_SECURED, /* Service connection response has been verified */
|
RXRPC_SKB_MARK_SERVICE_CONN_SECURED, /* Service connection response has been verified */
|
||||||
RXRPC_SKB_MARK_REJECT_BUSY, /* Reject with BUSY */
|
RXRPC_SKB_MARK_REJECT_BUSY, /* Reject with BUSY */
|
||||||
RXRPC_SKB_MARK_REJECT_ABORT, /* Reject with ABORT (code in skb->priority) */
|
RXRPC_SKB_MARK_REJECT_ABORT, /* Reject with ABORT (code in skb->priority) */
|
||||||
|
RXRPC_SKB_MARK_REJECT_CONN_ABORT, /* Reject with connection ABORT (code in skb->priority) */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1253,6 +1254,8 @@ int rxrpc_encap_rcv(struct sock *, struct sk_buff *);
|
|||||||
void rxrpc_error_report(struct sock *);
|
void rxrpc_error_report(struct sock *);
|
||||||
bool rxrpc_direct_abort(struct sk_buff *skb, enum rxrpc_abort_reason why,
|
bool rxrpc_direct_abort(struct sk_buff *skb, enum rxrpc_abort_reason why,
|
||||||
s32 abort_code, int err);
|
s32 abort_code, int err);
|
||||||
|
bool rxrpc_direct_conn_abort(struct sk_buff *skb, enum rxrpc_abort_reason why,
|
||||||
|
s32 abort_code, int err);
|
||||||
int rxrpc_io_thread(void *data);
|
int rxrpc_io_thread(void *data);
|
||||||
void rxrpc_post_response(struct rxrpc_connection *conn, struct sk_buff *skb);
|
void rxrpc_post_response(struct rxrpc_connection *conn, struct sk_buff *skb);
|
||||||
static inline void rxrpc_wake_up_io_thread(struct rxrpc_local *local)
|
static inline void rxrpc_wake_up_io_thread(struct rxrpc_local *local)
|
||||||
|
@ -374,8 +374,8 @@ bool rxrpc_new_incoming_call(struct rxrpc_local *local,
|
|||||||
spin_lock(&rx->incoming_lock);
|
spin_lock(&rx->incoming_lock);
|
||||||
if (rx->sk.sk_state == RXRPC_SERVER_LISTEN_DISABLED ||
|
if (rx->sk.sk_state == RXRPC_SERVER_LISTEN_DISABLED ||
|
||||||
rx->sk.sk_state == RXRPC_CLOSE) {
|
rx->sk.sk_state == RXRPC_CLOSE) {
|
||||||
rxrpc_direct_abort(skb, rxrpc_abort_shut_down,
|
rxrpc_direct_conn_abort(skb, rxrpc_abort_shut_down,
|
||||||
RX_INVALID_OPERATION, -ESHUTDOWN);
|
RX_INVALID_OPERATION, -ESHUTDOWN);
|
||||||
goto no_call;
|
goto no_call;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,12 +422,12 @@ bool rxrpc_new_incoming_call(struct rxrpc_local *local,
|
|||||||
|
|
||||||
unsupported_service:
|
unsupported_service:
|
||||||
read_unlock_irq(&local->services_lock);
|
read_unlock_irq(&local->services_lock);
|
||||||
return rxrpc_direct_abort(skb, rxrpc_abort_service_not_offered,
|
return rxrpc_direct_conn_abort(skb, rxrpc_abort_service_not_offered,
|
||||||
RX_INVALID_OPERATION, -EOPNOTSUPP);
|
RX_INVALID_OPERATION, -EOPNOTSUPP);
|
||||||
unsupported_security:
|
unsupported_security:
|
||||||
read_unlock_irq(&local->services_lock);
|
read_unlock_irq(&local->services_lock);
|
||||||
return rxrpc_direct_abort(skb, rxrpc_abort_service_not_offered,
|
return rxrpc_direct_conn_abort(skb, rxrpc_abort_service_not_offered,
|
||||||
RX_INVALID_OPERATION, -EKEYREJECTED);
|
RX_INVALID_OPERATION, -EKEYREJECTED);
|
||||||
no_call:
|
no_call:
|
||||||
spin_unlock(&rx->incoming_lock);
|
spin_unlock(&rx->incoming_lock);
|
||||||
read_unlock_irq(&local->services_lock);
|
read_unlock_irq(&local->services_lock);
|
||||||
|
@ -97,6 +97,20 @@ bool rxrpc_direct_abort(struct sk_buff *skb, enum rxrpc_abort_reason why,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Directly produce a connection abort from a packet.
|
||||||
|
*/
|
||||||
|
bool rxrpc_direct_conn_abort(struct sk_buff *skb, enum rxrpc_abort_reason why,
|
||||||
|
s32 abort_code, int err)
|
||||||
|
{
|
||||||
|
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
|
||||||
|
|
||||||
|
trace_rxrpc_abort(0, why, sp->hdr.cid, 0, sp->hdr.seq, abort_code, err);
|
||||||
|
skb->mark = RXRPC_SKB_MARK_REJECT_CONN_ABORT;
|
||||||
|
skb->priority = abort_code;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool rxrpc_bad_message(struct sk_buff *skb, enum rxrpc_abort_reason why)
|
static bool rxrpc_bad_message(struct sk_buff *skb, enum rxrpc_abort_reason why)
|
||||||
{
|
{
|
||||||
return rxrpc_direct_abort(skb, why, RX_PROTOCOL_ERROR, -EBADMSG);
|
return rxrpc_direct_abort(skb, why, RX_PROTOCOL_ERROR, -EBADMSG);
|
||||||
|
@ -829,7 +829,13 @@ void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb)
|
|||||||
msg.msg_controllen = 0;
|
msg.msg_controllen = 0;
|
||||||
msg.msg_flags = 0;
|
msg.msg_flags = 0;
|
||||||
|
|
||||||
memset(&whdr, 0, sizeof(whdr));
|
whdr = (struct rxrpc_wire_header) {
|
||||||
|
.epoch = htonl(sp->hdr.epoch),
|
||||||
|
.cid = htonl(sp->hdr.cid),
|
||||||
|
.callNumber = htonl(sp->hdr.callNumber),
|
||||||
|
.serviceId = htons(sp->hdr.serviceId),
|
||||||
|
.flags = ~sp->hdr.flags & RXRPC_CLIENT_INITIATED,
|
||||||
|
};
|
||||||
|
|
||||||
switch (skb->mark) {
|
switch (skb->mark) {
|
||||||
case RXRPC_SKB_MARK_REJECT_BUSY:
|
case RXRPC_SKB_MARK_REJECT_BUSY:
|
||||||
@ -837,6 +843,9 @@ void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb)
|
|||||||
size = sizeof(whdr);
|
size = sizeof(whdr);
|
||||||
ioc = 1;
|
ioc = 1;
|
||||||
break;
|
break;
|
||||||
|
case RXRPC_SKB_MARK_REJECT_CONN_ABORT:
|
||||||
|
whdr.callNumber = 0;
|
||||||
|
fallthrough;
|
||||||
case RXRPC_SKB_MARK_REJECT_ABORT:
|
case RXRPC_SKB_MARK_REJECT_ABORT:
|
||||||
whdr.type = RXRPC_PACKET_TYPE_ABORT;
|
whdr.type = RXRPC_PACKET_TYPE_ABORT;
|
||||||
code = htonl(skb->priority);
|
code = htonl(skb->priority);
|
||||||
@ -850,14 +859,6 @@ void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb)
|
|||||||
if (rxrpc_extract_addr_from_skb(&srx, skb) == 0) {
|
if (rxrpc_extract_addr_from_skb(&srx, skb) == 0) {
|
||||||
msg.msg_namelen = srx.transport_len;
|
msg.msg_namelen = srx.transport_len;
|
||||||
|
|
||||||
whdr.epoch = htonl(sp->hdr.epoch);
|
|
||||||
whdr.cid = htonl(sp->hdr.cid);
|
|
||||||
whdr.callNumber = htonl(sp->hdr.callNumber);
|
|
||||||
whdr.serviceId = htons(sp->hdr.serviceId);
|
|
||||||
whdr.flags = sp->hdr.flags;
|
|
||||||
whdr.flags ^= RXRPC_CLIENT_INITIATED;
|
|
||||||
whdr.flags &= RXRPC_CLIENT_INITIATED;
|
|
||||||
|
|
||||||
iov_iter_kvec(&msg.msg_iter, WRITE, iov, ioc, size);
|
iov_iter_kvec(&msg.msg_iter, WRITE, iov, ioc, size);
|
||||||
ret = do_udp_sendmsg(local->socket, &msg, size);
|
ret = do_udp_sendmsg(local->socket, &msg, size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -140,15 +140,15 @@ const struct rxrpc_security *rxrpc_get_incoming_security(struct rxrpc_sock *rx,
|
|||||||
|
|
||||||
sec = rxrpc_security_lookup(sp->hdr.securityIndex);
|
sec = rxrpc_security_lookup(sp->hdr.securityIndex);
|
||||||
if (!sec) {
|
if (!sec) {
|
||||||
rxrpc_direct_abort(skb, rxrpc_abort_unsupported_security,
|
rxrpc_direct_conn_abort(skb, rxrpc_abort_unsupported_security,
|
||||||
RX_INVALID_OPERATION, -EKEYREJECTED);
|
RX_INVALID_OPERATION, -EKEYREJECTED);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sp->hdr.securityIndex != RXRPC_SECURITY_NONE &&
|
if (sp->hdr.securityIndex != RXRPC_SECURITY_NONE &&
|
||||||
!rx->securities) {
|
!rx->securities) {
|
||||||
rxrpc_direct_abort(skb, rxrpc_abort_no_service_key,
|
rxrpc_direct_conn_abort(skb, rxrpc_abort_no_service_key,
|
||||||
sec->no_key_abort, -EKEYREJECTED);
|
sec->no_key_abort, -EKEYREJECTED);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user