Commit 5800b1cf authored by David Howells's avatar David Howells Committed by Jakub Kicinski
Browse files

rxrpc: Allow CHALLENGEs to the passed to the app for a RESPONSE



Allow the app to request that CHALLENGEs be passed to it through an
out-of-band queue that allows recvmsg() to pick it up so that the app can
add data to it with sendmsg().

This will allow the application (AFS or userspace) to interact with the
process if it wants to and put values into user-defined fields.  This will
be used by AFS when talking to a fileserver to supply that fileserver with
a crypto key by which callback RPCs can be encrypted (ie. notifications
from the fileserver to the client).

Signed-off-by: default avatarDavid Howells <dhowells@redhat.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/20250411095303.2316168-5-dhowells@redhat.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 019c8433
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1179,7 +1179,9 @@ API Function Reference

.. kernel-doc:: net/rxrpc/af_rxrpc.c
.. kernel-doc:: net/rxrpc/key.c
.. kernel-doc:: net/rxrpc/oob.c
.. kernel-doc:: net/rxrpc/peer_object.c
.. kernel-doc:: net/rxrpc/recvmsg.c
.. kernel-doc:: net/rxrpc/rxkad.c
.. kernel-doc:: net/rxrpc/sendmsg.c
.. kernel-doc:: net/rxrpc/server_key.c
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ kafs-y := \
	addr_prefs.o \
	callback.o \
	cell.o \
	cm_security.o \
	cmservice.o \
	dir.o \
	dir_edit.o \

fs/afs/cm_security.c

0 → 100644
+73 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-or-later
/* Cache manager security.
 *
 * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#include <linux/slab.h>
#include "internal.h"
#include "afs_fs.h"
#include "protocol_yfs.h"
#define RXRPC_TRACE_ONLY_DEFINE_ENUMS
#include <trace/events/rxrpc.h>

/*
 * Respond to an RxGK challenge, adding appdata.
 */
static int afs_respond_to_challenge(struct sk_buff *challenge)
{
	struct rxrpc_peer *peer;
	unsigned long peer_data;
	u16 service_id;
	u8 security_index;

	rxrpc_kernel_query_challenge(challenge, &peer, &peer_data,
				     &service_id, &security_index);

	_enter("%u,%u", service_id, security_index);

	switch (service_id) {
		/* We don't send CM_SERVICE RPCs, so don't expect a challenge
		 * therefrom.
		 */
	case FS_SERVICE:
	case VL_SERVICE:
	case YFS_FS_SERVICE:
	case YFS_VL_SERVICE:
		break;
	default:
		pr_warn("Can't respond to unknown challenge %u:%u",
			service_id, security_index);
		return rxrpc_kernel_reject_challenge(challenge, RX_USER_ABORT, -EPROTO,
						     afs_abort_unsupported_sec_class);
	}

	switch (security_index) {
	case RXRPC_SECURITY_RXKAD:
		return rxkad_kernel_respond_to_challenge(challenge);

	default:
		return rxrpc_kernel_reject_challenge(challenge, RX_USER_ABORT, -EPROTO,
						     afs_abort_unsupported_sec_class);
	}
}

/*
 * Process the OOB message queue, processing challenge packets.
 */
void afs_process_oob_queue(struct work_struct *work)
{
	struct afs_net *net = container_of(work, struct afs_net, rx_oob_work);
	struct sk_buff *oob;
	enum rxrpc_oob_type type;

	while ((oob = rxrpc_kernel_dequeue_oob(net->socket, &type))) {
		switch (type) {
		case RXRPC_OOB_CHALLENGE:
			afs_respond_to_challenge(oob);
			break;
		}
		rxrpc_kernel_free_oob(oob);
	}
}
+6 −0
Original line number Diff line number Diff line
@@ -281,6 +281,7 @@ struct afs_net {
	struct socket		*socket;
	struct afs_call		*spare_incoming_call;
	struct work_struct	charge_preallocation_work;
	struct work_struct	rx_oob_work;
	struct mutex		socket_mutex;
	atomic_t		nr_outstanding_calls;
	atomic_t		nr_superblocks;
@@ -1058,6 +1059,11 @@ extern void __net_exit afs_cell_purge(struct afs_net *);
 */
extern bool afs_cm_incoming_call(struct afs_call *);

/*
 * cm_security.c
 */
void afs_process_oob_queue(struct work_struct *work);

/*
 * dir.c
 */
+1 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ static int __net_init afs_net_init(struct net *net_ns)
	generate_random_uuid((unsigned char *)&net->uuid);

	INIT_WORK(&net->charge_preallocation_work, afs_charge_preallocation);
	INIT_WORK(&net->rx_oob_work, afs_process_oob_queue);
	mutex_init(&net->socket_mutex);

	net->cells = RB_ROOT;
Loading