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.

Merge branch 'rxrpc-afs-add-afs-gssapi-security-class-to-af_rxrpc-and-kafs'

David Howells says:

====================
rxrpc, afs: Add AFS GSSAPI security class to AF_RXRPC and kafs

Here's a set of patches to add basic support for the AFS GSSAPI security
class to AF_RXRPC and kafs. It provides transport security for keys that
match the security index 6 (YFS) for connections to the AFS fileserver and
VL server.

Note that security index 4 (OpenAFS) can also be supported using this, but
it needs more work as it's slightly different.

The patches also provide the ability to secure the callback channel -
connections from the fileserver back to the client that are used to pass
file change notifications, amongst other things. When challenged by the
fileserver, kafs will generate a token specific to that server and include
it in the RESPONSE packet as the appdata. The server then extracts this
and uses it to send callback RPC calls back to the client.

It can also be used to provide transport security on the callback channel,
but a further set of patches is required to provide the token and key to
set that up when the client responds to the fileserver's challenge.

This makes use of the previously added crypto-krb5 library that is now
upstream (last commit fc0cf10c04f4).

This series of patches consist of the following parts:

(0) Update kdoc comments to remove some kdoc builder warnings.

(1) Push reponding to CHALLENGE packets over to recvmsg() or the kernel
equivalent so that the application layer can include user-defined
information in the RESPONSE packet. In a follow-up patch set, this
will allow the callback channel to be secured by the AFS filesystem.

(2) Add the AF_RXRPC RxGK security class that uses a key obtained from the
AFS GSS security service to do Kerberos 5-based encryption instead of
pcbc(fcrypt) and pcbc(des).

(3) Add support for callback channel encryption in kafs.

(4) Provide the test rxperf server module with some fixed krb5 keys.
====================

Link: https://patch.msgid.link/20250411095303.2316168-1-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+4276 -249
+15
Documentation/networking/rxrpc.rst
··· 1172 1172 header plus exactly 1412 bytes of data. The terminal packet must contain 1173 1173 a four byte header plus any amount of data. In any event, a jumbo packet 1174 1174 may not exceed rxrpc_rx_mtu in size. 1175 + 1176 + 1177 + API Function Reference 1178 + ====================== 1179 + 1180 + .. kernel-doc:: net/rxrpc/af_rxrpc.c 1181 + .. kernel-doc:: net/rxrpc/call_object.c 1182 + .. kernel-doc:: net/rxrpc/key.c 1183 + .. kernel-doc:: net/rxrpc/oob.c 1184 + .. kernel-doc:: net/rxrpc/peer_object.c 1185 + .. kernel-doc:: net/rxrpc/recvmsg.c 1186 + .. kernel-doc:: net/rxrpc/rxgk.c 1187 + .. kernel-doc:: net/rxrpc/rxkad.c 1188 + .. kernel-doc:: net/rxrpc/sendmsg.c 1189 + .. kernel-doc:: net/rxrpc/server_key.c
+1
fs/afs/Kconfig
··· 5 5 select AF_RXRPC 6 6 select DNS_RESOLVER 7 7 select NETFS_SUPPORT 8 + select CRYPTO_KRB5 8 9 help 9 10 If you say Y here, you will get an experimental Andrew File System 10 11 driver. It currently only supports unsecured read-only AFS access.
+1
fs/afs/Makefile
··· 8 8 addr_prefs.o \ 9 9 callback.o \ 10 10 cell.o \ 11 + cm_security.o \ 11 12 cmservice.o \ 12 13 dir.o \ 13 14 dir_edit.o \
+340
fs/afs/cm_security.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* Cache manager security. 3 + * 4 + * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved. 5 + * Written by David Howells (dhowells@redhat.com) 6 + */ 7 + 8 + #include <linux/slab.h> 9 + #include <crypto/krb5.h> 10 + #include "internal.h" 11 + #include "afs_cm.h" 12 + #include "afs_fs.h" 13 + #include "protocol_yfs.h" 14 + #define RXRPC_TRACE_ONLY_DEFINE_ENUMS 15 + #include <trace/events/rxrpc.h> 16 + 17 + #define RXGK_SERVER_ENC_TOKEN 1036U // 0x40c 18 + #define xdr_round_up(x) (round_up((x), sizeof(__be32))) 19 + #define xdr_len_object(x) (4 + round_up((x), sizeof(__be32))) 20 + 21 + #ifdef CONFIG_RXGK 22 + static int afs_create_yfs_cm_token(struct sk_buff *challenge, 23 + struct afs_server *server); 24 + #endif 25 + 26 + /* 27 + * Respond to an RxGK challenge, adding appdata. 28 + */ 29 + static int afs_respond_to_challenge(struct sk_buff *challenge) 30 + { 31 + #ifdef CONFIG_RXGK 32 + struct krb5_buffer appdata = {}; 33 + struct afs_server *server; 34 + #endif 35 + struct rxrpc_peer *peer; 36 + unsigned long peer_data; 37 + u16 service_id; 38 + u8 security_index; 39 + 40 + rxrpc_kernel_query_challenge(challenge, &peer, &peer_data, 41 + &service_id, &security_index); 42 + 43 + _enter("%u,%u", service_id, security_index); 44 + 45 + switch (service_id) { 46 + /* We don't send CM_SERVICE RPCs, so don't expect a challenge 47 + * therefrom. 48 + */ 49 + case FS_SERVICE: 50 + case VL_SERVICE: 51 + case YFS_FS_SERVICE: 52 + case YFS_VL_SERVICE: 53 + break; 54 + default: 55 + pr_warn("Can't respond to unknown challenge %u:%u", 56 + service_id, security_index); 57 + return rxrpc_kernel_reject_challenge(challenge, RX_USER_ABORT, -EPROTO, 58 + afs_abort_unsupported_sec_class); 59 + } 60 + 61 + switch (security_index) { 62 + #ifdef CONFIG_RXKAD 63 + case RXRPC_SECURITY_RXKAD: 64 + return rxkad_kernel_respond_to_challenge(challenge); 65 + #endif 66 + 67 + #ifdef CONFIG_RXGK 68 + case RXRPC_SECURITY_RXGK: 69 + return rxgk_kernel_respond_to_challenge(challenge, &appdata); 70 + 71 + case RXRPC_SECURITY_YFS_RXGK: 72 + switch (service_id) { 73 + case FS_SERVICE: 74 + case YFS_FS_SERVICE: 75 + server = (struct afs_server *)peer_data; 76 + if (!server->cm_rxgk_appdata.data) { 77 + mutex_lock(&server->cm_token_lock); 78 + if (!server->cm_rxgk_appdata.data) 79 + afs_create_yfs_cm_token(challenge, server); 80 + mutex_unlock(&server->cm_token_lock); 81 + } 82 + if (server->cm_rxgk_appdata.data) 83 + appdata = server->cm_rxgk_appdata; 84 + break; 85 + } 86 + return rxgk_kernel_respond_to_challenge(challenge, &appdata); 87 + #endif 88 + 89 + default: 90 + return rxrpc_kernel_reject_challenge(challenge, RX_USER_ABORT, -EPROTO, 91 + afs_abort_unsupported_sec_class); 92 + } 93 + } 94 + 95 + /* 96 + * Process the OOB message queue, processing challenge packets. 97 + */ 98 + void afs_process_oob_queue(struct work_struct *work) 99 + { 100 + struct afs_net *net = container_of(work, struct afs_net, rx_oob_work); 101 + struct sk_buff *oob; 102 + enum rxrpc_oob_type type; 103 + 104 + while ((oob = rxrpc_kernel_dequeue_oob(net->socket, &type))) { 105 + switch (type) { 106 + case RXRPC_OOB_CHALLENGE: 107 + afs_respond_to_challenge(oob); 108 + break; 109 + } 110 + rxrpc_kernel_free_oob(oob); 111 + } 112 + } 113 + 114 + #ifdef CONFIG_RXGK 115 + /* 116 + * Create a securities keyring for the cache manager and attach a key to it for 117 + * the RxGK tokens we want to use to secure the callback connection back from 118 + * the fileserver. 119 + */ 120 + int afs_create_token_key(struct afs_net *net, struct socket *socket) 121 + { 122 + const struct krb5_enctype *krb5; 123 + struct key *ring; 124 + key_ref_t key; 125 + char K0[32], *desc; 126 + int ret; 127 + 128 + ring = keyring_alloc("kafs", 129 + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(), 130 + KEY_POS_SEARCH | KEY_POS_WRITE | 131 + KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH, 132 + KEY_ALLOC_NOT_IN_QUOTA, 133 + NULL, NULL); 134 + if (IS_ERR(ring)) 135 + return PTR_ERR(ring); 136 + 137 + ret = rxrpc_sock_set_security_keyring(socket->sk, ring); 138 + if (ret < 0) 139 + goto out; 140 + 141 + ret = -ENOPKG; 142 + krb5 = crypto_krb5_find_enctype(KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96); 143 + if (!krb5) 144 + goto out; 145 + 146 + if (WARN_ON_ONCE(krb5->key_len > sizeof(K0))) 147 + goto out; 148 + 149 + ret = -ENOMEM; 150 + desc = kasprintf(GFP_KERNEL, "%u:%u:%u:%u", 151 + YFS_CM_SERVICE, RXRPC_SECURITY_YFS_RXGK, 1, krb5->etype); 152 + if (!desc) 153 + goto out; 154 + 155 + wait_for_random_bytes(); 156 + get_random_bytes(K0, krb5->key_len); 157 + 158 + key = key_create(make_key_ref(ring, true), 159 + "rxrpc_s", desc, 160 + K0, krb5->key_len, 161 + KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | KEY_USR_VIEW, 162 + KEY_ALLOC_NOT_IN_QUOTA); 163 + kfree(desc); 164 + if (IS_ERR(key)) { 165 + ret = PTR_ERR(key); 166 + goto out; 167 + } 168 + 169 + net->fs_cm_token_key = key_ref_to_ptr(key); 170 + ret = 0; 171 + out: 172 + key_put(ring); 173 + return ret; 174 + } 175 + 176 + /* 177 + * Create an YFS RxGK GSS token to use as a ticket to the specified fileserver. 178 + */ 179 + static int afs_create_yfs_cm_token(struct sk_buff *challenge, 180 + struct afs_server *server) 181 + { 182 + const struct krb5_enctype *conn_krb5, *token_krb5; 183 + const struct krb5_buffer *token_key; 184 + struct crypto_aead *aead; 185 + struct scatterlist sg; 186 + struct afs_net *net = server->cell->net; 187 + const struct key *key = net->fs_cm_token_key; 188 + size_t keysize, uuidsize, authsize, toksize, encsize, contsize, adatasize, offset; 189 + __be32 caps[1] = { 190 + [0] = htonl(AFS_CAP_ERROR_TRANSLATION), 191 + }; 192 + __be32 *xdr; 193 + void *appdata, *K0, *encbase; 194 + u32 enctype; 195 + int ret; 196 + 197 + if (!key) 198 + return -ENOKEY; 199 + 200 + /* Assume that the fileserver is happy to use the same encoding type as 201 + * we were told to use by the token obtained by the user. 202 + */ 203 + enctype = rxgk_kernel_query_challenge(challenge); 204 + 205 + conn_krb5 = crypto_krb5_find_enctype(enctype); 206 + if (!conn_krb5) 207 + return -ENOPKG; 208 + token_krb5 = key->payload.data[0]; 209 + token_key = (const struct krb5_buffer *)&key->payload.data[2]; 210 + 211 + /* struct rxgk_key { 212 + * afs_uint32 enctype; 213 + * opaque key<>; 214 + * }; 215 + */ 216 + keysize = 4 + xdr_len_object(conn_krb5->key_len); 217 + 218 + /* struct RXGK_AuthName { 219 + * afs_int32 kind; 220 + * opaque data<AUTHDATAMAX>; 221 + * opaque display<AUTHPRINTABLEMAX>; 222 + * }; 223 + */ 224 + uuidsize = sizeof(server->uuid); 225 + authsize = 4 + xdr_len_object(uuidsize) + xdr_len_object(0); 226 + 227 + /* struct RXGK_Token { 228 + * rxgk_key K0; 229 + * RXGK_Level level; 230 + * rxgkTime starttime; 231 + * afs_int32 lifetime; 232 + * afs_int32 bytelife; 233 + * rxgkTime expirationtime; 234 + * struct RXGK_AuthName identities<>; 235 + * }; 236 + */ 237 + toksize = keysize + 8 + 4 + 4 + 8 + xdr_len_object(authsize); 238 + 239 + offset = 0; 240 + encsize = crypto_krb5_how_much_buffer(token_krb5, KRB5_ENCRYPT_MODE, toksize, &offset); 241 + 242 + /* struct RXGK_TokenContainer { 243 + * afs_int32 kvno; 244 + * afs_int32 enctype; 245 + * opaque encrypted_token<>; 246 + * }; 247 + */ 248 + contsize = 4 + 4 + xdr_len_object(encsize); 249 + 250 + /* struct YFSAppData { 251 + * opr_uuid initiatorUuid; 252 + * opr_uuid acceptorUuid; 253 + * Capabilities caps; 254 + * afs_int32 enctype; 255 + * opaque callbackKey<>; 256 + * opaque callbackToken<>; 257 + * }; 258 + */ 259 + adatasize = 16 + 16 + 260 + xdr_len_object(sizeof(caps)) + 261 + 4 + 262 + xdr_len_object(conn_krb5->key_len) + 263 + xdr_len_object(contsize); 264 + 265 + ret = -ENOMEM; 266 + appdata = kzalloc(adatasize, GFP_KERNEL); 267 + if (!appdata) 268 + goto out; 269 + xdr = appdata; 270 + 271 + memcpy(xdr, &net->uuid, 16); /* appdata.initiatorUuid */ 272 + xdr += 16 / 4; 273 + memcpy(xdr, &server->uuid, 16); /* appdata.acceptorUuid */ 274 + xdr += 16 / 4; 275 + *xdr++ = htonl(ARRAY_SIZE(caps)); /* appdata.caps.len */ 276 + memcpy(xdr, &caps, sizeof(caps)); /* appdata.caps */ 277 + xdr += ARRAY_SIZE(caps); 278 + *xdr++ = htonl(conn_krb5->etype); /* appdata.enctype */ 279 + 280 + *xdr++ = htonl(conn_krb5->key_len); /* appdata.callbackKey.len */ 281 + K0 = xdr; 282 + get_random_bytes(K0, conn_krb5->key_len); /* appdata.callbackKey.data */ 283 + xdr += xdr_round_up(conn_krb5->key_len) / 4; 284 + 285 + *xdr++ = htonl(contsize); /* appdata.callbackToken.len */ 286 + *xdr++ = htonl(1); /* cont.kvno */ 287 + *xdr++ = htonl(token_krb5->etype); /* cont.enctype */ 288 + *xdr++ = htonl(encsize); /* cont.encrypted_token.len */ 289 + 290 + encbase = xdr; 291 + xdr += offset / 4; 292 + *xdr++ = htonl(conn_krb5->etype); /* token.K0.enctype */ 293 + *xdr++ = htonl(conn_krb5->key_len); /* token.K0.key.len */ 294 + memcpy(xdr, K0, conn_krb5->key_len); /* token.K0.key.data */ 295 + xdr += xdr_round_up(conn_krb5->key_len) / 4; 296 + 297 + *xdr++ = htonl(RXRPC_SECURITY_ENCRYPT); /* token.level */ 298 + *xdr++ = htonl(0); /* token.starttime */ 299 + *xdr++ = htonl(0); /* " */ 300 + *xdr++ = htonl(0); /* token.lifetime */ 301 + *xdr++ = htonl(0); /* token.bytelife */ 302 + *xdr++ = htonl(0); /* token.expirationtime */ 303 + *xdr++ = htonl(0); /* " */ 304 + *xdr++ = htonl(1); /* token.identities.count */ 305 + *xdr++ = htonl(0); /* token.identities[0].kind */ 306 + *xdr++ = htonl(uuidsize); /* token.identities[0].data.len */ 307 + memcpy(xdr, &server->uuid, uuidsize); 308 + xdr += xdr_round_up(uuidsize) / 4; 309 + *xdr++ = htonl(0); /* token.identities[0].display.len */ 310 + 311 + xdr = encbase + xdr_round_up(encsize); 312 + 313 + if ((unsigned long)xdr - (unsigned long)appdata != adatasize) 314 + pr_err("Appdata size incorrect %lx != %zx\n", 315 + (unsigned long)xdr - (unsigned long)appdata, adatasize); 316 + 317 + aead = crypto_krb5_prepare_encryption(token_krb5, token_key, RXGK_SERVER_ENC_TOKEN, 318 + GFP_KERNEL); 319 + if (IS_ERR(aead)) { 320 + ret = PTR_ERR(aead); 321 + goto out_token; 322 + } 323 + 324 + sg_init_one(&sg, encbase, encsize); 325 + ret = crypto_krb5_encrypt(token_krb5, aead, &sg, 1, encsize, offset, toksize, false); 326 + if (ret < 0) 327 + goto out_aead; 328 + 329 + server->cm_rxgk_appdata.len = adatasize; 330 + server->cm_rxgk_appdata.data = appdata; 331 + appdata = NULL; 332 + 333 + out_aead: 334 + crypto_free_aead(aead); 335 + out_token: 336 + kfree(appdata); 337 + out: 338 + return ret; 339 + } 340 + #endif /* CONFIG_RXGK */
+20
fs/afs/internal.h
··· 20 20 #include <linux/uuid.h> 21 21 #include <linux/mm_types.h> 22 22 #include <linux/dns_resolver.h> 23 + #include <crypto/krb5.h> 23 24 #include <net/net_namespace.h> 24 25 #include <net/netns/generic.h> 25 26 #include <net/sock.h> ··· 177 176 bool intr; /* T if interruptible */ 178 177 bool unmarshalling_error; /* T if an unmarshalling error occurred */ 179 178 bool responded; /* Got a response from the call (may be abort) */ 179 + u8 security_ix; /* Security class */ 180 180 u16 service_id; /* Actual service ID (after upgrade) */ 181 181 unsigned int debug_id; /* Trace ID */ 182 + u32 enctype; /* Security encoding type */ 182 183 u32 operation_ID; /* operation ID for an incoming call */ 183 184 u32 count; /* count for use in unmarshalling */ 184 185 union { /* place to extract temporary data */ ··· 284 281 struct socket *socket; 285 282 struct afs_call *spare_incoming_call; 286 283 struct work_struct charge_preallocation_work; 284 + struct work_struct rx_oob_work; 287 285 struct mutex socket_mutex; 288 286 atomic_t nr_outstanding_calls; 289 287 atomic_t nr_superblocks; ··· 309 305 struct list_head fs_probe_slow; /* List of afs_server to probe at 5m intervals */ 310 306 struct hlist_head fs_proc; /* procfs servers list */ 311 307 308 + struct key *fs_cm_token_key; /* Key for creating CM tokens */ 312 309 struct work_struct fs_prober; 313 310 struct timer_list fs_probe_timer; 314 311 atomic_t servers_outstanding; ··· 545 540 struct list_head volumes; /* RCU list of afs_server_entry objects */ 546 541 struct work_struct destroyer; /* Work item to try and destroy a server */ 547 542 struct timer_list timer; /* Management timer */ 543 + struct mutex cm_token_lock; /* Lock governing creation of appdata */ 544 + struct krb5_buffer cm_rxgk_appdata; /* Appdata to be included in RESPONSE packet */ 548 545 time64_t unuse_time; /* Time at which last unused */ 549 546 unsigned long flags; 550 547 #define AFS_SERVER_FL_RESPONDING 0 /* The server is responding */ ··· 1064 1057 * cmservice.c 1065 1058 */ 1066 1059 extern bool afs_cm_incoming_call(struct afs_call *); 1060 + 1061 + /* 1062 + * cm_security.c 1063 + */ 1064 + void afs_process_oob_queue(struct work_struct *work); 1065 + #ifdef CONFIG_RXGK 1066 + int afs_create_token_key(struct afs_net *net, struct socket *socket); 1067 + #else 1068 + static inline int afs_create_token_key(struct afs_net *net, struct socket *socket) 1069 + { 1070 + return 0; 1071 + } 1072 + #endif 1067 1073 1068 1074 /* 1069 1075 * dir.c
+1
fs/afs/main.c
··· 73 73 generate_random_uuid((unsigned char *)&net->uuid); 74 74 75 75 INIT_WORK(&net->charge_preallocation_work, afs_charge_preallocation); 76 + INIT_WORK(&net->rx_oob_work, afs_process_oob_queue); 76 77 mutex_init(&net->socket_mutex); 77 78 78 79 net->cells = RB_ROOT;
+27
fs/afs/misc.c
··· 8 8 #include <linux/kernel.h> 9 9 #include <linux/module.h> 10 10 #include <linux/errno.h> 11 + #include <crypto/krb5.h> 11 12 #include "internal.h" 12 13 #include "afs_fs.h" 13 14 #include "protocol_uae.h" ··· 103 102 case RXKADSEALEDINCON: return -EKEYREJECTED; 104 103 case RXKADDATALEN: return -EKEYREJECTED; 105 104 case RXKADILLEGALLEVEL: return -EKEYREJECTED; 105 + 106 + case RXGK_INCONSISTENCY: return -EPROTO; 107 + case RXGK_PACKETSHORT: return -EPROTO; 108 + case RXGK_BADCHALLENGE: return -EPROTO; 109 + case RXGK_SEALEDINCON: return -EKEYREJECTED; 110 + case RXGK_NOTAUTH: return -EKEYREJECTED; 111 + case RXGK_EXPIRED: return -EKEYEXPIRED; 112 + case RXGK_BADLEVEL: return -EKEYREJECTED; 113 + case RXGK_BADKEYNO: return -EKEYREJECTED; 114 + case RXGK_NOTRXGK: return -EKEYREJECTED; 115 + case RXGK_UNSUPPORTED: return -EKEYREJECTED; 116 + case RXGK_GSSERROR: return -EKEYREJECTED; 117 + #ifdef RXGK_BADETYPE 118 + case RXGK_BADETYPE: return -ENOPKG; 119 + #endif 120 + #ifdef RXGK_BADTOKEN 121 + case RXGK_BADTOKEN: return -EKEYREJECTED; 122 + #endif 123 + #ifdef RXGK_BADETYPE 124 + case RXGK_DATALEN: return -EPROTO; 125 + #endif 126 + #ifdef RXGK_BADQOP 127 + case RXGK_BADQOP: return -EKEYREJECTED; 128 + #endif 129 + 130 + case KRB5_PROG_KEYTYPE_NOSUPP: return -ENOPKG; 106 131 107 132 case RXGEN_OPCODE: return -ENOTSUPP; 108 133
+36 -4
fs/afs/rxrpc.c
··· 24 24 static void afs_process_async_call(struct work_struct *); 25 25 static void afs_rx_new_call(struct sock *, struct rxrpc_call *, unsigned long); 26 26 static void afs_rx_discard_new_call(struct rxrpc_call *, unsigned long); 27 + static void afs_rx_attach(struct rxrpc_call *rxcall, unsigned long user_call_ID); 28 + static void afs_rx_notify_oob(struct sock *sk, struct sk_buff *oob); 27 29 static int afs_deliver_cm_op_id(struct afs_call *); 30 + 31 + static const struct rxrpc_kernel_ops afs_rxrpc_callback_ops = { 32 + .notify_new_call = afs_rx_new_call, 33 + .discard_new_call = afs_rx_discard_new_call, 34 + .user_attach_call = afs_rx_attach, 35 + .notify_oob = afs_rx_notify_oob, 36 + }; 28 37 29 38 /* asynchronous incoming call initial processing */ 30 39 static const struct afs_call_type afs_RXCMxxxx = { ··· 58 49 goto error_1; 59 50 60 51 socket->sk->sk_allocation = GFP_NOFS; 52 + socket->sk->sk_user_data = net; 61 53 62 54 /* bind the callback manager's address to make this a server socket */ 63 55 memset(&srx, 0, sizeof(srx)); ··· 73 63 RXRPC_SECURITY_ENCRYPT); 74 64 if (ret < 0) 75 65 goto error_2; 66 + 67 + ret = rxrpc_sock_set_manage_response(socket->sk, true); 68 + if (ret < 0) 69 + goto error_2; 70 + 71 + ret = afs_create_token_key(net, socket); 72 + if (ret < 0) 73 + pr_err("Couldn't create RxGK CM key: %d\n", ret); 76 74 77 75 ret = kernel_bind(socket, (struct sockaddr *) &srx, sizeof(srx)); 78 76 if (ret == -EADDRINUSE) { ··· 102 84 * it sends back to us. 103 85 */ 104 86 105 - rxrpc_kernel_new_call_notification(socket, afs_rx_new_call, 106 - afs_rx_discard_new_call); 87 + rxrpc_kernel_set_notifications(socket, &afs_rxrpc_callback_ops); 107 88 108 89 ret = kernel_listen(socket, INT_MAX); 109 90 if (ret < 0) ··· 142 125 143 126 kernel_sock_shutdown(net->socket, SHUT_RDWR); 144 127 flush_workqueue(afs_async_calls); 128 + net->socket->sk->sk_user_data = NULL; 145 129 sock_release(net->socket); 130 + key_put(net->fs_cm_token_key); 146 131 147 132 _debug("dework"); 148 133 _leave(""); ··· 757 738 758 739 if (rxrpc_kernel_charge_accept(net->socket, 759 740 afs_wake_up_async_call, 760 - afs_rx_attach, 761 741 (unsigned long)call, 762 742 GFP_KERNEL, 763 743 call->debug_id) < 0) ··· 818 800 if (!afs_cm_incoming_call(call)) 819 801 return -ENOTSUPP; 820 802 803 + call->security_ix = rxrpc_kernel_query_call_security(call->rxcall, 804 + &call->service_id, 805 + &call->enctype); 806 + 821 807 trace_afs_cb_call(call); 822 808 call->work.func = call->type->work; 823 809 824 - /* pass responsibility for the remainer of this message off to the 810 + /* pass responsibility for the remainder of this message off to the 825 811 * cache manager op */ 826 812 return call->type->deliver(call); 827 813 } ··· 973 951 if (call) 974 952 call->unmarshalling_error = true; 975 953 return -EBADMSG; 954 + } 955 + 956 + /* 957 + * Wake up OOB notification processing. 958 + */ 959 + static void afs_rx_notify_oob(struct sock *sk, struct sk_buff *oob) 960 + { 961 + struct afs_net *net = sk->sk_user_data; 962 + 963 + schedule_work(&net->rx_oob_work); 976 964 }
+2
fs/afs/server.c
··· 131 131 timer_setup(&server->timer, afs_server_timer, 0); 132 132 INIT_LIST_HEAD(&server->volumes); 133 133 init_waitqueue_head(&server->probe_wq); 134 + mutex_init(&server->cm_token_lock); 134 135 INIT_LIST_HEAD(&server->probe_link); 135 136 INIT_HLIST_NODE(&server->proc_link); 136 137 spin_lock_init(&server->probe_lock); ··· 397 396 afs_put_endpoint_state(rcu_access_pointer(server->endpoint_state), 398 397 afs_estate_trace_put_server); 399 398 afs_put_cell(server->cell, afs_cell_trace_put_server); 399 + kfree(server->cm_rxgk_appdata.data); 400 400 kfree(server); 401 401 } 402 402
+5
include/crypto/krb5.h
··· 64 64 #define KEY_USAGE_SEED_INTEGRITY (0x55) 65 65 66 66 /* 67 + * Standard Kerberos error codes. 68 + */ 69 + #define KRB5_PROG_KEYTYPE_NOSUPP -1765328233 70 + 71 + /* 67 72 * Mode of operation. 68 73 */ 69 74 enum krb5_crypto_mode {
+17
include/keys/rxrpc-type.h
··· 9 9 #define _KEYS_RXRPC_TYPE_H 10 10 11 11 #include <linux/key.h> 12 + #include <crypto/krb5.h> 12 13 13 14 /* 14 15 * key type for AF_RXRPC keys ··· 33 32 }; 34 33 35 34 /* 35 + * RxRPC key for YFS-RxGK (type-6 security) 36 + */ 37 + struct rxgk_key { 38 + s64 begintime; /* Time at which the ticket starts */ 39 + s64 endtime; /* Time at which the ticket ends */ 40 + u64 lifetime; /* Maximum lifespan of a connection (seconds) */ 41 + u64 bytelife; /* Maximum number of bytes on a connection */ 42 + unsigned int enctype; /* Encoding type */ 43 + s8 level; /* Negotiated security RXRPC_SECURITY_PLAIN/AUTH/ENCRYPT */ 44 + struct krb5_buffer key; /* Master key, K0 */ 45 + struct krb5_buffer ticket; /* Ticket to be passed to server */ 46 + u8 _key[]; /* Key storage */ 47 + }; 48 + 49 + /* 36 50 * list of tokens attached to an rxrpc key 37 51 */ 38 52 struct rxrpc_key_token { ··· 56 40 struct rxrpc_key_token *next; /* the next token in the list */ 57 41 union { 58 42 struct rxkad_key *kad; 43 + struct rxgk_key *rxgk; 59 44 }; 60 45 }; 61 46
+41 -10
include/net/af_rxrpc.h
··· 16 16 struct socket; 17 17 struct rxrpc_call; 18 18 struct rxrpc_peer; 19 + struct krb5_buffer; 19 20 enum rxrpc_abort_reason; 20 21 21 22 enum rxrpc_interruptibility { ··· 25 24 RXRPC_UNINTERRUPTIBLE, /* Call should not be interruptible at all */ 26 25 }; 27 26 27 + enum rxrpc_oob_type { 28 + RXRPC_OOB_CHALLENGE, /* Security challenge for a connection */ 29 + }; 30 + 28 31 /* 29 32 * Debug ID counter for tracing. 30 33 */ 31 34 extern atomic_t rxrpc_debug_id; 32 35 36 + /* 37 + * Operations table for rxrpc to call out to a kernel application (e.g. kAFS). 38 + */ 39 + struct rxrpc_kernel_ops { 40 + void (*notify_new_call)(struct sock *sk, struct rxrpc_call *call, 41 + unsigned long user_call_ID); 42 + void (*discard_new_call)(struct rxrpc_call *call, unsigned long user_call_ID); 43 + void (*user_attach_call)(struct rxrpc_call *call, unsigned long user_call_ID); 44 + void (*notify_oob)(struct sock *sk, struct sk_buff *oob); 45 + }; 46 + 33 47 typedef void (*rxrpc_notify_rx_t)(struct sock *, struct rxrpc_call *, 34 48 unsigned long); 35 49 typedef void (*rxrpc_notify_end_tx_t)(struct sock *, struct rxrpc_call *, 36 50 unsigned long); 37 - typedef void (*rxrpc_notify_new_call_t)(struct sock *, struct rxrpc_call *, 38 - unsigned long); 39 - typedef void (*rxrpc_discard_new_call_t)(struct rxrpc_call *, unsigned long); 40 - typedef void (*rxrpc_user_attach_call_t)(struct rxrpc_call *, unsigned long); 41 51 42 - void rxrpc_kernel_new_call_notification(struct socket *, 43 - rxrpc_notify_new_call_t, 44 - rxrpc_discard_new_call_t); 52 + void rxrpc_kernel_set_notifications(struct socket *sock, 53 + const struct rxrpc_kernel_ops *app_ops); 45 54 struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock, 46 55 struct rxrpc_peer *peer, 47 56 struct key *key, ··· 83 72 unsigned long rxrpc_kernel_set_peer_data(struct rxrpc_peer *peer, unsigned long app_data); 84 73 unsigned long rxrpc_kernel_get_peer_data(const struct rxrpc_peer *peer); 85 74 unsigned int rxrpc_kernel_get_srtt(const struct rxrpc_peer *); 86 - int rxrpc_kernel_charge_accept(struct socket *, rxrpc_notify_rx_t, 87 - rxrpc_user_attach_call_t, unsigned long, gfp_t, 88 - unsigned int); 75 + int rxrpc_kernel_charge_accept(struct socket *sock, rxrpc_notify_rx_t notify_rx, 76 + unsigned long user_call_ID, gfp_t gfp, 77 + unsigned int debug_id); 89 78 void rxrpc_kernel_set_tx_length(struct socket *, struct rxrpc_call *, s64); 90 79 bool rxrpc_kernel_check_life(const struct socket *, const struct rxrpc_call *); 91 80 u32 rxrpc_kernel_get_epoch(struct socket *, struct rxrpc_call *); ··· 94 83 95 84 int rxrpc_sock_set_min_security_level(struct sock *sk, unsigned int val); 96 85 int rxrpc_sock_set_security_keyring(struct sock *, struct key *); 86 + int rxrpc_sock_set_manage_response(struct sock *sk, bool set); 87 + 88 + enum rxrpc_oob_type rxrpc_kernel_query_oob(struct sk_buff *oob, 89 + struct rxrpc_peer **_peer, 90 + unsigned long *_peer_appdata); 91 + struct sk_buff *rxrpc_kernel_dequeue_oob(struct socket *sock, 92 + enum rxrpc_oob_type *_type); 93 + void rxrpc_kernel_free_oob(struct sk_buff *oob); 94 + void rxrpc_kernel_query_challenge(struct sk_buff *challenge, 95 + struct rxrpc_peer **_peer, 96 + unsigned long *_peer_appdata, 97 + u16 *_service_id, u8 *_security_index); 98 + int rxrpc_kernel_reject_challenge(struct sk_buff *challenge, u32 abort_code, 99 + int error, enum rxrpc_abort_reason why); 100 + int rxkad_kernel_respond_to_challenge(struct sk_buff *challenge); 101 + u32 rxgk_kernel_query_challenge(struct sk_buff *challenge); 102 + int rxgk_kernel_respond_to_challenge(struct sk_buff *challenge, 103 + struct krb5_buffer *appdata); 104 + u8 rxrpc_kernel_query_call_security(struct rxrpc_call *call, 105 + u16 *_service_id, u32 *_enctype); 97 106 98 107 #endif /* _NET_RXRPC_H */
+9 -2
include/trace/events/afs.h
··· 663 663 __field(unsigned int, call) 664 664 __field(u32, op) 665 665 __field(u16, service_id) 666 + __field(u8, security_ix) 667 + __field(u32, enctype) 666 668 ), 667 669 668 670 TP_fast_assign( 669 671 __entry->call = call->debug_id; 670 672 __entry->op = call->operation_ID; 671 673 __entry->service_id = call->service_id; 674 + __entry->security_ix = call->security_ix; 675 + __entry->enctype = call->enctype; 672 676 ), 673 677 674 - TP_printk("c=%08x %s", 678 + TP_printk("c=%08x %s sv=%u sx=%u en=%u", 675 679 __entry->call, 676 680 __entry->service_id == 2501 ? 677 681 __print_symbolic(__entry->op, yfs_cm_operations) : 678 - __print_symbolic(__entry->op, afs_cm_operations)) 682 + __print_symbolic(__entry->op, afs_cm_operations), 683 + __entry->service_id, 684 + __entry->security_ix, 685 + __entry->enctype) 679 686 ); 680 687 681 688 TRACE_EVENT(afs_call,
+160 -3
include/trace/events/rxrpc.h
··· 25 25 EM(afs_abort_probeuuid_negative, "afs-probeuuid-neg") \ 26 26 EM(afs_abort_send_data_error, "afs-send-data") \ 27 27 EM(afs_abort_unmarshal_error, "afs-unmarshal") \ 28 + EM(afs_abort_unsupported_sec_class, "afs-unsup-sec-class") \ 28 29 /* rxperf errors */ \ 29 30 EM(rxperf_abort_general_error, "rxperf-error") \ 30 31 EM(rxperf_abort_oom, "rxperf-oom") \ ··· 69 68 EM(rxkad_abort_resp_tkt_sname, "rxkad-resp-tk-sname") \ 70 69 EM(rxkad_abort_resp_unknown_tkt, "rxkad-resp-unknown-tkt") \ 71 70 EM(rxkad_abort_resp_version, "rxkad-resp-version") \ 71 + /* RxGK security errors */ \ 72 + EM(rxgk_abort_1_verify_mic_eproto, "rxgk1-vfy-mic-eproto") \ 73 + EM(rxgk_abort_2_decrypt_eproto, "rxgk2-dec-eproto") \ 74 + EM(rxgk_abort_2_short_data, "rxgk2-short-data") \ 75 + EM(rxgk_abort_2_short_encdata, "rxgk2-short-encdata") \ 76 + EM(rxgk_abort_2_short_header, "rxgk2-short-hdr") \ 77 + EM(rxgk_abort_bad_key_number, "rxgk-bad-key-num") \ 78 + EM(rxgk_abort_chall_key_expired, "rxgk-chall-key-exp") \ 79 + EM(rxgk_abort_chall_no_key, "rxgk-chall-nokey") \ 80 + EM(rxgk_abort_chall_short, "rxgk-chall-short") \ 81 + EM(rxgk_abort_resp_auth_dec, "rxgk-resp-auth-dec") \ 82 + EM(rxgk_abort_resp_bad_callid, "rxgk-resp-bad-callid") \ 83 + EM(rxgk_abort_resp_bad_nonce, "rxgk-resp-bad-nonce") \ 84 + EM(rxgk_abort_resp_bad_param, "rxgk-resp-bad-param") \ 85 + EM(rxgk_abort_resp_call_ctr, "rxgk-resp-call-ctr") \ 86 + EM(rxgk_abort_resp_call_state, "rxgk-resp-call-state") \ 87 + EM(rxgk_abort_resp_internal_error, "rxgk-resp-int-error") \ 88 + EM(rxgk_abort_resp_nopkg, "rxgk-resp-nopkg") \ 89 + EM(rxgk_abort_resp_short_applen, "rxgk-resp-short-applen") \ 90 + EM(rxgk_abort_resp_short_auth, "rxgk-resp-short-auth") \ 91 + EM(rxgk_abort_resp_short_call_list, "rxgk-resp-short-callls") \ 92 + EM(rxgk_abort_resp_short_packet, "rxgk-resp-short-packet") \ 93 + EM(rxgk_abort_resp_short_yfs_klen, "rxgk-resp-short-yfs-klen") \ 94 + EM(rxgk_abort_resp_short_yfs_key, "rxgk-resp-short-yfs-key") \ 95 + EM(rxgk_abort_resp_short_yfs_tkt, "rxgk-resp-short-yfs-tkt") \ 96 + EM(rxgk_abort_resp_tok_dec, "rxgk-resp-tok-dec") \ 97 + EM(rxgk_abort_resp_tok_internal_error, "rxgk-resp-tok-int-err") \ 98 + EM(rxgk_abort_resp_tok_keyerr, "rxgk-resp-tok-keyerr") \ 99 + EM(rxgk_abort_resp_tok_nokey, "rxgk-resp-tok-nokey") \ 100 + EM(rxgk_abort_resp_tok_nopkg, "rxgk-resp-tok-nopkg") \ 101 + EM(rxgk_abort_resp_tok_short, "rxgk-resp-tok-short") \ 102 + EM(rxgk_abort_resp_xdr_align, "rxgk-resp-xdr-align") \ 72 103 /* rxrpc errors */ \ 73 104 EM(rxrpc_abort_call_improper_term, "call-improper-term") \ 74 105 EM(rxrpc_abort_call_reset, "call-reset") \ ··· 110 77 EM(rxrpc_abort_call_timeout, "call-timeout") \ 111 78 EM(rxrpc_abort_no_service_key, "no-serv-key") \ 112 79 EM(rxrpc_abort_nomem, "nomem") \ 80 + EM(rxrpc_abort_response_sendmsg, "resp-sendmsg") \ 113 81 EM(rxrpc_abort_service_not_offered, "serv-not-offered") \ 114 82 EM(rxrpc_abort_shut_down, "shut-down") \ 115 83 EM(rxrpc_abort_unsupported_security, "unsup-sec") \ ··· 167 133 EM(rxrpc_skb_get_conn_secured, "GET conn-secd") \ 168 134 EM(rxrpc_skb_get_conn_work, "GET conn-work") \ 169 135 EM(rxrpc_skb_get_local_work, "GET locl-work") \ 136 + EM(rxrpc_skb_get_post_oob, "GET post-oob ") \ 170 137 EM(rxrpc_skb_get_reject_work, "GET rej-work ") \ 171 138 EM(rxrpc_skb_get_to_recvmsg, "GET to-recv ") \ 172 139 EM(rxrpc_skb_get_to_recvmsg_oos, "GET to-recv-o") \ 173 140 EM(rxrpc_skb_new_encap_rcv, "NEW encap-rcv") \ 174 141 EM(rxrpc_skb_new_error_report, "NEW error-rpt") \ 175 142 EM(rxrpc_skb_new_jumbo_subpacket, "NEW jumbo-sub") \ 143 + EM(rxrpc_skb_new_response_rxgk, "NEW resp-rxgk") \ 144 + EM(rxrpc_skb_new_response_rxkad, "NEW resp-rxkd") \ 176 145 EM(rxrpc_skb_new_unshared, "NEW unshared ") \ 177 146 EM(rxrpc_skb_put_call_rx, "PUT call-rx ") \ 147 + EM(rxrpc_skb_put_challenge, "PUT challenge") \ 178 148 EM(rxrpc_skb_put_conn_secured, "PUT conn-secd") \ 179 149 EM(rxrpc_skb_put_conn_work, "PUT conn-work") \ 180 150 EM(rxrpc_skb_put_error_report, "PUT error-rep") \ 181 151 EM(rxrpc_skb_put_input, "PUT input ") \ 182 152 EM(rxrpc_skb_put_jumbo_subpacket, "PUT jumbo-sub") \ 153 + EM(rxrpc_skb_put_oob, "PUT oob ") \ 183 154 EM(rxrpc_skb_put_purge, "PUT purge ") \ 155 + EM(rxrpc_skb_put_purge_oob, "PUT purge-oob") \ 156 + EM(rxrpc_skb_put_response, "PUT response ") \ 184 157 EM(rxrpc_skb_put_rotate, "PUT rotate ") \ 185 158 EM(rxrpc_skb_put_unknown, "PUT unknown ") \ 186 159 EM(rxrpc_skb_see_conn_work, "SEE conn-work") \ 160 + EM(rxrpc_skb_see_oob_challenge, "SEE oob-chall") \ 187 161 EM(rxrpc_skb_see_recvmsg, "SEE recvmsg ") \ 162 + EM(rxrpc_skb_see_recvmsg_oob, "SEE recvm-oob") \ 188 163 EM(rxrpc_skb_see_reject, "SEE reject ") \ 189 164 EM(rxrpc_skb_see_rotate, "SEE rotate ") \ 190 165 E_(rxrpc_skb_see_version, "SEE version ") ··· 259 216 EM(rxrpc_conn_free, "FREE ") \ 260 217 EM(rxrpc_conn_get_activate_call, "GET act-call") \ 261 218 EM(rxrpc_conn_get_call_input, "GET inp-call") \ 219 + EM(rxrpc_conn_get_challenge_input, "GET inp-chal") \ 262 220 EM(rxrpc_conn_get_conn_input, "GET inp-conn") \ 263 221 EM(rxrpc_conn_get_idle, "GET idle ") \ 264 222 EM(rxrpc_conn_get_poke_abort, "GET pk-abort") \ 223 + EM(rxrpc_conn_get_poke_response, "GET response") \ 265 224 EM(rxrpc_conn_get_poke_secured, "GET secured ") \ 266 225 EM(rxrpc_conn_get_poke_timer, "GET poke ") \ 267 226 EM(rxrpc_conn_get_service_conn, "GET svc-conn") \ ··· 271 226 EM(rxrpc_conn_new_service, "NEW service ") \ 272 227 EM(rxrpc_conn_put_call, "PUT call ") \ 273 228 EM(rxrpc_conn_put_call_input, "PUT inp-call") \ 229 + EM(rxrpc_conn_put_challenge_input, "PUT inp-chal") \ 274 230 EM(rxrpc_conn_put_conn_input, "PUT inp-conn") \ 275 231 EM(rxrpc_conn_put_discard_idle, "PUT disc-idl") \ 276 232 EM(rxrpc_conn_put_local_dead, "PUT loc-dead") \ 277 233 EM(rxrpc_conn_put_noreuse, "PUT noreuse ") \ 234 + EM(rxrpc_conn_put_oob, "PUT oob ") \ 278 235 EM(rxrpc_conn_put_poke, "PUT poke ") \ 279 236 EM(rxrpc_conn_put_service_reaped, "PUT svc-reap") \ 280 237 EM(rxrpc_conn_put_unbundle, "PUT unbundle") \ ··· 378 331 EM(rxrpc_recvmsg_full, "FULL") \ 379 332 EM(rxrpc_recvmsg_hole, "HOLE") \ 380 333 EM(rxrpc_recvmsg_next, "NEXT") \ 334 + EM(rxrpc_recvmsg_oobq, "OOBQ") \ 381 335 EM(rxrpc_recvmsg_requeue, "REQU") \ 382 336 EM(rxrpc_recvmsg_return, "RETN") \ 383 337 EM(rxrpc_recvmsg_terminal, "TERM") \ ··· 503 455 EM(rxrpc_tx_point_call_final_resend, "CallFinalResend") \ 504 456 EM(rxrpc_tx_point_conn_abort, "ConnAbort") \ 505 457 EM(rxrpc_tx_point_reject, "Reject") \ 458 + EM(rxrpc_tx_point_rxgk_challenge, "RxGKChall") \ 506 459 EM(rxrpc_tx_point_rxkad_challenge, "RxkadChall") \ 507 - EM(rxrpc_tx_point_rxkad_response, "RxkadResp") \ 460 + EM(rxrpc_tx_point_response, "Response") \ 508 461 EM(rxrpc_tx_point_version_keepalive, "VerKeepalive") \ 509 462 E_(rxrpc_tx_point_version_reply, "VerReply") 510 463 ··· 522 473 523 474 #define rxrpc_txbuf_traces \ 524 475 EM(rxrpc_txbuf_alloc_data, "ALLOC DATA ") \ 476 + EM(rxrpc_txbuf_alloc_response, "ALLOC RESP ") \ 525 477 EM(rxrpc_txbuf_free, "FREE ") \ 526 478 EM(rxrpc_txbuf_get_buffer, "GET BUFFER ") \ 527 479 EM(rxrpc_txbuf_get_trans, "GET TRANS ") \ ··· 530 480 EM(rxrpc_txbuf_put_cleaned, "PUT CLEANED") \ 531 481 EM(rxrpc_txbuf_put_nomem, "PUT NOMEM ") \ 532 482 EM(rxrpc_txbuf_put_rotated, "PUT ROTATED") \ 483 + EM(rxrpc_txbuf_put_response_tx, "PUT RESP TX") \ 533 484 EM(rxrpc_txbuf_put_send_aborted, "PUT SEND-X ") \ 534 485 EM(rxrpc_txbuf_put_trans, "PUT TRANS ") \ 535 486 EM(rxrpc_txbuf_see_lost, "SEE LOST ") \ ··· 1201 1150 __entry->abort_code) 1202 1151 ); 1203 1152 1153 + TRACE_EVENT(rxrpc_tx_challenge, 1154 + TP_PROTO(struct rxrpc_connection *conn, rxrpc_serial_t serial, 1155 + u32 version, u32 nonce), 1156 + 1157 + TP_ARGS(conn, serial, version, nonce), 1158 + 1159 + TP_STRUCT__entry( 1160 + __field(unsigned int, conn) 1161 + __field(rxrpc_serial_t, serial) 1162 + __field(u32, version) 1163 + __field(u32, nonce) 1164 + __field(u16, service_id) 1165 + __field(u8, security_ix) 1166 + ), 1167 + 1168 + TP_fast_assign( 1169 + __entry->conn = conn->debug_id; 1170 + __entry->serial = serial; 1171 + __entry->version = version; 1172 + __entry->nonce = nonce; 1173 + __entry->service_id = conn->service_id; 1174 + __entry->security_ix = conn->security_ix; 1175 + ), 1176 + 1177 + TP_printk("C=%08x CHALLENGE r=%08x sv=%u+%u v=%x n=%x", 1178 + __entry->conn, 1179 + __entry->serial, 1180 + __entry->service_id, 1181 + __entry->security_ix, 1182 + __entry->version, 1183 + __entry->nonce) 1184 + ); 1185 + 1204 1186 TRACE_EVENT(rxrpc_rx_challenge, 1205 1187 TP_PROTO(struct rxrpc_connection *conn, rxrpc_serial_t serial, 1206 1188 u32 version, u32 nonce, u32 min_level), ··· 1246 1162 __field(u32, version) 1247 1163 __field(u32, nonce) 1248 1164 __field(u32, min_level) 1165 + __field(u16, service_id) 1166 + __field(u8, security_ix) 1249 1167 ), 1250 1168 1251 1169 TP_fast_assign( ··· 1256 1170 __entry->version = version; 1257 1171 __entry->nonce = nonce; 1258 1172 __entry->min_level = min_level; 1173 + __entry->service_id = conn->service_id; 1174 + __entry->security_ix = conn->security_ix; 1259 1175 ), 1260 1176 1261 - TP_printk("C=%08x CHALLENGE %08x v=%x n=%x ml=%x", 1177 + TP_printk("C=%08x CHALLENGE r=%08x sv=%u+%u v=%x n=%x ml=%x", 1262 1178 __entry->conn, 1263 1179 __entry->serial, 1180 + __entry->service_id, 1181 + __entry->security_ix, 1264 1182 __entry->version, 1265 1183 __entry->nonce, 1266 1184 __entry->min_level) 1185 + ); 1186 + 1187 + TRACE_EVENT(rxrpc_tx_response, 1188 + TP_PROTO(struct rxrpc_connection *conn, rxrpc_serial_t serial, 1189 + struct rxrpc_skb_priv *rsp), 1190 + 1191 + TP_ARGS(conn, serial, rsp), 1192 + 1193 + TP_STRUCT__entry( 1194 + __field(unsigned int, conn) 1195 + __field(rxrpc_serial_t, serial) 1196 + __field(rxrpc_serial_t, challenge) 1197 + __field(u32, version) 1198 + __field(u32, kvno) 1199 + __field(u16, ticket_len) 1200 + __field(u16, appdata_len) 1201 + __field(u16, service_id) 1202 + __field(u8, security_ix) 1203 + ), 1204 + 1205 + TP_fast_assign( 1206 + __entry->conn = conn->debug_id; 1207 + __entry->serial = serial; 1208 + __entry->challenge = rsp->resp.challenge_serial; 1209 + __entry->version = rsp->resp.version; 1210 + __entry->kvno = rsp->resp.kvno; 1211 + __entry->ticket_len = rsp->resp.ticket_len; 1212 + __entry->service_id = conn->service_id; 1213 + __entry->security_ix = conn->security_ix; 1214 + ), 1215 + 1216 + TP_printk("C=%08x RESPONSE r=%08x cr=%08x sv=%u+%u v=%x kv=%x tl=%u", 1217 + __entry->conn, 1218 + __entry->serial, 1219 + __entry->challenge, 1220 + __entry->service_id, 1221 + __entry->security_ix, 1222 + __entry->version, 1223 + __entry->kvno, 1224 + __entry->ticket_len) 1267 1225 ); 1268 1226 1269 1227 TRACE_EVENT(rxrpc_rx_response, ··· 1322 1192 __field(u32, version) 1323 1193 __field(u32, kvno) 1324 1194 __field(u32, ticket_len) 1195 + __field(u8, security_ix) 1325 1196 ), 1326 1197 1327 1198 TP_fast_assign( ··· 1331 1200 __entry->version = version; 1332 1201 __entry->kvno = kvno; 1333 1202 __entry->ticket_len = ticket_len; 1203 + __entry->security_ix = conn->security_ix; 1334 1204 ), 1335 1205 1336 - TP_printk("C=%08x RESPONSE %08x v=%x kvno=%x tl=%x", 1206 + TP_printk("C=%08x RESPONSE r=%08x sx=%u v=%x kvno=%x tl=%x", 1337 1207 __entry->conn, 1338 1208 __entry->serial, 1209 + __entry->security_ix, 1339 1210 __entry->version, 1340 1211 __entry->kvno, 1341 1212 __entry->ticket_len) ··· 2799 2666 __entry->exp ? "Exp" : "Set", 2800 2667 __print_symbolic(__entry->mode, rxrpc_rack_timer_modes), 2801 2668 ktime_to_us(__entry->delay)) 2669 + ); 2670 + 2671 + TRACE_EVENT(rxrpc_rxgk_rekey, 2672 + TP_PROTO(struct rxrpc_connection *conn, 2673 + unsigned int current_key, unsigned int requested_key), 2674 + 2675 + TP_ARGS(conn, current_key, requested_key), 2676 + 2677 + TP_STRUCT__entry( 2678 + __field(unsigned int, conn) 2679 + __field(unsigned int, current_key) 2680 + __field(unsigned int, requested_key) 2681 + ), 2682 + 2683 + TP_fast_assign( 2684 + __entry->conn = conn->debug_id; 2685 + __entry->current_key = current_key; 2686 + __entry->requested_key = requested_key; 2687 + ), 2688 + 2689 + TP_printk("C=%08x cur=%x req=%x", 2690 + __entry->conn, 2691 + __entry->current_key, 2692 + __entry->requested_key) 2802 2693 ); 2803 2694 2804 2695 #undef EM
+65 -12
include/uapi/linux/rxrpc.h
··· 36 36 #define RXRPC_MIN_SECURITY_LEVEL 4 /* minimum security level */ 37 37 #define RXRPC_UPGRADEABLE_SERVICE 5 /* Upgrade service[0] -> service[1] */ 38 38 #define RXRPC_SUPPORTED_CMSG 6 /* Get highest supported control message type */ 39 + #define RXRPC_MANAGE_RESPONSE 7 /* [clnt] Want to manage RESPONSE packets */ 39 40 40 41 /* 41 42 * RxRPC control messages 42 43 * - If neither abort or accept are specified, the message is a data message. 43 44 * - terminal messages mean that a user call ID tag can be recycled 45 + * - C/S/- indicate whether these are applicable to client, server or both 44 46 * - s/r/- indicate whether these are applicable to sendmsg() and/or recvmsg() 45 47 */ 46 48 enum rxrpc_cmsg_type { 47 - RXRPC_USER_CALL_ID = 1, /* sr: user call ID specifier */ 48 - RXRPC_ABORT = 2, /* sr: abort request / notification [terminal] */ 49 - RXRPC_ACK = 3, /* -r: [Service] RPC op final ACK received [terminal] */ 50 - RXRPC_NET_ERROR = 5, /* -r: network error received [terminal] */ 51 - RXRPC_BUSY = 6, /* -r: server busy received [terminal] */ 52 - RXRPC_LOCAL_ERROR = 7, /* -r: local error generated [terminal] */ 53 - RXRPC_NEW_CALL = 8, /* -r: [Service] new incoming call notification */ 54 - RXRPC_EXCLUSIVE_CALL = 10, /* s-: Call should be on exclusive connection */ 55 - RXRPC_UPGRADE_SERVICE = 11, /* s-: Request service upgrade for client call */ 56 - RXRPC_TX_LENGTH = 12, /* s-: Total length of Tx data */ 57 - RXRPC_SET_CALL_TIMEOUT = 13, /* s-: Set one or more call timeouts */ 58 - RXRPC_CHARGE_ACCEPT = 14, /* s-: Charge the accept pool with a user call ID */ 49 + RXRPC_USER_CALL_ID = 1, /* -sr: User call ID specifier */ 50 + RXRPC_ABORT = 2, /* -sr: Abort request / notification [terminal] */ 51 + RXRPC_ACK = 3, /* S-r: RPC op final ACK received [terminal] */ 52 + RXRPC_NET_ERROR = 5, /* --r: Network error received [terminal] */ 53 + RXRPC_BUSY = 6, /* C-r: Server busy received [terminal] */ 54 + RXRPC_LOCAL_ERROR = 7, /* --r: Local error generated [terminal] */ 55 + RXRPC_NEW_CALL = 8, /* S-r: New incoming call notification */ 56 + RXRPC_EXCLUSIVE_CALL = 10, /* Cs-: Call should be on exclusive connection */ 57 + RXRPC_UPGRADE_SERVICE = 11, /* Cs-: Request service upgrade for client call */ 58 + RXRPC_TX_LENGTH = 12, /* -s-: Total length of Tx data */ 59 + RXRPC_SET_CALL_TIMEOUT = 13, /* -s-: Set one or more call timeouts */ 60 + RXRPC_CHARGE_ACCEPT = 14, /* Ss-: Charge the accept pool with a user call ID */ 61 + RXRPC_OOB_ID = 15, /* -sr: OOB message ID */ 62 + RXRPC_CHALLENGED = 16, /* C-r: Info on a received CHALLENGE */ 63 + RXRPC_RESPOND = 17, /* Cs-: Respond to a challenge */ 64 + RXRPC_RESPONDED = 18, /* S-r: Data received in RESPONSE */ 65 + RXRPC_RESP_RXGK_APPDATA = 19, /* Cs-: RESPONSE: RxGK app data to include */ 59 66 RXRPC__SUPPORTED 60 67 }; 61 68 ··· 80 73 #define RXRPC_SECURITY_RXKAD 2 /* kaserver or kerberos 4 */ 81 74 #define RXRPC_SECURITY_RXGK 4 /* gssapi-based */ 82 75 #define RXRPC_SECURITY_RXK5 5 /* kerberos 5 */ 76 + #define RXRPC_SECURITY_YFS_RXGK 6 /* YFS gssapi-based */ 83 77 84 78 /* 85 79 * RxRPC-level abort codes ··· 125 117 #define RXKADSEALEDINCON 19270410 /* sealed data inconsistent */ 126 118 #define RXKADDATALEN 19270411 /* user data too long */ 127 119 #define RXKADILLEGALLEVEL 19270412 /* caller not authorised to use encrypted conns */ 120 + 121 + /* 122 + * RxGK GSSAPI security abort codes. 123 + */ 124 + #if 0 /* Original standard abort codes (used by OpenAFS) */ 125 + #define RXGK_INCONSISTENCY 1233242880 /* Security module structure inconsistent */ 126 + #define RXGK_PACKETSHORT 1233242881 /* Packet too short for security challenge */ 127 + #define RXGK_BADCHALLENGE 1233242882 /* Invalid security challenge */ 128 + #define RXGK_BADETYPE 1233242883 /* Invalid or impermissible encryption type */ 129 + #define RXGK_BADLEVEL 1233242884 /* Invalid or impermissible security level */ 130 + #define RXGK_BADKEYNO 1233242885 /* Key version number not found */ 131 + #define RXGK_EXPIRED 1233242886 /* Token has expired */ 132 + #define RXGK_NOTAUTH 1233242887 /* Caller not authorized */ 133 + #define RXGK_BAD_TOKEN 1233242888 /* Security object was passed a bad token */ 134 + #define RXGK_SEALED_INCON 1233242889 /* Sealed data inconsistent */ 135 + #define RXGK_DATA_LEN 1233242890 /* User data too long */ 136 + #define RXGK_BAD_QOP 1233242891 /* Inadequate quality of protection available */ 137 + #else /* Revised standard abort codes (used by YFS) */ 138 + #define RXGK_INCONSISTENCY 1233242880 /* Security module structure inconsistent */ 139 + #define RXGK_PACKETSHORT 1233242881 /* Packet too short for security challenge */ 140 + #define RXGK_BADCHALLENGE 1233242882 /* Security challenge/response failed */ 141 + #define RXGK_SEALEDINCON 1233242883 /* Sealed data is inconsistent */ 142 + #define RXGK_NOTAUTH 1233242884 /* Caller not authorised */ 143 + #define RXGK_EXPIRED 1233242885 /* Authentication expired */ 144 + #define RXGK_BADLEVEL 1233242886 /* Unsupported or not permitted security level */ 145 + #define RXGK_BADKEYNO 1233242887 /* Bad transport key number */ 146 + #define RXGK_NOTRXGK 1233242888 /* Security layer is not rxgk */ 147 + #define RXGK_UNSUPPORTED 1233242889 /* Endpoint does not support rxgk */ 148 + #define RXGK_GSSERROR 1233242890 /* GSSAPI mechanism error */ 149 + #endif 150 + 151 + /* 152 + * Challenge information in the RXRPC_CHALLENGED control message. 153 + */ 154 + struct rxrpc_challenge { 155 + __u16 service_id; /* The service ID of the connection (may be upgraded) */ 156 + __u8 security_index; /* The security index of the connection */ 157 + __u8 pad; /* Round out to a multiple of 4 bytes. */ 158 + /* ... The security class gets to append extra information ... */ 159 + }; 160 + 161 + struct rxgk_challenge { 162 + struct rxrpc_challenge base; 163 + __u32 enctype; /* Krb5 encoding type */ 164 + }; 128 165 129 166 #endif /* _UAPI_LINUX_RXRPC_H */
+23
net/rxrpc/Kconfig
··· 67 67 68 68 See Documentation/networking/rxrpc.rst. 69 69 70 + config RXGK 71 + bool "RxRPC GSSAPI security" 72 + select CRYPTO_KRB5 73 + select CRYPTO_MANAGER 74 + select CRYPTO_KRB5ENC 75 + select CRYPTO_AUTHENC 76 + select CRYPTO_SKCIPHER 77 + select CRYPTO_HASH_INFO 78 + select CRYPTO_HMAC 79 + select CRYPTO_CMAC 80 + select CRYPTO_SHA1 81 + select CRYPTO_SHA256 82 + select CRYPTO_SHA512 83 + select CRYPTO_CBC 84 + select CRYPTO_CTS 85 + select CRYPTO_AES 86 + select CRYPTO_CAMELLIA 87 + help 88 + Provide the GSSAPI-based RxGK security class for AFS. Keys are added 89 + with add_key(). 90 + 91 + See Documentation/networking/rxrpc.rst. 92 + 70 93 config RXPERF 71 94 tristate "RxRPC test service" 72 95 help
+5 -1
net/rxrpc/Makefile
··· 24 24 local_object.o \ 25 25 misc.o \ 26 26 net_ns.o \ 27 + oob.o \ 27 28 output.o \ 28 29 peer_event.o \ 29 30 peer_object.o \ ··· 40 39 rxrpc-$(CONFIG_PROC_FS) += proc.o 41 40 rxrpc-$(CONFIG_RXKAD) += rxkad.o 42 41 rxrpc-$(CONFIG_SYSCTL) += sysctl.o 43 - 42 + rxrpc-$(CONFIG_RXGK) += \ 43 + rxgk.o \ 44 + rxgk_app.o \ 45 + rxgk_kdf.o 44 46 45 47 obj-$(CONFIG_RXPERF) += rxperf.o
+75 -18
net/rxrpc/af_rxrpc.c
··· 265 265 * @gfp: Allocation flags 266 266 * 267 267 * Lookup or create a remote transport endpoint record for the specified 268 - * address and return it with a ref held. 268 + * address. 269 + * 270 + * Return: The peer record found with a reference, %NULL if no record is found 271 + * or a negative error code if the address is invalid or unsupported. 269 272 */ 270 273 struct rxrpc_peer *rxrpc_kernel_lookup_peer(struct socket *sock, 271 274 struct sockaddr_rxrpc *srx, gfp_t gfp) ··· 286 283 287 284 /** 288 285 * rxrpc_kernel_get_peer - Get a reference on a peer 289 - * @peer: The peer to get a reference on. 286 + * @peer: The peer to get a reference on (may be NULL). 290 287 * 291 - * Get a record for the remote peer in a call. 288 + * Get a reference for a remote peer record (if not NULL). 289 + * 290 + * Return: The @peer argument. 292 291 */ 293 292 struct rxrpc_peer *rxrpc_kernel_get_peer(struct rxrpc_peer *peer) 294 293 { ··· 301 296 /** 302 297 * rxrpc_kernel_put_peer - Allow a kernel app to drop a peer reference 303 298 * @peer: The peer to drop a ref on 299 + * 300 + * Drop a reference on a peer record. 304 301 */ 305 302 void rxrpc_kernel_put_peer(struct rxrpc_peer *peer) 306 303 { ··· 327 320 * 328 321 * Allow a kernel service to begin a call on the nominated socket. This just 329 322 * sets up all the internal tracking structures and allocates connection and 330 - * call IDs as appropriate. The call to be used is returned. 323 + * call IDs as appropriate. 331 324 * 332 325 * The default socket destination address and security may be overridden by 333 326 * supplying @srx and @key. 327 + * 328 + * Return: The new call or an error code. 334 329 */ 335 330 struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock, 336 331 struct rxrpc_peer *peer, ··· 446 437 * 447 438 * Allow a kernel service to find out whether a call is still alive - whether 448 439 * it has completed successfully and all received data has been consumed. 440 + * 441 + * Return: %true if the call is still ongoing and %false if it has completed. 449 442 */ 450 443 bool rxrpc_kernel_check_life(const struct socket *sock, 451 444 const struct rxrpc_call *call) ··· 467 456 * 468 457 * Allow a kernel service to retrieve the epoch value from a service call to 469 458 * see if the client at the other end rebooted. 459 + * 460 + * Return: The epoch of the call's connection. 470 461 */ 471 462 u32 rxrpc_kernel_get_epoch(struct socket *sock, struct rxrpc_call *call) 472 463 { ··· 477 464 EXPORT_SYMBOL(rxrpc_kernel_get_epoch); 478 465 479 466 /** 480 - * rxrpc_kernel_new_call_notification - Get notifications of new calls 481 - * @sock: The socket to intercept received messages on 482 - * @notify_new_call: Function to be called when new calls appear 483 - * @discard_new_call: Function to discard preallocated calls 467 + * rxrpc_kernel_set_notifications - Set table of callback operations 468 + * @sock: The socket to install table upon 469 + * @app_ops: Callback operation table to set 484 470 * 485 - * Allow a kernel service to be given notifications about new calls. 471 + * Allow a kernel service to set a table of event notifications on a socket. 486 472 */ 487 - void rxrpc_kernel_new_call_notification( 488 - struct socket *sock, 489 - rxrpc_notify_new_call_t notify_new_call, 490 - rxrpc_discard_new_call_t discard_new_call) 473 + void rxrpc_kernel_set_notifications(struct socket *sock, 474 + const struct rxrpc_kernel_ops *app_ops) 491 475 { 492 476 struct rxrpc_sock *rx = rxrpc_sk(sock->sk); 493 477 494 - rx->notify_new_call = notify_new_call; 495 - rx->discard_new_call = discard_new_call; 478 + rx->app_ops = app_ops; 496 479 } 497 - EXPORT_SYMBOL(rxrpc_kernel_new_call_notification); 480 + EXPORT_SYMBOL(rxrpc_kernel_set_notifications); 498 481 499 482 /** 500 483 * rxrpc_kernel_set_max_life - Set maximum lifespan on a call ··· 633 624 fallthrough; 634 625 case RXRPC_SERVER_BOUND: 635 626 case RXRPC_SERVER_LISTENING: 636 - ret = rxrpc_do_sendmsg(rx, m, len); 627 + if (m->msg_flags & MSG_OOB) 628 + ret = rxrpc_sendmsg_oob(rx, m, len); 629 + else 630 + ret = rxrpc_do_sendmsg(rx, m, len); 637 631 /* The socket has been unlocked */ 638 632 goto out; 639 633 default: ··· 671 659 sockptr_t optval, unsigned int optlen) 672 660 { 673 661 struct rxrpc_sock *rx = rxrpc_sk(sock->sk); 674 - unsigned int min_sec_level; 662 + unsigned int min_sec_level, val; 675 663 u16 service_upgrade[2]; 676 664 int ret; 677 665 ··· 750 738 goto error; 751 739 rx->service_upgrade.from = service_upgrade[0]; 752 740 rx->service_upgrade.to = service_upgrade[1]; 741 + goto success; 742 + 743 + case RXRPC_MANAGE_RESPONSE: 744 + ret = -EINVAL; 745 + if (optlen != sizeof(unsigned int)) 746 + goto error; 747 + ret = -EISCONN; 748 + if (rx->sk.sk_state != RXRPC_UNBOUND) 749 + goto error; 750 + ret = copy_safe_from_sockptr(&val, sizeof(val), 751 + optval, optlen); 752 + if (ret) 753 + goto error; 754 + ret = -EINVAL; 755 + if (val > 1) 756 + goto error; 757 + if (val) 758 + set_bit(RXRPC_SOCK_MANAGE_RESPONSE, &rx->flags); 759 + else 760 + clear_bit(RXRPC_SOCK_MANAGE_RESPONSE, &rx->flags); 753 761 goto success; 754 762 755 763 default: ··· 878 846 rx->calls = RB_ROOT; 879 847 880 848 spin_lock_init(&rx->incoming_lock); 849 + skb_queue_head_init(&rx->recvmsg_oobq); 850 + rx->pending_oobq = RB_ROOT; 881 851 INIT_LIST_HEAD(&rx->sock_calls); 882 852 INIT_LIST_HEAD(&rx->to_be_accepted); 883 853 INIT_LIST_HEAD(&rx->recvmsg_q); ··· 913 879 lock_sock(sk); 914 880 915 881 if (sk->sk_state < RXRPC_CLOSE) { 882 + spin_lock_irq(&rx->recvmsg_lock); 916 883 sk->sk_state = RXRPC_CLOSE; 917 884 sk->sk_shutdown = SHUTDOWN_MASK; 885 + spin_unlock_irq(&rx->recvmsg_lock); 918 886 } else { 919 887 ret = -ESHUTDOWN; 920 888 } ··· 928 892 } 929 893 930 894 /* 895 + * Purge the out-of-band queue. 896 + */ 897 + static void rxrpc_purge_oob_queue(struct sock *sk) 898 + { 899 + struct rxrpc_sock *rx = rxrpc_sk(sk); 900 + struct sk_buff *skb; 901 + 902 + while ((skb = skb_dequeue(&rx->recvmsg_oobq))) 903 + rxrpc_kernel_free_oob(skb); 904 + while (!RB_EMPTY_ROOT(&rx->pending_oobq)) { 905 + skb = rb_entry(rx->pending_oobq.rb_node, struct sk_buff, rbnode); 906 + rb_erase(&skb->rbnode, &rx->pending_oobq); 907 + rxrpc_kernel_free_oob(skb); 908 + } 909 + } 910 + 911 + /* 931 912 * RxRPC socket destructor 932 913 */ 933 914 static void rxrpc_sock_destructor(struct sock *sk) 934 915 { 935 916 _enter("%p", sk); 936 917 918 + rxrpc_purge_oob_queue(sk); 937 919 rxrpc_purge_queue(&sk->sk_receive_queue); 938 920 939 921 WARN_ON(refcount_read(&sk->sk_wmem_alloc)); ··· 990 936 break; 991 937 } 992 938 939 + spin_lock_irq(&rx->recvmsg_lock); 993 940 sk->sk_state = RXRPC_CLOSE; 941 + spin_unlock_irq(&rx->recvmsg_lock); 994 942 995 943 if (rx->local && rx->local->service == rx) { 996 944 write_lock(&rx->local->services_lock); ··· 1004 948 rxrpc_discard_prealloc(rx); 1005 949 rxrpc_release_calls_on_socket(rx); 1006 950 flush_workqueue(rxrpc_workqueue); 951 + rxrpc_purge_oob_queue(sk); 1007 952 rxrpc_purge_queue(&sk->sk_receive_queue); 1008 953 1009 954 rxrpc_unuse_local(rx->local, rxrpc_local_unuse_release_sock);
+76 -6
net/rxrpc/ar-internal.h
··· 31 31 struct rxrpc_connection; 32 32 struct rxrpc_txbuf; 33 33 struct rxrpc_txqueue; 34 + struct rxgk_context; 34 35 35 36 /* 36 37 * Mark applied to socket buffers in skb->mark. skb->priority is used ··· 40 39 enum rxrpc_skb_mark { 41 40 RXRPC_SKB_MARK_PACKET, /* Received packet */ 42 41 RXRPC_SKB_MARK_ERROR, /* Error notification */ 42 + RXRPC_SKB_MARK_CHALLENGE, /* Challenge notification */ 43 43 RXRPC_SKB_MARK_SERVICE_CONN_SECURED, /* Service connection response has been verified */ 44 44 RXRPC_SKB_MARK_REJECT_BUSY, /* Reject with BUSY */ 45 45 RXRPC_SKB_MARK_REJECT_ABORT, /* Reject with ABORT (code in skb->priority) */ ··· 148 146 struct rxrpc_sock { 149 147 /* WARNING: sk has to be the first member */ 150 148 struct sock sk; 151 - rxrpc_notify_new_call_t notify_new_call; /* Func to notify of new call */ 152 - rxrpc_discard_new_call_t discard_new_call; /* Func to discard a new call */ 149 + const struct rxrpc_kernel_ops *app_ops; /* Table of kernel app notification funcs */ 153 150 struct rxrpc_local *local; /* local endpoint */ 154 151 struct rxrpc_backlog *backlog; /* Preallocation for services */ 152 + struct sk_buff_head recvmsg_oobq; /* OOB messages for recvmsg to pick up */ 153 + struct rb_root pending_oobq; /* OOB messages awaiting userspace to respond to */ 154 + u64 oob_id_counter; /* OOB message ID counter */ 155 155 spinlock_t incoming_lock; /* Incoming call vs service shutdown lock */ 156 156 struct list_head sock_calls; /* List of calls owned by this socket */ 157 157 struct list_head to_be_accepted; /* calls awaiting acceptance */ ··· 164 160 struct rb_root calls; /* User ID -> call mapping */ 165 161 unsigned long flags; 166 162 #define RXRPC_SOCK_CONNECTED 0 /* connect_srx is set */ 163 + #define RXRPC_SOCK_MANAGE_RESPONSE 1 /* User wants to manage RESPONSE packets */ 167 164 rwlock_t call_lock; /* lock for calls */ 168 165 u32 min_sec_level; /* minimum security level */ 169 166 #define RXRPC_SECURITY_MAX RXRPC_SECURITY_ENCRYPT ··· 208 203 */ 209 204 struct rxrpc_skb_priv { 210 205 union { 211 - struct rxrpc_connection *conn; /* Connection referred to (poke packet) */ 206 + struct rxrpc_connection *poke_conn; /* Conn referred to (poke packet) */ 212 207 struct { 213 208 u16 offset; /* Offset of data */ 214 209 u16 len; /* Length of data */ ··· 222 217 u16 nr_acks; /* Number of acks+nacks */ 223 218 u8 reason; /* Reason for ack */ 224 219 } ack; 220 + struct { 221 + struct rxrpc_connection *conn; /* Connection referred to */ 222 + union { 223 + u32 rxkad_nonce; 224 + }; 225 + } chall; 226 + struct { 227 + rxrpc_serial_t challenge_serial; 228 + u32 kvno; 229 + u32 version; 230 + u16 len; 231 + u16 ticket_len; 232 + } resp; 225 233 }; 226 234 struct rxrpc_host_header hdr; /* RxRPC packet header from this packet */ 227 235 }; ··· 288 270 /* issue a challenge */ 289 271 int (*issue_challenge)(struct rxrpc_connection *); 290 272 273 + /* Validate a challenge packet */ 274 + bool (*validate_challenge)(struct rxrpc_connection *conn, 275 + struct sk_buff *skb); 276 + 277 + /* Fill out the cmsg for recvmsg() to pass on a challenge to userspace. 278 + * The security class gets to add additional information. 279 + */ 280 + int (*challenge_to_recvmsg)(struct rxrpc_connection *conn, 281 + struct sk_buff *challenge, 282 + struct msghdr *msg); 283 + 284 + /* Parse sendmsg() control message and respond to challenge. */ 285 + int (*sendmsg_respond_to_challenge)(struct sk_buff *challenge, 286 + struct msghdr *msg); 287 + 291 288 /* respond to a challenge */ 292 - int (*respond_to_challenge)(struct rxrpc_connection *, 293 - struct sk_buff *); 289 + int (*respond_to_challenge)(struct rxrpc_connection *conn, 290 + struct sk_buff *challenge); 294 291 295 292 /* verify a response */ 296 293 int (*verify_response)(struct rxrpc_connection *, ··· 313 280 314 281 /* clear connection security */ 315 282 void (*clear)(struct rxrpc_connection *); 283 + 284 + /* Default ticket -> key decoder */ 285 + int (*default_decode_ticket)(struct rxrpc_connection *conn, struct sk_buff *skb, 286 + unsigned int ticket_offset, unsigned int ticket_len, 287 + struct key **_key); 316 288 }; 317 289 318 290 /* ··· 564 526 struct rxrpc_crypt csum_iv; /* packet checksum base */ 565 527 u32 nonce; /* response re-use preventer */ 566 528 } rxkad; 529 + struct { 530 + struct rxgk_context *keys[4]; /* (Re-)keying buffer */ 531 + u64 start_time; /* The start time for TK derivation */ 532 + u8 nonce[20]; /* Response re-use preventer */ 533 + u32 enctype; /* Kerberos 5 encoding type */ 534 + u32 key_number; /* Current key number */ 535 + } rxgk; 567 536 }; 537 + rwlock_t security_use_lock; /* Security use/modification lock */ 538 + struct sk_buff *tx_response; /* Response packet to be transmitted */ 539 + 568 540 unsigned long flags; 569 541 unsigned long events; 570 542 unsigned long idle_timestamp; /* Time at which last became idle */ ··· 740 692 u32 call_id; /* call ID on connection */ 741 693 u32 cid; /* connection ID plus channel index */ 742 694 u32 security_level; /* Security level selected */ 695 + u32 security_enctype; /* Security-specific encoding type (or 0) */ 743 696 int debug_id; /* debug ID for printks */ 744 697 unsigned short rx_pkt_offset; /* Current recvmsg packet offset */ 745 698 unsigned short rx_pkt_len; /* Current recvmsg packet len */ ··· 916 867 unsigned short len; /* Amount of data in buffer */ 917 868 unsigned short space; /* Remaining data space */ 918 869 unsigned short offset; /* Offset of fill point */ 870 + unsigned short crypto_header; /* Size of crypto header */ 871 + unsigned short sec_header; /* Size of security header */ 919 872 unsigned short pkt_len; /* Size of packet content */ 920 873 unsigned short alloc_size; /* Amount of bufferage allocated */ 921 874 unsigned int flags; ··· 1052 1001 struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *, 1053 1002 struct rxrpc_conn_parameters *, 1054 1003 struct rxrpc_call_params *, gfp_t, 1055 - unsigned int); 1004 + unsigned int) 1005 + __releases(&rx->sk.sk_lock) 1006 + __acquires(&call->user_mutex); 1056 1007 void rxrpc_start_call_timer(struct rxrpc_call *call); 1057 1008 void rxrpc_incoming_call(struct rxrpc_sock *, struct rxrpc_call *, 1058 1009 struct sk_buff *); ··· 1251 1198 bool rxrpc_direct_abort(struct sk_buff *skb, enum rxrpc_abort_reason why, 1252 1199 s32 abort_code, int err); 1253 1200 int rxrpc_io_thread(void *data); 1201 + void rxrpc_post_response(struct rxrpc_connection *conn, struct sk_buff *skb); 1254 1202 static inline void rxrpc_wake_up_io_thread(struct rxrpc_local *local) 1255 1203 { 1204 + if (!local->io_thread) 1205 + return; 1256 1206 wake_up_process(READ_ONCE(local->io_thread)); 1257 1207 } 1258 1208 ··· 1345 1289 } 1346 1290 1347 1291 /* 1292 + * out_of_band.c 1293 + */ 1294 + void rxrpc_notify_socket_oob(struct rxrpc_call *call, struct sk_buff *skb); 1295 + void rxrpc_add_pending_oob(struct rxrpc_sock *rx, struct sk_buff *skb); 1296 + int rxrpc_sendmsg_oob(struct rxrpc_sock *rx, struct msghdr *msg, size_t len); 1297 + 1298 + /* 1348 1299 * output.c 1349 1300 */ 1301 + ssize_t do_udp_sendmsg(struct socket *socket, struct msghdr *msg, size_t len); 1350 1302 void rxrpc_send_ACK(struct rxrpc_call *call, u8 ack_reason, 1351 1303 rxrpc_serial_t serial, enum rxrpc_propose_ack_trace why); 1352 1304 void rxrpc_send_probe_for_pmtud(struct rxrpc_call *call); ··· 1363 1299 void rxrpc_send_conn_abort(struct rxrpc_connection *conn); 1364 1300 void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb); 1365 1301 void rxrpc_send_keepalive(struct rxrpc_peer *); 1302 + void rxrpc_send_response(struct rxrpc_connection *conn, struct sk_buff *skb); 1366 1303 1367 1304 /* 1368 1305 * peer_event.c ··· 1426 1361 ktime_t send_time, ktime_t resp_time); 1427 1362 ktime_t rxrpc_get_rto_backoff(struct rxrpc_call *call, bool retrans); 1428 1363 void rxrpc_call_init_rtt(struct rxrpc_call *call); 1364 + 1365 + /* 1366 + * rxgk.c 1367 + */ 1368 + extern const struct rxrpc_security rxgk_yfs; 1429 1369 1430 1370 /* 1431 1371 * rxkad.c
+16 -18
net/rxrpc/call_accept.c
··· 34 34 static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx, 35 35 struct rxrpc_backlog *b, 36 36 rxrpc_notify_rx_t notify_rx, 37 - rxrpc_user_attach_call_t user_attach_call, 38 37 unsigned long user_call_ID, gfp_t gfp, 39 38 unsigned int debug_id) 40 39 { ··· 122 123 123 124 call->user_call_ID = user_call_ID; 124 125 call->notify_rx = notify_rx; 125 - if (user_attach_call) { 126 + if (rx->app_ops && 127 + rx->app_ops->user_attach_call) { 126 128 rxrpc_get_call(call, rxrpc_call_get_kernel_service); 127 - user_attach_call(call, user_call_ID); 129 + rx->app_ops->user_attach_call(call, user_call_ID); 128 130 } 129 131 130 132 rxrpc_get_call(call, rxrpc_call_get_userid); ··· 219 219 while (CIRC_CNT(head, tail, size) > 0) { 220 220 struct rxrpc_call *call = b->call_backlog[tail]; 221 221 rcu_assign_pointer(call->socket, rx); 222 - if (rx->discard_new_call) { 222 + if (rx->app_ops && 223 + rx->app_ops->discard_new_call) { 223 224 _debug("discard %lx", call->user_call_ID); 224 - rx->discard_new_call(call, call->user_call_ID); 225 + rx->app_ops->discard_new_call(call, call->user_call_ID); 225 226 if (call->notify_rx) 226 227 call->notify_rx = rxrpc_dummy_notify; 227 228 rxrpc_put_call(call, rxrpc_call_put_kernel); ··· 388 387 rxrpc_incoming_call(rx, call, skb); 389 388 conn = call->conn; 390 389 391 - if (rx->notify_new_call) 392 - rx->notify_new_call(&rx->sk, call, call->user_call_ID); 390 + if (rx->app_ops && 391 + rx->app_ops->notify_new_call) 392 + rx->app_ops->notify_new_call(&rx->sk, call, call->user_call_ID); 393 393 394 394 spin_lock(&conn->state_lock); 395 395 if (conn->state == RXRPC_CONN_SERVICE_UNSECURED) { ··· 442 440 if (rx->sk.sk_state == RXRPC_CLOSE) 443 441 return -ESHUTDOWN; 444 442 445 - return rxrpc_service_prealloc_one(rx, b, NULL, NULL, user_call_ID, 446 - GFP_KERNEL, 443 + return rxrpc_service_prealloc_one(rx, b, NULL, user_call_ID, GFP_KERNEL, 447 444 atomic_inc_return(&rxrpc_debug_id)); 448 445 } 449 446 ··· 450 449 * rxrpc_kernel_charge_accept - Charge up socket with preallocated calls 451 450 * @sock: The socket on which to preallocate 452 451 * @notify_rx: Event notification function for the call 453 - * @user_attach_call: Func to attach call to user_call_ID 454 452 * @user_call_ID: The tag to attach to the preallocated call 455 453 * @gfp: The allocation conditions. 456 454 * @debug_id: The tracing debug ID. 457 455 * 458 - * Charge up the socket with preallocated calls, each with a user ID. A 459 - * function should be provided to effect the attachment from the user's side. 460 - * The user is given a ref to hold on the call. 456 + * Charge up the socket with preallocated calls, each with a user ID. The 457 + * ->user_attach_call() callback function should be provided to effect the 458 + * attachment from the user's side. The user is given a ref to hold on the 459 + * call. 461 460 * 462 461 * Note that the call may be come connected before this function returns. 463 462 */ 464 - int rxrpc_kernel_charge_accept(struct socket *sock, 465 - rxrpc_notify_rx_t notify_rx, 466 - rxrpc_user_attach_call_t user_attach_call, 463 + int rxrpc_kernel_charge_accept(struct socket *sock, rxrpc_notify_rx_t notify_rx, 467 464 unsigned long user_call_ID, gfp_t gfp, 468 465 unsigned int debug_id) 469 466 { ··· 471 472 if (sock->sk->sk_state == RXRPC_CLOSE) 472 473 return -ESHUTDOWN; 473 474 474 - return rxrpc_service_prealloc_one(rx, b, notify_rx, 475 - user_attach_call, user_call_ID, 475 + return rxrpc_service_prealloc_one(rx, b, notify_rx, user_call_ID, 476 476 gfp, debug_id); 477 477 } 478 478 EXPORT_SYMBOL(rxrpc_kernel_charge_accept);
+22 -2
net/rxrpc/call_object.c
··· 145 145 INIT_LIST_HEAD(&call->recvmsg_link); 146 146 INIT_LIST_HEAD(&call->sock_link); 147 147 INIT_LIST_HEAD(&call->attend_link); 148 - skb_queue_head_init(&call->rx_queue); 149 148 skb_queue_head_init(&call->recvmsg_queue); 149 + skb_queue_head_init(&call->rx_queue); 150 150 skb_queue_head_init(&call->rx_oos_queue); 151 151 init_waitqueue_head(&call->waitq); 152 152 spin_lock_init(&call->notify_lock); ··· 322 322 struct rxrpc_call_params *p, 323 323 gfp_t gfp, 324 324 unsigned int debug_id) 325 - __releases(&rx->sk.sk_lock.slock) 325 + __releases(&rx->sk.sk_lock) 326 326 __acquires(&call->user_mutex) 327 327 { 328 328 struct rxrpc_call *call, *xcall; ··· 760 760 atomic_dec(&rxnet->nr_calls); 761 761 wait_var_event(&rxnet->nr_calls, !atomic_read(&rxnet->nr_calls)); 762 762 } 763 + 764 + /** 765 + * rxrpc_kernel_query_call_security - Query call's security parameters 766 + * @call: The call to query 767 + * @_service_id: Where to return the service ID 768 + * @_enctype: Where to return the "encoding type" 769 + * 770 + * This queries the security parameters of a call, setting *@_service_id and 771 + * *@_enctype and returning the security class. 772 + * 773 + * Return: The security class protocol number. 774 + */ 775 + u8 rxrpc_kernel_query_call_security(struct rxrpc_call *call, 776 + u16 *_service_id, u32 *_enctype) 777 + { 778 + *_service_id = call->dest_srx.srx_service; 779 + *_enctype = call->security_enctype; 780 + return call->security_ix; 781 + } 782 + EXPORT_SYMBOL(rxrpc_kernel_query_call_security);
+126 -8
net/rxrpc/conn_event.c
··· 19 19 /* 20 20 * Set the completion state on an aborted connection. 21 21 */ 22 - static bool rxrpc_set_conn_aborted(struct rxrpc_connection *conn, struct sk_buff *skb, 22 + static bool rxrpc_set_conn_aborted(struct rxrpc_connection *conn, 23 23 s32 abort_code, int err, 24 24 enum rxrpc_call_completion compl) 25 25 { ··· 49 49 int rxrpc_abort_conn(struct rxrpc_connection *conn, struct sk_buff *skb, 50 50 s32 abort_code, int err, enum rxrpc_abort_reason why) 51 51 { 52 - struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 53 52 54 - if (rxrpc_set_conn_aborted(conn, skb, abort_code, err, 53 + u32 cid = conn->proto.cid, call = 0, seq = 0; 54 + 55 + if (skb) { 56 + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 57 + 58 + cid = sp->hdr.cid; 59 + call = sp->hdr.callNumber; 60 + seq = sp->hdr.seq; 61 + } 62 + 63 + if (rxrpc_set_conn_aborted(conn, abort_code, err, 55 64 RXRPC_CALL_LOCALLY_ABORTED)) { 56 - trace_rxrpc_abort(0, why, sp->hdr.cid, sp->hdr.callNumber, 57 - sp->hdr.seq, abort_code, err); 65 + trace_rxrpc_abort(0, why, cid, call, seq, abort_code, err); 58 66 rxrpc_poke_conn(conn, rxrpc_conn_get_poke_abort); 59 67 } 60 68 return -EPROTO; ··· 75 67 struct sk_buff *skb) 76 68 { 77 69 trace_rxrpc_rx_conn_abort(conn, skb); 78 - rxrpc_set_conn_aborted(conn, skb, skb->priority, -ECONNABORTED, 70 + rxrpc_set_conn_aborted(conn, skb->priority, -ECONNABORTED, 79 71 RXRPC_CALL_REMOTELY_ABORTED); 80 72 } 81 73 ··· 256 248 257 249 switch (sp->hdr.type) { 258 250 case RXRPC_PACKET_TYPE_CHALLENGE: 259 - return conn->security->respond_to_challenge(conn, skb); 251 + ret = conn->security->respond_to_challenge(conn, skb); 252 + sp->chall.conn = NULL; 253 + rxrpc_put_connection(conn, rxrpc_conn_put_challenge_input); 254 + return ret; 260 255 261 256 case RXRPC_PACKET_TYPE_RESPONSE: 262 257 ret = conn->security->verify_response(conn, skb); ··· 281 270 * we've already received the packet, put it on the 282 271 * front of the queue. 283 272 */ 284 - sp->conn = rxrpc_get_connection(conn, rxrpc_conn_get_poke_secured); 273 + sp->poke_conn = rxrpc_get_connection( 274 + conn, rxrpc_conn_get_poke_secured); 285 275 skb->mark = RXRPC_SKB_MARK_SERVICE_CONN_SECURED; 286 276 rxrpc_get_skb(skb, rxrpc_skb_get_conn_secured); 287 277 skb_queue_head(&conn->local->rx_queue, skb); ··· 404 392 } 405 393 406 394 /* 395 + * Post a CHALLENGE packet to the socket of one of a connection's calls so that 396 + * it can get application data to include in the packet, possibly querying 397 + * userspace. 398 + */ 399 + static bool rxrpc_post_challenge(struct rxrpc_connection *conn, 400 + struct sk_buff *skb) 401 + { 402 + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 403 + struct rxrpc_call *call = NULL; 404 + struct rxrpc_sock *rx; 405 + bool respond = false; 406 + 407 + sp->chall.conn = 408 + rxrpc_get_connection(conn, rxrpc_conn_get_challenge_input); 409 + 410 + if (!conn->security->challenge_to_recvmsg) { 411 + rxrpc_post_packet_to_conn(conn, skb); 412 + return true; 413 + } 414 + 415 + rcu_read_lock(); 416 + 417 + for (int i = 0; i < ARRAY_SIZE(conn->channels); i++) { 418 + if (conn->channels[i].call) { 419 + call = conn->channels[i].call; 420 + rx = rcu_dereference(call->socket); 421 + if (!rx) { 422 + call = NULL; 423 + continue; 424 + } 425 + 426 + respond = true; 427 + if (test_bit(RXRPC_SOCK_MANAGE_RESPONSE, &rx->flags)) 428 + break; 429 + call = NULL; 430 + } 431 + } 432 + 433 + if (!respond) { 434 + rcu_read_unlock(); 435 + rxrpc_put_connection(conn, rxrpc_conn_put_challenge_input); 436 + sp->chall.conn = NULL; 437 + return false; 438 + } 439 + 440 + if (call) 441 + rxrpc_notify_socket_oob(call, skb); 442 + rcu_read_unlock(); 443 + 444 + if (!call) 445 + rxrpc_post_packet_to_conn(conn, skb); 446 + return true; 447 + } 448 + 449 + /* 407 450 * Input a connection-level packet. 408 451 */ 409 452 bool rxrpc_input_conn_packet(struct rxrpc_connection *conn, struct sk_buff *skb) ··· 478 411 return true; 479 412 480 413 case RXRPC_PACKET_TYPE_CHALLENGE: 414 + rxrpc_see_skb(skb, rxrpc_skb_see_oob_challenge); 415 + if (rxrpc_is_conn_aborted(conn)) { 416 + if (conn->completion == RXRPC_CALL_LOCALLY_ABORTED) 417 + rxrpc_send_conn_abort(conn); 418 + return true; 419 + } 420 + if (!conn->security->validate_challenge(conn, skb)) 421 + return false; 422 + return rxrpc_post_challenge(conn, skb); 423 + 481 424 case RXRPC_PACKET_TYPE_RESPONSE: 482 425 if (rxrpc_is_conn_aborted(conn)) { 483 426 if (conn->completion == RXRPC_CALL_LOCALLY_ABORTED) ··· 513 436 if (test_and_clear_bit(RXRPC_CONN_EV_ABORT_CALLS, &conn->events)) 514 437 rxrpc_abort_calls(conn); 515 438 439 + if (conn->tx_response) { 440 + struct sk_buff *skb; 441 + 442 + spin_lock_irq(&conn->local->lock); 443 + skb = conn->tx_response; 444 + conn->tx_response = NULL; 445 + spin_unlock_irq(&conn->local->lock); 446 + 447 + if (conn->state != RXRPC_CONN_ABORTED) 448 + rxrpc_send_response(conn, skb); 449 + rxrpc_free_skb(skb, rxrpc_skb_put_response); 450 + } 451 + 516 452 if (skb) { 517 453 switch (skb->mark) { 518 454 case RXRPC_SKB_MARK_SERVICE_CONN_SECURED: ··· 541 451 /* Process delayed ACKs whose time has come. */ 542 452 if (conn->flags & RXRPC_CONN_FINAL_ACK_MASK) 543 453 rxrpc_process_delayed_final_acks(conn, false); 454 + } 455 + 456 + /* 457 + * Post a RESPONSE message to the I/O thread for transmission. 458 + */ 459 + void rxrpc_post_response(struct rxrpc_connection *conn, struct sk_buff *skb) 460 + { 461 + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 462 + struct rxrpc_local *local = conn->local; 463 + struct sk_buff *old; 464 + 465 + _enter("%x", sp->resp.challenge_serial); 466 + 467 + spin_lock_irq(&local->lock); 468 + old = conn->tx_response; 469 + if (old) { 470 + struct rxrpc_skb_priv *osp = rxrpc_skb(skb); 471 + 472 + /* Always go with the response to the most recent challenge. */ 473 + if (after(sp->resp.challenge_serial, osp->resp.challenge_serial)) 474 + conn->tx_response = old; 475 + else 476 + old = skb; 477 + } else { 478 + conn->tx_response = skb; 479 + } 480 + spin_unlock_irq(&local->lock); 481 + rxrpc_poke_conn(conn, rxrpc_conn_get_poke_response); 544 482 }
+2
net/rxrpc/conn_object.c
··· 73 73 skb_queue_head_init(&conn->rx_queue); 74 74 conn->rxnet = rxnet; 75 75 conn->security = &rxrpc_no_security; 76 + rwlock_init(&conn->security_use_lock); 76 77 spin_lock_init(&conn->state_lock); 77 78 conn->debug_id = atomic_inc_return(&rxrpc_debug_id); 78 79 conn->idle_timestamp = jiffies; ··· 330 329 } 331 330 332 331 rxrpc_purge_queue(&conn->rx_queue); 332 + rxrpc_free_skb(conn->tx_response, rxrpc_skb_put_response); 333 333 334 334 rxrpc_kill_client_conn(conn); 335 335
+10 -3
net/rxrpc/insecure.c
··· 42 42 { 43 43 } 44 44 45 - static int none_respond_to_challenge(struct rxrpc_connection *conn, 46 - struct sk_buff *skb) 45 + static bool none_validate_challenge(struct rxrpc_connection *conn, 46 + struct sk_buff *skb) 47 47 { 48 48 return rxrpc_abort_conn(conn, skb, RX_PROTOCOL_ERROR, -EPROTO, 49 49 rxrpc_eproto_rxnull_challenge); 50 + } 51 + 52 + static int none_sendmsg_respond_to_challenge(struct sk_buff *challenge, 53 + struct msghdr *msg) 54 + { 55 + return -EINVAL; 50 56 } 51 57 52 58 static int none_verify_response(struct rxrpc_connection *conn, ··· 88 82 .alloc_txbuf = none_alloc_txbuf, 89 83 .secure_packet = none_secure_packet, 90 84 .verify_packet = none_verify_packet, 91 - .respond_to_challenge = none_respond_to_challenge, 85 + .validate_challenge = none_validate_challenge, 86 + .sendmsg_respond_to_challenge = none_sendmsg_respond_to_challenge, 92 87 .verify_response = none_verify_response, 93 88 .clear = none_clear, 94 89 };
+7 -5
net/rxrpc/io_thread.c
··· 489 489 rxrpc_free_skb(skb, rxrpc_skb_put_error_report); 490 490 break; 491 491 case RXRPC_SKB_MARK_SERVICE_CONN_SECURED: 492 - rxrpc_input_conn_event(sp->conn, skb); 493 - rxrpc_put_connection(sp->conn, rxrpc_conn_put_poke); 492 + rxrpc_input_conn_event(sp->poke_conn, skb); 493 + rxrpc_put_connection(sp->poke_conn, rxrpc_conn_put_poke); 494 494 rxrpc_free_skb(skb, rxrpc_skb_put_conn_secured); 495 495 break; 496 496 default: ··· 501 501 } 502 502 503 503 /* Deal with connections that want immediate attention. */ 504 - spin_lock_irq(&local->lock); 505 - list_splice_tail_init(&local->conn_attend_q, &conn_attend_q); 506 - spin_unlock_irq(&local->lock); 504 + if (!list_empty_careful(&local->conn_attend_q)) { 505 + spin_lock_irq(&local->lock); 506 + list_splice_tail_init(&local->conn_attend_q, &conn_attend_q); 507 + spin_unlock_irq(&local->lock); 508 + } 507 509 508 510 while ((conn = list_first_entry_or_null(&conn_attend_q, 509 511 struct rxrpc_connection,
+187
net/rxrpc/key.c
··· 129 129 return 0; 130 130 } 131 131 132 + static u64 xdr_dec64(const __be32 *xdr) 133 + { 134 + return (u64)ntohl(xdr[0]) << 32 | (u64)ntohl(xdr[1]); 135 + } 136 + 137 + static time64_t rxrpc_s64_to_time64(s64 time_in_100ns) 138 + { 139 + bool neg = false; 140 + u64 tmp = time_in_100ns; 141 + 142 + if (time_in_100ns < 0) { 143 + tmp = -time_in_100ns; 144 + neg = true; 145 + } 146 + do_div(tmp, 10000000); 147 + return neg ? -tmp : tmp; 148 + } 149 + 150 + /* 151 + * Parse a YFS-RxGK type XDR format token 152 + * - the caller guarantees we have at least 4 words 153 + * 154 + * struct token_rxgk { 155 + * opr_time begintime; 156 + * opr_time endtime; 157 + * afs_int64 level; 158 + * afs_int64 lifetime; 159 + * afs_int64 bytelife; 160 + * afs_int64 enctype; 161 + * opaque key<>; 162 + * opaque ticket<>; 163 + * }; 164 + */ 165 + static int rxrpc_preparse_xdr_yfs_rxgk(struct key_preparsed_payload *prep, 166 + size_t datalen, 167 + const __be32 *xdr, unsigned int toklen) 168 + { 169 + struct rxrpc_key_token *token, **pptoken; 170 + time64_t expiry; 171 + size_t plen; 172 + const __be32 *ticket, *key; 173 + s64 tmp; 174 + u32 tktlen, keylen; 175 + 176 + _enter(",{%x,%x,%x,%x},%x", 177 + ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), 178 + toklen); 179 + 180 + if (6 * 2 + 2 > toklen / 4) 181 + goto reject; 182 + 183 + key = xdr + (6 * 2 + 1); 184 + keylen = ntohl(key[-1]); 185 + _debug("keylen: %x", keylen); 186 + keylen = round_up(keylen, 4); 187 + if ((6 * 2 + 2) * 4 + keylen > toklen) 188 + goto reject; 189 + 190 + ticket = xdr + (6 * 2 + 1 + (keylen / 4) + 1); 191 + tktlen = ntohl(ticket[-1]); 192 + _debug("tktlen: %x", tktlen); 193 + tktlen = round_up(tktlen, 4); 194 + if ((6 * 2 + 2) * 4 + keylen + tktlen != toklen) { 195 + kleave(" = -EKEYREJECTED [%x!=%x, %x,%x]", 196 + (6 * 2 + 2) * 4 + keylen + tktlen, toklen, 197 + keylen, tktlen); 198 + goto reject; 199 + } 200 + 201 + plen = sizeof(*token) + sizeof(*token->rxgk) + tktlen + keylen; 202 + prep->quotalen = datalen + plen; 203 + 204 + plen -= sizeof(*token); 205 + token = kzalloc(sizeof(*token), GFP_KERNEL); 206 + if (!token) 207 + goto nomem; 208 + 209 + token->rxgk = kzalloc(sizeof(*token->rxgk) + keylen, GFP_KERNEL); 210 + if (!token->rxgk) 211 + goto nomem_token; 212 + 213 + token->security_index = RXRPC_SECURITY_YFS_RXGK; 214 + token->rxgk->begintime = xdr_dec64(xdr + 0 * 2); 215 + token->rxgk->endtime = xdr_dec64(xdr + 1 * 2); 216 + token->rxgk->level = tmp = xdr_dec64(xdr + 2 * 2); 217 + if (tmp < -1LL || tmp > RXRPC_SECURITY_ENCRYPT) 218 + goto reject_token; 219 + token->rxgk->lifetime = xdr_dec64(xdr + 3 * 2); 220 + token->rxgk->bytelife = xdr_dec64(xdr + 4 * 2); 221 + token->rxgk->enctype = tmp = xdr_dec64(xdr + 5 * 2); 222 + if (tmp < 0 || tmp > UINT_MAX) 223 + goto reject_token; 224 + token->rxgk->key.len = ntohl(key[-1]); 225 + token->rxgk->key.data = token->rxgk->_key; 226 + token->rxgk->ticket.len = ntohl(ticket[-1]); 227 + 228 + if (token->rxgk->endtime != 0) { 229 + expiry = rxrpc_s64_to_time64(token->rxgk->endtime); 230 + if (expiry < 0) 231 + goto expired; 232 + if (expiry < prep->expiry) 233 + prep->expiry = expiry; 234 + } 235 + 236 + memcpy(token->rxgk->key.data, key, token->rxgk->key.len); 237 + 238 + /* Pad the ticket so that we can use it directly in XDR */ 239 + token->rxgk->ticket.data = kzalloc(round_up(token->rxgk->ticket.len, 4), 240 + GFP_KERNEL); 241 + if (!token->rxgk->ticket.data) 242 + goto nomem_yrxgk; 243 + memcpy(token->rxgk->ticket.data, ticket, token->rxgk->ticket.len); 244 + 245 + _debug("SCIX: %u", token->security_index); 246 + _debug("EXPY: %llx", token->rxgk->endtime); 247 + _debug("LIFE: %llx", token->rxgk->lifetime); 248 + _debug("BYTE: %llx", token->rxgk->bytelife); 249 + _debug("ENC : %u", token->rxgk->enctype); 250 + _debug("LEVL: %u", token->rxgk->level); 251 + _debug("KLEN: %u", token->rxgk->key.len); 252 + _debug("TLEN: %u", token->rxgk->ticket.len); 253 + _debug("KEY0: %*phN", token->rxgk->key.len, token->rxgk->key.data); 254 + _debug("TICK: %*phN", 255 + min_t(u32, token->rxgk->ticket.len, 32), token->rxgk->ticket.data); 256 + 257 + /* count the number of tokens attached */ 258 + prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1); 259 + 260 + /* attach the data */ 261 + for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0]; 262 + *pptoken; 263 + pptoken = &(*pptoken)->next) 264 + continue; 265 + *pptoken = token; 266 + 267 + _leave(" = 0"); 268 + return 0; 269 + 270 + nomem_yrxgk: 271 + kfree(token->rxgk); 272 + nomem_token: 273 + kfree(token); 274 + nomem: 275 + return -ENOMEM; 276 + reject_token: 277 + kfree(token); 278 + reject: 279 + return -EKEYREJECTED; 280 + expired: 281 + kfree(token->rxgk); 282 + kfree(token); 283 + return -EKEYEXPIRED; 284 + } 285 + 132 286 /* 133 287 * attempt to parse the data as the XDR format 134 288 * - the caller guarantees we have more than 7 words ··· 381 227 switch (sec_ix) { 382 228 case RXRPC_SECURITY_RXKAD: 383 229 ret2 = rxrpc_preparse_xdr_rxkad(prep, datalen, token, toklen); 230 + break; 231 + case RXRPC_SECURITY_YFS_RXGK: 232 + ret2 = rxrpc_preparse_xdr_yfs_rxgk(prep, datalen, token, toklen); 384 233 break; 385 234 default: 386 235 ret2 = -EPROTONOSUPPORT; ··· 547 390 case RXRPC_SECURITY_RXKAD: 548 391 kfree(token->kad); 549 392 break; 393 + case RXRPC_SECURITY_YFS_RXGK: 394 + kfree(token->rxgk->ticket.data); 395 + kfree(token->rxgk); 396 + break; 550 397 default: 551 398 pr_err("Unknown token type %x on rxrpc key\n", 552 399 token->security_index); ··· 593 432 switch (token->security_index) { 594 433 case RXRPC_SECURITY_RXKAD: 595 434 seq_puts(m, "ka"); 435 + break; 436 + case RXRPC_SECURITY_YFS_RXGK: 437 + seq_puts(m, "ygk"); 596 438 break; 597 439 default: /* we have a ticket we can't encode */ 598 440 seq_printf(m, "%u", token->security_index); ··· 695 531 * 696 532 * Generate a null RxRPC key that can be used to indicate anonymous security is 697 533 * required for a particular domain. 534 + * 535 + * Return: The new key or a negative error code. 698 536 */ 699 537 struct key *rxrpc_get_null_key(const char *keyname) 700 538 { ··· 759 593 * end, primary, tktlen */ 760 594 if (!token->no_leak_key) 761 595 toksize += RND(token->kad->ticket_len); 596 + break; 597 + 598 + case RXRPC_SECURITY_YFS_RXGK: 599 + toksize += 6 * 8 + 2 * 4; 600 + if (!token->no_leak_key) 601 + toksize += RND(token->rxgk->key.len); 602 + toksize += RND(token->rxgk->ticket.len); 762 603 break; 763 604 764 605 default: /* we have a ticket we can't encode */ ··· 845 672 ENCODE(0); 846 673 else 847 674 ENCODE_DATA(token->kad->ticket_len, token->kad->ticket); 675 + break; 676 + 677 + case RXRPC_SECURITY_YFS_RXGK: 678 + ENCODE64(token->rxgk->begintime); 679 + ENCODE64(token->rxgk->endtime); 680 + ENCODE64(token->rxgk->level); 681 + ENCODE64(token->rxgk->lifetime); 682 + ENCODE64(token->rxgk->bytelife); 683 + ENCODE64(token->rxgk->enctype); 684 + if (token->no_leak_key) 685 + ENCODE(0); 686 + else 687 + ENCODE_DATA(token->rxgk->key.len, token->rxgk->key.data); 688 + ENCODE_DATA(token->rxgk->ticket.len, token->rxgk->ticket.data); 848 689 break; 849 690 850 691 default:
+379
net/rxrpc/oob.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* Out of band message handling (e.g. challenge-response) 3 + * 4 + * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved. 5 + * Written by David Howells (dhowells@redhat.com) 6 + */ 7 + 8 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 + 10 + #include <linux/net.h> 11 + #include <linux/gfp.h> 12 + #include <linux/skbuff.h> 13 + #include <linux/export.h> 14 + #include <linux/sched/signal.h> 15 + #include <net/sock.h> 16 + #include <net/af_rxrpc.h> 17 + #include "ar-internal.h" 18 + 19 + enum rxrpc_oob_command { 20 + RXRPC_OOB_CMD_UNSET, 21 + RXRPC_OOB_CMD_RESPOND, 22 + } __mode(byte); 23 + 24 + struct rxrpc_oob_params { 25 + u64 oob_id; /* ID number of message if reply */ 26 + s32 abort_code; 27 + enum rxrpc_oob_command command; 28 + bool have_oob_id:1; 29 + }; 30 + 31 + /* 32 + * Post an out-of-band message for attention by the socket or kernel service 33 + * associated with a reference call. 34 + */ 35 + void rxrpc_notify_socket_oob(struct rxrpc_call *call, struct sk_buff *skb) 36 + { 37 + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 38 + struct rxrpc_sock *rx; 39 + struct sock *sk; 40 + 41 + rcu_read_lock(); 42 + 43 + rx = rcu_dereference(call->socket); 44 + if (rx) { 45 + sk = &rx->sk; 46 + spin_lock_irq(&rx->recvmsg_lock); 47 + 48 + if (sk->sk_state < RXRPC_CLOSE) { 49 + skb->skb_mstamp_ns = rx->oob_id_counter++; 50 + rxrpc_get_skb(skb, rxrpc_skb_get_post_oob); 51 + skb_queue_tail(&rx->recvmsg_oobq, skb); 52 + 53 + trace_rxrpc_notify_socket(call->debug_id, sp->hdr.serial); 54 + if (rx->app_ops) 55 + rx->app_ops->notify_oob(sk, skb); 56 + } 57 + 58 + spin_unlock_irq(&rx->recvmsg_lock); 59 + if (!rx->app_ops && !sock_flag(sk, SOCK_DEAD)) 60 + sk->sk_data_ready(sk); 61 + } 62 + 63 + rcu_read_unlock(); 64 + } 65 + 66 + /* 67 + * Locate the OOB message to respond to by its ID. 68 + */ 69 + static struct sk_buff *rxrpc_find_pending_oob(struct rxrpc_sock *rx, u64 oob_id) 70 + { 71 + struct rb_node *p; 72 + struct sk_buff *skb; 73 + 74 + p = rx->pending_oobq.rb_node; 75 + while (p) { 76 + skb = rb_entry(p, struct sk_buff, rbnode); 77 + 78 + if (oob_id < skb->skb_mstamp_ns) 79 + p = p->rb_left; 80 + else if (oob_id > skb->skb_mstamp_ns) 81 + p = p->rb_right; 82 + else 83 + return skb; 84 + } 85 + 86 + return NULL; 87 + } 88 + 89 + /* 90 + * Add an OOB message into the pending-response set. We always assign the next 91 + * value from a 64-bit counter to the oob_id, so just assume we're always going 92 + * to be on the right-hand edge of the tree and that the counter won't wrap. 93 + * The tree is also given a ref to the message. 94 + */ 95 + void rxrpc_add_pending_oob(struct rxrpc_sock *rx, struct sk_buff *skb) 96 + { 97 + struct rb_node **pp = &rx->pending_oobq.rb_node, *p = NULL; 98 + 99 + while (*pp) { 100 + p = *pp; 101 + pp = &(*pp)->rb_right; 102 + } 103 + 104 + rb_link_node(&skb->rbnode, p, pp); 105 + rb_insert_color(&skb->rbnode, &rx->pending_oobq); 106 + } 107 + 108 + /* 109 + * Extract control messages from the sendmsg() control buffer. 110 + */ 111 + static int rxrpc_sendmsg_oob_cmsg(struct msghdr *msg, struct rxrpc_oob_params *p) 112 + { 113 + struct cmsghdr *cmsg; 114 + int len; 115 + 116 + if (msg->msg_controllen == 0) 117 + return -EINVAL; 118 + 119 + for_each_cmsghdr(cmsg, msg) { 120 + if (!CMSG_OK(msg, cmsg)) 121 + return -EINVAL; 122 + 123 + len = cmsg->cmsg_len - sizeof(struct cmsghdr); 124 + _debug("CMSG %d, %d, %d", 125 + cmsg->cmsg_level, cmsg->cmsg_type, len); 126 + 127 + if (cmsg->cmsg_level != SOL_RXRPC) 128 + continue; 129 + 130 + switch (cmsg->cmsg_type) { 131 + case RXRPC_OOB_ID: 132 + if (len != sizeof(p->oob_id) || p->have_oob_id) 133 + return -EINVAL; 134 + memcpy(&p->oob_id, CMSG_DATA(cmsg), sizeof(p->oob_id)); 135 + p->have_oob_id = true; 136 + break; 137 + case RXRPC_RESPOND: 138 + if (p->command != RXRPC_OOB_CMD_UNSET) 139 + return -EINVAL; 140 + p->command = RXRPC_OOB_CMD_RESPOND; 141 + break; 142 + case RXRPC_ABORT: 143 + if (len != sizeof(p->abort_code) || p->abort_code) 144 + return -EINVAL; 145 + memcpy(&p->abort_code, CMSG_DATA(cmsg), sizeof(p->abort_code)); 146 + if (p->abort_code == 0) 147 + return -EINVAL; 148 + break; 149 + case RXRPC_RESP_RXGK_APPDATA: 150 + if (p->command != RXRPC_OOB_CMD_RESPOND) 151 + return -EINVAL; 152 + break; 153 + default: 154 + return -EINVAL; 155 + } 156 + } 157 + 158 + switch (p->command) { 159 + case RXRPC_OOB_CMD_RESPOND: 160 + if (!p->have_oob_id) 161 + return -EBADSLT; 162 + break; 163 + default: 164 + return -EINVAL; 165 + } 166 + 167 + return 0; 168 + } 169 + 170 + /* 171 + * Allow userspace to respond to an OOB using sendmsg(). 172 + */ 173 + static int rxrpc_respond_to_oob(struct rxrpc_sock *rx, 174 + struct rxrpc_oob_params *p, 175 + struct msghdr *msg) 176 + { 177 + struct rxrpc_connection *conn; 178 + struct rxrpc_skb_priv *sp; 179 + struct sk_buff *skb; 180 + int ret; 181 + 182 + skb = rxrpc_find_pending_oob(rx, p->oob_id); 183 + if (skb) 184 + rb_erase(&skb->rbnode, &rx->pending_oobq); 185 + release_sock(&rx->sk); 186 + if (!skb) 187 + return -EBADSLT; 188 + 189 + sp = rxrpc_skb(skb); 190 + 191 + switch (p->command) { 192 + case RXRPC_OOB_CMD_RESPOND: 193 + ret = -EPROTO; 194 + if (skb->mark != RXRPC_OOB_CHALLENGE) 195 + break; 196 + conn = sp->chall.conn; 197 + ret = -EOPNOTSUPP; 198 + if (!conn->security->sendmsg_respond_to_challenge) 199 + break; 200 + if (p->abort_code) { 201 + rxrpc_abort_conn(conn, NULL, p->abort_code, -ECONNABORTED, 202 + rxrpc_abort_response_sendmsg); 203 + ret = 0; 204 + } else { 205 + ret = conn->security->sendmsg_respond_to_challenge(skb, msg); 206 + } 207 + break; 208 + default: 209 + ret = -EINVAL; 210 + break; 211 + } 212 + 213 + rxrpc_free_skb(skb, rxrpc_skb_put_oob); 214 + return ret; 215 + } 216 + 217 + /* 218 + * Send an out-of-band message or respond to a received out-of-band message. 219 + * - caller gives us the socket lock 220 + * - the socket may be either a client socket or a server socket 221 + */ 222 + int rxrpc_sendmsg_oob(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) 223 + { 224 + struct rxrpc_oob_params p = {}; 225 + int ret; 226 + 227 + _enter(""); 228 + 229 + ret = rxrpc_sendmsg_oob_cmsg(msg, &p); 230 + if (ret < 0) 231 + goto error_release_sock; 232 + 233 + if (p.have_oob_id) 234 + return rxrpc_respond_to_oob(rx, &p, msg); 235 + 236 + release_sock(&rx->sk); 237 + 238 + switch (p.command) { 239 + default: 240 + ret = -EINVAL; 241 + break; 242 + } 243 + 244 + _leave(" = %d", ret); 245 + return ret; 246 + 247 + error_release_sock: 248 + release_sock(&rx->sk); 249 + return ret; 250 + } 251 + 252 + /** 253 + * rxrpc_kernel_query_oob - Query the parameters of an out-of-band message 254 + * @oob: The message to query 255 + * @_peer: Where to return the peer record 256 + * @_peer_appdata: The application data attached to a peer record 257 + * 258 + * Extract useful parameters from an out-of-band message. The source peer 259 + * parameters are returned through the argument list and the message type is 260 + * returned. 261 + * 262 + * Return: 263 + * * %RXRPC_OOB_CHALLENGE - Challenge wanting a response. 264 + */ 265 + enum rxrpc_oob_type rxrpc_kernel_query_oob(struct sk_buff *oob, 266 + struct rxrpc_peer **_peer, 267 + unsigned long *_peer_appdata) 268 + { 269 + struct rxrpc_skb_priv *sp = rxrpc_skb(oob); 270 + enum rxrpc_oob_type type = oob->mark; 271 + 272 + switch (type) { 273 + case RXRPC_OOB_CHALLENGE: 274 + *_peer = sp->chall.conn->peer; 275 + *_peer_appdata = sp->chall.conn->peer->app_data; 276 + break; 277 + default: 278 + WARN_ON_ONCE(1); 279 + *_peer = NULL; 280 + *_peer_appdata = 0; 281 + break; 282 + } 283 + 284 + return type; 285 + } 286 + EXPORT_SYMBOL(rxrpc_kernel_query_oob); 287 + 288 + /** 289 + * rxrpc_kernel_dequeue_oob - Dequeue and return the front OOB message 290 + * @sock: The socket to query 291 + * @_type: Where to return the message type 292 + * 293 + * Dequeue the front OOB message, if there is one, and return it and 294 + * its type. 295 + * 296 + * Return: The sk_buff representing the OOB message or %NULL if the queue was 297 + * empty. 298 + */ 299 + struct sk_buff *rxrpc_kernel_dequeue_oob(struct socket *sock, 300 + enum rxrpc_oob_type *_type) 301 + { 302 + struct rxrpc_sock *rx = rxrpc_sk(sock->sk); 303 + struct sk_buff *oob; 304 + 305 + oob = skb_dequeue(&rx->recvmsg_oobq); 306 + if (oob) 307 + *_type = oob->mark; 308 + return oob; 309 + } 310 + EXPORT_SYMBOL(rxrpc_kernel_dequeue_oob); 311 + 312 + /** 313 + * rxrpc_kernel_free_oob - Free an out-of-band message 314 + * @oob: The OOB message to free 315 + * 316 + * Free an OOB message along with any resources it holds. 317 + */ 318 + void rxrpc_kernel_free_oob(struct sk_buff *oob) 319 + { 320 + struct rxrpc_skb_priv *sp = rxrpc_skb(oob); 321 + 322 + switch (oob->mark) { 323 + case RXRPC_OOB_CHALLENGE: 324 + rxrpc_put_connection(sp->chall.conn, rxrpc_conn_put_oob); 325 + break; 326 + } 327 + 328 + rxrpc_free_skb(oob, rxrpc_skb_put_purge_oob); 329 + } 330 + EXPORT_SYMBOL(rxrpc_kernel_free_oob); 331 + 332 + /** 333 + * rxrpc_kernel_query_challenge - Query the parameters of a challenge 334 + * @challenge: The challenge to query 335 + * @_peer: Where to return the peer record 336 + * @_peer_appdata: The application data attached to a peer record 337 + * @_service_id: Where to return the connection service ID 338 + * @_security_index: Where to return the connection security index 339 + * 340 + * Extract useful parameters from a CHALLENGE message. 341 + */ 342 + void rxrpc_kernel_query_challenge(struct sk_buff *challenge, 343 + struct rxrpc_peer **_peer, 344 + unsigned long *_peer_appdata, 345 + u16 *_service_id, u8 *_security_index) 346 + { 347 + struct rxrpc_skb_priv *sp = rxrpc_skb(challenge); 348 + 349 + *_peer = sp->chall.conn->peer; 350 + *_peer_appdata = sp->chall.conn->peer->app_data; 351 + *_service_id = sp->hdr.serviceId; 352 + *_security_index = sp->hdr.securityIndex; 353 + } 354 + EXPORT_SYMBOL(rxrpc_kernel_query_challenge); 355 + 356 + /** 357 + * rxrpc_kernel_reject_challenge - Allow a kernel service to reject a challenge 358 + * @challenge: The challenge to be rejected 359 + * @abort_code: The abort code to stick into the ABORT packet 360 + * @error: Local error value 361 + * @why: Indication as to why. 362 + * 363 + * Allow a kernel service to reject a challenge by aborting the connection if 364 + * it's still in an abortable state. The error is returned so this function 365 + * can be used with a return statement. 366 + * 367 + * Return: The %error parameter. 368 + */ 369 + int rxrpc_kernel_reject_challenge(struct sk_buff *challenge, u32 abort_code, 370 + int error, enum rxrpc_abort_reason why) 371 + { 372 + struct rxrpc_skb_priv *sp = rxrpc_skb(challenge); 373 + 374 + _enter("{%x},%d,%d,%u", sp->hdr.serial, abort_code, error, why); 375 + 376 + rxrpc_abort_conn(sp->chall.conn, NULL, abort_code, error, why); 377 + return error; 378 + } 379 + EXPORT_SYMBOL(rxrpc_kernel_reject_challenge);
+59 -1
net/rxrpc/output.c
··· 18 18 19 19 extern int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len); 20 20 21 - static ssize_t do_udp_sendmsg(struct socket *socket, struct msghdr *msg, size_t len) 21 + ssize_t do_udp_sendmsg(struct socket *socket, struct msghdr *msg, size_t len) 22 22 { 23 23 struct sockaddr *sa = msg->msg_name; 24 24 struct sock *sk = socket->sk; ··· 915 915 916 916 peer->last_tx_at = ktime_get_seconds(); 917 917 _leave(""); 918 + } 919 + 920 + /* 921 + * Send a RESPONSE message. 922 + */ 923 + void rxrpc_send_response(struct rxrpc_connection *conn, struct sk_buff *response) 924 + { 925 + struct rxrpc_skb_priv *sp = rxrpc_skb(response); 926 + struct scatterlist sg[16]; 927 + struct bio_vec bvec[16]; 928 + struct msghdr msg; 929 + size_t len = sp->resp.len; 930 + __be32 wserial; 931 + u32 serial = 0; 932 + int ret, nr_sg; 933 + 934 + _enter("C=%x,%x", conn->debug_id, sp->resp.challenge_serial); 935 + 936 + sg_init_table(sg, ARRAY_SIZE(sg)); 937 + ret = skb_to_sgvec(response, sg, 0, len); 938 + if (ret < 0) 939 + goto fail; 940 + nr_sg = ret; 941 + 942 + for (int i = 0; i < nr_sg; i++) 943 + bvec_set_page(&bvec[i], sg_page(&sg[i]), sg[i].length, sg[i].offset); 944 + 945 + iov_iter_bvec(&msg.msg_iter, WRITE, bvec, nr_sg, len); 946 + 947 + msg.msg_name = &conn->peer->srx.transport; 948 + msg.msg_namelen = conn->peer->srx.transport_len; 949 + msg.msg_control = NULL; 950 + msg.msg_controllen = 0; 951 + msg.msg_flags = MSG_SPLICE_PAGES; 952 + 953 + serial = rxrpc_get_next_serials(conn, 1); 954 + wserial = htonl(serial); 955 + 956 + trace_rxrpc_tx_response(conn, serial, sp); 957 + 958 + ret = skb_store_bits(response, offsetof(struct rxrpc_wire_header, serial), 959 + &wserial, sizeof(wserial)); 960 + if (ret < 0) 961 + goto fail; 962 + 963 + rxrpc_local_dont_fragment(conn->local, false); 964 + 965 + ret = do_udp_sendmsg(conn->local->socket, &msg, len); 966 + if (ret < 0) 967 + goto fail; 968 + 969 + conn->peer->last_tx_at = ktime_get_seconds(); 970 + return; 971 + 972 + fail: 973 + trace_rxrpc_tx_fail(conn->debug_id, serial, ret, 974 + rxrpc_tx_point_response); 975 + kleave(" = %d", ret); 918 976 }
+18 -4
net/rxrpc/peer_object.c
··· 475 475 * @call: The call to query 476 476 * 477 477 * Get a record for the remote peer in a call. 478 + * 479 + * Return: The call's peer record. 478 480 */ 479 481 struct rxrpc_peer *rxrpc_kernel_get_call_peer(struct socket *sock, struct rxrpc_call *call) 480 482 { ··· 488 486 * rxrpc_kernel_get_srtt - Get a call's peer smoothed RTT 489 487 * @peer: The peer to query 490 488 * 491 - * Get the call's peer smoothed RTT in uS or UINT_MAX if we have no samples. 489 + * Get the call's peer smoothed RTT. 490 + * 491 + * Return: The RTT in uS or %UINT_MAX if we have no samples. 492 492 */ 493 493 unsigned int rxrpc_kernel_get_srtt(const struct rxrpc_peer *peer) 494 494 { ··· 503 499 * @peer: The peer to query 504 500 * 505 501 * Get a pointer to the address from a peer record. The caller is responsible 506 - * for making sure that the address is not deallocated. 502 + * for making sure that the address is not deallocated. A fake address will be 503 + * substituted if %peer in NULL. 504 + * 505 + * Return: The rxrpc address record or a fake record. 507 506 */ 508 507 const struct sockaddr_rxrpc *rxrpc_kernel_remote_srx(const struct rxrpc_peer *peer) 509 508 { ··· 519 512 * @peer: The peer to query 520 513 * 521 514 * Get a pointer to the transport address from a peer record. The caller is 522 - * responsible for making sure that the address is not deallocated. 515 + * responsible for making sure that the address is not deallocated. A fake 516 + * address will be substituted if %peer in NULL. 517 + * 518 + * Return: The transport address record or a fake record. 523 519 */ 524 520 const struct sockaddr *rxrpc_kernel_remote_addr(const struct rxrpc_peer *peer) 525 521 { ··· 537 527 * @app_data: The data to set 538 528 * 539 529 * Set the app-specific data on a peer. AF_RXRPC makes no effort to retain 540 - * anything the data might refer to. The previous app_data is returned. 530 + * anything the data might refer to. 531 + * 532 + * Return: The previous app_data. 541 533 */ 542 534 unsigned long rxrpc_kernel_set_peer_data(struct rxrpc_peer *peer, unsigned long app_data) 543 535 { ··· 552 540 * @peer: The peer to query 553 541 * 554 542 * Retrieve the app-specific data from a peer. 543 + * 544 + * Return: The peer's app data. 555 545 */ 556 546 unsigned long rxrpc_kernel_get_peer_data(const struct rxrpc_peer *peer) 557 547 {
+20
net/rxrpc/protocol.h
··· 181 181 __be32 ticket_len; /* Kerberos ticket length */ 182 182 } __packed; 183 183 184 + /* 185 + * GSSAPI security type-4 and type-6 data header. 186 + */ 187 + struct rxgk_header { 188 + __be32 epoch; 189 + __be32 cid; 190 + __be32 call_number; 191 + __be32 seq; 192 + __be32 sec_index; 193 + __be32 data_len; 194 + } __packed; 195 + 196 + /* 197 + * GSSAPI security type-4 and type-6 response packet header. 198 + */ 199 + struct rxgk_response { 200 + __be64 start_time; 201 + __be32 token_len; 202 + } __packed; 203 + 184 204 #endif /* _LINUX_RXRPC_PACKET_H */
+108 -24
net/rxrpc/recvmsg.c
··· 155 155 } 156 156 157 157 /* 158 + * Transcribe a call's user ID to a control message. 159 + */ 160 + static int rxrpc_recvmsg_user_id(struct rxrpc_call *call, struct msghdr *msg, 161 + int flags) 162 + { 163 + if (!test_bit(RXRPC_CALL_HAS_USERID, &call->flags)) 164 + return 0; 165 + 166 + if (flags & MSG_CMSG_COMPAT) { 167 + unsigned int id32 = call->user_call_ID; 168 + 169 + return put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID, 170 + sizeof(unsigned int), &id32); 171 + } else { 172 + unsigned long idl = call->user_call_ID; 173 + 174 + return put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID, 175 + sizeof(unsigned long), &idl); 176 + } 177 + } 178 + 179 + /* 180 + * Deal with a CHALLENGE packet. 181 + */ 182 + static int rxrpc_recvmsg_challenge(struct socket *sock, struct msghdr *msg, 183 + struct sk_buff *challenge, unsigned int flags) 184 + { 185 + struct rxrpc_skb_priv *sp = rxrpc_skb(challenge); 186 + struct rxrpc_connection *conn = sp->chall.conn; 187 + 188 + return conn->security->challenge_to_recvmsg(conn, challenge, msg); 189 + } 190 + 191 + /* 192 + * Process OOB packets. Called with the socket locked. 193 + */ 194 + static int rxrpc_recvmsg_oob(struct socket *sock, struct msghdr *msg, 195 + unsigned int flags) 196 + { 197 + struct rxrpc_sock *rx = rxrpc_sk(sock->sk); 198 + struct sk_buff *skb; 199 + bool need_response = false; 200 + int ret; 201 + 202 + skb = skb_peek(&rx->recvmsg_oobq); 203 + if (!skb) 204 + return -EAGAIN; 205 + rxrpc_see_skb(skb, rxrpc_skb_see_recvmsg); 206 + 207 + ret = put_cmsg(msg, SOL_RXRPC, RXRPC_OOB_ID, sizeof(u64), 208 + &skb->skb_mstamp_ns); 209 + if (ret < 0) 210 + return ret; 211 + 212 + switch ((enum rxrpc_oob_type)skb->mark) { 213 + case RXRPC_OOB_CHALLENGE: 214 + need_response = true; 215 + ret = rxrpc_recvmsg_challenge(sock, msg, skb, flags); 216 + break; 217 + default: 218 + WARN_ONCE(1, "recvmsg() can't process unknown OOB type %u\n", 219 + skb->mark); 220 + ret = -EIO; 221 + break; 222 + } 223 + 224 + if (!(flags & MSG_PEEK)) 225 + skb_unlink(skb, &rx->recvmsg_oobq); 226 + if (need_response) 227 + rxrpc_add_pending_oob(rx, skb); 228 + else 229 + rxrpc_free_skb(skb, rxrpc_skb_put_oob); 230 + return ret; 231 + } 232 + 233 + /* 158 234 * Deliver messages to a call. This keeps processing packets until the buffer 159 235 * is filled and we find either more DATA (returns 0) or the end of the DATA 160 236 * (returns 1). If more packets are required, it returns -EAGAIN and if the ··· 241 165 size_t len, int flags, size_t *_offset) 242 166 { 243 167 struct rxrpc_skb_priv *sp; 168 + struct rxrpc_sock *rx = rxrpc_sk(sock->sk); 244 169 struct sk_buff *skb; 245 170 rxrpc_seq_t seq = 0; 246 171 size_t remain; ··· 284 207 trace_rxrpc_recvdata(call, rxrpc_recvmsg_next, seq, 285 208 sp->offset, sp->len, ret2); 286 209 if (ret2 < 0) { 287 - kdebug("verify = %d", ret2); 288 210 ret = ret2; 289 211 goto out; 290 212 } ··· 331 255 332 256 if (!(flags & MSG_PEEK)) 333 257 rxrpc_rotate_rx_window(call); 258 + 259 + if (!rx->app_ops && 260 + !skb_queue_empty_lockless(&rx->recvmsg_oobq)) { 261 + trace_rxrpc_recvdata(call, rxrpc_recvmsg_oobq, seq, 262 + rx_pkt_offset, rx_pkt_len, ret); 263 + break; 264 + } 334 265 } 335 266 336 267 out: ··· 345 262 call->rx_pkt_offset = rx_pkt_offset; 346 263 call->rx_pkt_len = rx_pkt_len; 347 264 } 265 + 348 266 done: 349 267 trace_rxrpc_recvdata(call, rxrpc_recvmsg_data_return, seq, 350 268 rx_pkt_offset, rx_pkt_len, ret); ··· 385 301 /* Return immediately if a client socket has no outstanding calls */ 386 302 if (RB_EMPTY_ROOT(&rx->calls) && 387 303 list_empty(&rx->recvmsg_q) && 304 + skb_queue_empty_lockless(&rx->recvmsg_oobq) && 388 305 rx->sk.sk_state != RXRPC_SERVER_LISTENING) { 389 306 release_sock(&rx->sk); 390 307 return -EAGAIN; ··· 407 322 if (ret) 408 323 goto wait_error; 409 324 410 - if (list_empty(&rx->recvmsg_q)) { 325 + if (list_empty(&rx->recvmsg_q) && 326 + skb_queue_empty_lockless(&rx->recvmsg_oobq)) { 411 327 if (signal_pending(current)) 412 328 goto wait_interrupted; 413 329 trace_rxrpc_recvmsg(0, rxrpc_recvmsg_wait, 0); ··· 416 330 } 417 331 finish_wait(sk_sleep(&rx->sk), &wait); 418 332 goto try_again; 333 + } 334 + 335 + /* Deal with OOB messages before we consider getting normal data. */ 336 + if (!skb_queue_empty_lockless(&rx->recvmsg_oobq)) { 337 + ret = rxrpc_recvmsg_oob(sock, msg, flags); 338 + release_sock(&rx->sk); 339 + if (ret == -EAGAIN) 340 + goto try_again; 341 + goto error_no_call; 419 342 } 420 343 421 344 /* Find the next call and dequeue it if we're not just peeking. If we ··· 437 342 call = list_entry(l, struct rxrpc_call, recvmsg_link); 438 343 439 344 if (!rxrpc_call_is_complete(call) && 440 - skb_queue_empty(&call->recvmsg_queue)) { 345 + skb_queue_empty(&call->recvmsg_queue) && 346 + skb_queue_empty(&rx->recvmsg_oobq)) { 441 347 list_del_init(&call->recvmsg_link); 442 348 spin_unlock_irq(&rx->recvmsg_lock); 443 349 release_sock(&rx->sk); ··· 473 377 if (test_bit(RXRPC_CALL_RELEASED, &call->flags)) 474 378 BUG(); 475 379 476 - if (test_bit(RXRPC_CALL_HAS_USERID, &call->flags)) { 477 - if (flags & MSG_CMSG_COMPAT) { 478 - unsigned int id32 = call->user_call_ID; 479 - 480 - ret = put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID, 481 - sizeof(unsigned int), &id32); 482 - } else { 483 - unsigned long idl = call->user_call_ID; 484 - 485 - ret = put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID, 486 - sizeof(unsigned long), &idl); 487 - } 488 - if (ret < 0) 489 - goto error_unlock_call; 490 - } 380 + ret = rxrpc_recvmsg_user_id(call, msg, flags); 381 + if (ret < 0) 382 + goto error_unlock_call; 491 383 492 384 if (msg->msg_name && call->peer) { 493 385 size_t len = sizeof(call->dest_srx); ··· 561 477 * @_service: Where to store the actual service ID (may be upgraded) 562 478 * 563 479 * Allow a kernel service to receive data and pick up information about the 564 - * state of a call. Returns 0 if got what was asked for and there's more 565 - * available, 1 if we got what was asked for and we're at the end of the data 566 - * and -EAGAIN if we need more data. 480 + * state of a call. Note that *@_abort should also be initialised to %0. 567 481 * 568 - * Note that we may return -EAGAIN to drain empty packets at the end of the 569 - * data, even if we've already copied over the requested data. 482 + * Note that we may return %-EAGAIN to drain empty packets at the end 483 + * of the data, even if we've already copied over the requested data. 570 484 * 571 - * *_abort should also be initialised to 0. 485 + * Return: %0 if got what was asked for and there's more available, %1 486 + * if we got what was asked for and we're at the end of the data and 487 + * %-EAGAIN if we need more data. 572 488 */ 573 489 int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call, 574 490 struct iov_iter *iter, size_t *_len,
+1367
net/rxrpc/rxgk.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* GSSAPI-based RxRPC security 3 + * 4 + * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved. 5 + * Written by David Howells (dhowells@redhat.com) 6 + */ 7 + 8 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 + 10 + #include <linux/net.h> 11 + #include <linux/skbuff.h> 12 + #include <linux/slab.h> 13 + #include <linux/key-type.h> 14 + #include "ar-internal.h" 15 + #include "rxgk_common.h" 16 + 17 + /* 18 + * Parse the information from a server key 19 + */ 20 + static int rxgk_preparse_server_key(struct key_preparsed_payload *prep) 21 + { 22 + const struct krb5_enctype *krb5; 23 + struct krb5_buffer *server_key = (void *)&prep->payload.data[2]; 24 + unsigned int service, sec_class, kvno, enctype; 25 + int n = 0; 26 + 27 + _enter("%zu", prep->datalen); 28 + 29 + if (sscanf(prep->orig_description, "%u:%u:%u:%u%n", 30 + &service, &sec_class, &kvno, &enctype, &n) != 4) 31 + return -EINVAL; 32 + 33 + if (prep->orig_description[n]) 34 + return -EINVAL; 35 + 36 + krb5 = crypto_krb5_find_enctype(enctype); 37 + if (!krb5) 38 + return -ENOPKG; 39 + 40 + prep->payload.data[0] = (struct krb5_enctype *)krb5; 41 + 42 + if (prep->datalen != krb5->key_len) 43 + return -EKEYREJECTED; 44 + 45 + server_key->len = prep->datalen; 46 + server_key->data = kmemdup(prep->data, prep->datalen, GFP_KERNEL); 47 + if (!server_key->data) 48 + return -ENOMEM; 49 + 50 + _leave(" = 0"); 51 + return 0; 52 + } 53 + 54 + static void rxgk_free_server_key(union key_payload *payload) 55 + { 56 + struct krb5_buffer *server_key = (void *)&payload->data[2]; 57 + 58 + kfree_sensitive(server_key->data); 59 + } 60 + 61 + static void rxgk_free_preparse_server_key(struct key_preparsed_payload *prep) 62 + { 63 + rxgk_free_server_key(&prep->payload); 64 + } 65 + 66 + static void rxgk_destroy_server_key(struct key *key) 67 + { 68 + rxgk_free_server_key(&key->payload); 69 + } 70 + 71 + static void rxgk_describe_server_key(const struct key *key, struct seq_file *m) 72 + { 73 + const struct krb5_enctype *krb5 = key->payload.data[0]; 74 + 75 + if (krb5) 76 + seq_printf(m, ": %s", krb5->name); 77 + } 78 + 79 + /* 80 + * Handle rekeying the connection when we see our limits overrun or when the 81 + * far side decided to rekey. 82 + * 83 + * Returns a ref on the context if successful or -ESTALE if the key is out of 84 + * date. 85 + */ 86 + static struct rxgk_context *rxgk_rekey(struct rxrpc_connection *conn, 87 + const u16 *specific_key_number) 88 + { 89 + struct rxgk_context *gk, *dead = NULL; 90 + unsigned int key_number, current_key, mask = ARRAY_SIZE(conn->rxgk.keys) - 1; 91 + bool crank = false; 92 + 93 + _enter("%d", specific_key_number ? *specific_key_number : -1); 94 + 95 + mutex_lock(&conn->security_lock); 96 + 97 + current_key = conn->rxgk.key_number; 98 + if (!specific_key_number) { 99 + key_number = current_key; 100 + } else { 101 + if (*specific_key_number == (u16)current_key) 102 + key_number = current_key; 103 + else if (*specific_key_number == (u16)(current_key - 1)) 104 + key_number = current_key - 1; 105 + else if (*specific_key_number == (u16)(current_key + 1)) 106 + goto crank_window; 107 + else 108 + goto bad_key; 109 + } 110 + 111 + gk = conn->rxgk.keys[key_number & mask]; 112 + if (!gk) 113 + goto generate_key; 114 + if (!specific_key_number && 115 + test_bit(RXGK_TK_NEEDS_REKEY, &gk->flags)) 116 + goto crank_window; 117 + 118 + grab: 119 + refcount_inc(&gk->usage); 120 + mutex_unlock(&conn->security_lock); 121 + rxgk_put(dead); 122 + return gk; 123 + 124 + crank_window: 125 + trace_rxrpc_rxgk_rekey(conn, current_key, 126 + specific_key_number ? *specific_key_number : -1); 127 + if (current_key == UINT_MAX) 128 + goto bad_key; 129 + if (current_key + 1 == UINT_MAX) 130 + set_bit(RXRPC_CONN_DONT_REUSE, &conn->flags); 131 + 132 + key_number = current_key + 1; 133 + if (WARN_ON(conn->rxgk.keys[key_number & mask])) 134 + goto bad_key; 135 + crank = true; 136 + 137 + generate_key: 138 + gk = conn->rxgk.keys[current_key & mask]; 139 + gk = rxgk_generate_transport_key(conn, gk->key, key_number, GFP_NOFS); 140 + if (IS_ERR(gk)) { 141 + mutex_unlock(&conn->security_lock); 142 + return gk; 143 + } 144 + 145 + write_lock(&conn->security_use_lock); 146 + if (crank) { 147 + current_key++; 148 + conn->rxgk.key_number = current_key; 149 + dead = conn->rxgk.keys[(current_key - 2) & mask]; 150 + conn->rxgk.keys[(current_key - 2) & mask] = NULL; 151 + } 152 + conn->rxgk.keys[current_key & mask] = gk; 153 + write_unlock(&conn->security_use_lock); 154 + goto grab; 155 + 156 + bad_key: 157 + mutex_unlock(&conn->security_lock); 158 + return ERR_PTR(-ESTALE); 159 + } 160 + 161 + /* 162 + * Get the specified keying context. 163 + * 164 + * Returns a ref on the context if successful or -ESTALE if the key is out of 165 + * date. 166 + */ 167 + static struct rxgk_context *rxgk_get_key(struct rxrpc_connection *conn, 168 + const u16 *specific_key_number) 169 + { 170 + struct rxgk_context *gk; 171 + unsigned int key_number, current_key, mask = ARRAY_SIZE(conn->rxgk.keys) - 1; 172 + 173 + _enter("{%u},%d", 174 + conn->rxgk.key_number, specific_key_number ? *specific_key_number : -1); 175 + 176 + read_lock(&conn->security_use_lock); 177 + 178 + current_key = conn->rxgk.key_number; 179 + if (!specific_key_number) { 180 + key_number = current_key; 181 + } else { 182 + /* Only the bottom 16 bits of the key number are exposed in the 183 + * header, so we try and keep the upper 16 bits in step. The 184 + * whole 32 bits are used to generate the TK. 185 + */ 186 + if (*specific_key_number == (u16)current_key) 187 + key_number = current_key; 188 + else if (*specific_key_number == (u16)(current_key - 1)) 189 + key_number = current_key - 1; 190 + else if (*specific_key_number == (u16)(current_key + 1)) 191 + goto rekey; 192 + else 193 + goto bad_key; 194 + } 195 + 196 + gk = conn->rxgk.keys[key_number & mask]; 197 + if (!gk) 198 + goto slow_path; 199 + if (!specific_key_number && 200 + key_number < UINT_MAX) { 201 + if (time_after(jiffies, gk->expiry) || 202 + gk->bytes_remaining < 0) { 203 + set_bit(RXGK_TK_NEEDS_REKEY, &gk->flags); 204 + goto slow_path; 205 + } 206 + 207 + if (test_bit(RXGK_TK_NEEDS_REKEY, &gk->flags)) 208 + goto slow_path; 209 + } 210 + 211 + refcount_inc(&gk->usage); 212 + read_unlock(&conn->security_use_lock); 213 + return gk; 214 + 215 + rekey: 216 + _debug("rekey"); 217 + if (current_key == UINT_MAX) 218 + goto bad_key; 219 + gk = conn->rxgk.keys[current_key & mask]; 220 + if (gk) 221 + set_bit(RXGK_TK_NEEDS_REKEY, &gk->flags); 222 + slow_path: 223 + read_unlock(&conn->security_use_lock); 224 + return rxgk_rekey(conn, specific_key_number); 225 + bad_key: 226 + read_unlock(&conn->security_use_lock); 227 + return ERR_PTR(-ESTALE); 228 + } 229 + 230 + /* 231 + * initialise connection security 232 + */ 233 + static int rxgk_init_connection_security(struct rxrpc_connection *conn, 234 + struct rxrpc_key_token *token) 235 + { 236 + struct rxgk_context *gk; 237 + int ret; 238 + 239 + _enter("{%d,%u},{%x}", 240 + conn->debug_id, conn->rxgk.key_number, key_serial(conn->key)); 241 + 242 + conn->security_ix = token->security_index; 243 + conn->security_level = token->rxgk->level; 244 + 245 + if (rxrpc_conn_is_client(conn)) { 246 + conn->rxgk.start_time = ktime_get(); 247 + do_div(conn->rxgk.start_time, 100); 248 + } 249 + 250 + gk = rxgk_generate_transport_key(conn, token->rxgk, conn->rxgk.key_number, 251 + GFP_NOFS); 252 + if (IS_ERR(gk)) 253 + return PTR_ERR(gk); 254 + conn->rxgk.enctype = gk->krb5->etype; 255 + conn->rxgk.keys[gk->key_number & 3] = gk; 256 + 257 + switch (conn->security_level) { 258 + case RXRPC_SECURITY_PLAIN: 259 + case RXRPC_SECURITY_AUTH: 260 + case RXRPC_SECURITY_ENCRYPT: 261 + break; 262 + default: 263 + ret = -EKEYREJECTED; 264 + goto error; 265 + } 266 + 267 + ret = 0; 268 + error: 269 + _leave(" = %d", ret); 270 + return ret; 271 + } 272 + 273 + /* 274 + * Clean up the crypto on a call. 275 + */ 276 + static void rxgk_free_call_crypto(struct rxrpc_call *call) 277 + { 278 + } 279 + 280 + /* 281 + * Work out how much data we can put in a packet. 282 + */ 283 + static struct rxrpc_txbuf *rxgk_alloc_txbuf(struct rxrpc_call *call, size_t remain, gfp_t gfp) 284 + { 285 + enum krb5_crypto_mode mode; 286 + struct rxgk_context *gk; 287 + struct rxrpc_txbuf *txb; 288 + size_t shdr, alloc, limit, part, offset, gap; 289 + 290 + switch (call->conn->security_level) { 291 + default: 292 + alloc = umin(remain, RXRPC_JUMBO_DATALEN); 293 + return rxrpc_alloc_data_txbuf(call, alloc, 1, gfp); 294 + case RXRPC_SECURITY_AUTH: 295 + shdr = 0; 296 + mode = KRB5_CHECKSUM_MODE; 297 + break; 298 + case RXRPC_SECURITY_ENCRYPT: 299 + shdr = sizeof(struct rxgk_header); 300 + mode = KRB5_ENCRYPT_MODE; 301 + break; 302 + } 303 + 304 + gk = rxgk_get_key(call->conn, NULL); 305 + if (IS_ERR(gk)) 306 + return NULL; 307 + 308 + /* Work out the maximum amount of data that will fit. */ 309 + alloc = RXRPC_JUMBO_DATALEN; 310 + limit = crypto_krb5_how_much_data(gk->krb5, mode, &alloc, &offset); 311 + 312 + if (remain < limit - shdr) { 313 + part = remain; 314 + alloc = crypto_krb5_how_much_buffer(gk->krb5, mode, 315 + shdr + part, &offset); 316 + gap = 0; 317 + } else { 318 + part = limit - shdr; 319 + gap = RXRPC_JUMBO_DATALEN - alloc; 320 + alloc = RXRPC_JUMBO_DATALEN; 321 + } 322 + 323 + rxgk_put(gk); 324 + 325 + txb = rxrpc_alloc_data_txbuf(call, alloc, 16, gfp); 326 + if (!txb) 327 + return NULL; 328 + 329 + txb->crypto_header = offset; 330 + txb->sec_header = shdr; 331 + txb->offset += offset + shdr; 332 + txb->space = part; 333 + 334 + /* Clear excess space in the packet */ 335 + if (gap) 336 + memset(txb->data + alloc - gap, 0, gap); 337 + return txb; 338 + } 339 + 340 + /* 341 + * Integrity mode (sign a packet - level 1 security) 342 + */ 343 + static int rxgk_secure_packet_integrity(const struct rxrpc_call *call, 344 + struct rxgk_context *gk, 345 + struct rxrpc_txbuf *txb) 346 + { 347 + struct rxgk_header *hdr; 348 + struct scatterlist sg[1]; 349 + struct krb5_buffer metadata; 350 + int ret = -ENOMEM; 351 + 352 + _enter(""); 353 + 354 + hdr = kzalloc(sizeof(*hdr), GFP_NOFS); 355 + if (!hdr) 356 + goto error_gk; 357 + 358 + hdr->epoch = htonl(call->conn->proto.epoch); 359 + hdr->cid = htonl(call->cid); 360 + hdr->call_number = htonl(call->call_id); 361 + hdr->seq = htonl(txb->seq); 362 + hdr->sec_index = htonl(call->security_ix); 363 + hdr->data_len = htonl(txb->len); 364 + metadata.len = sizeof(*hdr); 365 + metadata.data = hdr; 366 + 367 + sg_init_table(sg, 1); 368 + sg_set_buf(&sg[0], txb->data, txb->alloc_size); 369 + 370 + ret = crypto_krb5_get_mic(gk->krb5, gk->tx_Kc, &metadata, 371 + sg, 1, txb->alloc_size, 372 + txb->crypto_header, txb->sec_header + txb->len); 373 + if (ret >= 0) { 374 + txb->pkt_len = ret; 375 + if (txb->alloc_size == RXRPC_JUMBO_DATALEN) 376 + txb->jumboable = true; 377 + gk->bytes_remaining -= ret; 378 + } 379 + kfree(hdr); 380 + error_gk: 381 + rxgk_put(gk); 382 + _leave(" = %d", ret); 383 + return ret; 384 + } 385 + 386 + /* 387 + * wholly encrypt a packet (level 2 security) 388 + */ 389 + static int rxgk_secure_packet_encrypted(const struct rxrpc_call *call, 390 + struct rxgk_context *gk, 391 + struct rxrpc_txbuf *txb) 392 + { 393 + struct rxgk_header *hdr; 394 + struct scatterlist sg[1]; 395 + int ret; 396 + 397 + _enter("%x", txb->len); 398 + 399 + /* Insert the header into the buffer. */ 400 + hdr = txb->data + txb->crypto_header; 401 + hdr->epoch = htonl(call->conn->proto.epoch); 402 + hdr->cid = htonl(call->cid); 403 + hdr->call_number = htonl(call->call_id); 404 + hdr->seq = htonl(txb->seq); 405 + hdr->sec_index = htonl(call->security_ix); 406 + hdr->data_len = htonl(txb->len); 407 + 408 + sg_init_table(sg, 1); 409 + sg_set_buf(&sg[0], txb->data, txb->alloc_size); 410 + 411 + ret = crypto_krb5_encrypt(gk->krb5, gk->tx_enc, 412 + sg, 1, txb->alloc_size, 413 + txb->crypto_header, txb->sec_header + txb->len, 414 + false); 415 + if (ret >= 0) { 416 + txb->pkt_len = ret; 417 + if (txb->alloc_size == RXRPC_JUMBO_DATALEN) 418 + txb->jumboable = true; 419 + gk->bytes_remaining -= ret; 420 + } 421 + 422 + rxgk_put(gk); 423 + _leave(" = %d", ret); 424 + return ret; 425 + } 426 + 427 + /* 428 + * checksum an RxRPC packet header 429 + */ 430 + static int rxgk_secure_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb) 431 + { 432 + struct rxgk_context *gk; 433 + int ret; 434 + 435 + _enter("{%d{%x}},{#%u},%u,", 436 + call->debug_id, key_serial(call->conn->key), txb->seq, txb->len); 437 + 438 + gk = rxgk_get_key(call->conn, NULL); 439 + if (IS_ERR(gk)) 440 + return PTR_ERR(gk) == -ESTALE ? -EKEYREJECTED : PTR_ERR(gk); 441 + 442 + ret = key_validate(call->conn->key); 443 + if (ret < 0) 444 + return ret; 445 + 446 + call->security_enctype = gk->krb5->etype; 447 + txb->cksum = htons(gk->key_number); 448 + 449 + switch (call->conn->security_level) { 450 + case RXRPC_SECURITY_PLAIN: 451 + rxgk_put(gk); 452 + txb->pkt_len = txb->len; 453 + return 0; 454 + case RXRPC_SECURITY_AUTH: 455 + return rxgk_secure_packet_integrity(call, gk, txb); 456 + case RXRPC_SECURITY_ENCRYPT: 457 + return rxgk_secure_packet_encrypted(call, gk, txb); 458 + default: 459 + rxgk_put(gk); 460 + return -EPERM; 461 + } 462 + } 463 + 464 + /* 465 + * Integrity mode (check the signature on a packet - level 1 security) 466 + */ 467 + static int rxgk_verify_packet_integrity(struct rxrpc_call *call, 468 + struct rxgk_context *gk, 469 + struct sk_buff *skb) 470 + { 471 + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 472 + struct rxgk_header *hdr; 473 + struct krb5_buffer metadata; 474 + unsigned int offset = sp->offset, len = sp->len; 475 + size_t data_offset = 0, data_len = len; 476 + u32 ac; 477 + int ret = -ENOMEM; 478 + 479 + _enter(""); 480 + 481 + crypto_krb5_where_is_the_data(gk->krb5, KRB5_CHECKSUM_MODE, 482 + &data_offset, &data_len); 483 + 484 + hdr = kzalloc(sizeof(*hdr), GFP_NOFS); 485 + if (!hdr) 486 + return -ENOMEM; 487 + 488 + hdr->epoch = htonl(call->conn->proto.epoch); 489 + hdr->cid = htonl(call->cid); 490 + hdr->call_number = htonl(call->call_id); 491 + hdr->seq = htonl(sp->hdr.seq); 492 + hdr->sec_index = htonl(call->security_ix); 493 + hdr->data_len = htonl(data_len); 494 + 495 + metadata.len = sizeof(*hdr); 496 + metadata.data = hdr; 497 + ret = rxgk_verify_mic_skb(gk->krb5, gk->rx_Kc, &metadata, 498 + skb, &offset, &len, &ac); 499 + kfree(hdr); 500 + if (ret == -EPROTO) { 501 + rxrpc_abort_eproto(call, skb, ac, 502 + rxgk_abort_1_verify_mic_eproto); 503 + } else { 504 + sp->offset = offset; 505 + sp->len = len; 506 + } 507 + 508 + rxgk_put(gk); 509 + _leave(" = %d", ret); 510 + return ret; 511 + } 512 + 513 + /* 514 + * Decrypt an encrypted packet (level 2 security). 515 + */ 516 + static int rxgk_verify_packet_encrypted(struct rxrpc_call *call, 517 + struct rxgk_context *gk, 518 + struct sk_buff *skb) 519 + { 520 + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 521 + struct rxgk_header hdr; 522 + unsigned int offset = sp->offset, len = sp->len; 523 + int ret; 524 + u32 ac; 525 + 526 + _enter(""); 527 + 528 + ret = rxgk_decrypt_skb(gk->krb5, gk->rx_enc, skb, &offset, &len, &ac); 529 + if (ret == -EPROTO) 530 + rxrpc_abort_eproto(call, skb, ac, rxgk_abort_2_decrypt_eproto); 531 + if (ret < 0) 532 + goto error; 533 + 534 + if (len < sizeof(hdr)) { 535 + ret = rxrpc_abort_eproto(call, skb, RXGK_PACKETSHORT, 536 + rxgk_abort_2_short_header); 537 + goto error; 538 + } 539 + 540 + /* Extract the header from the skb */ 541 + ret = skb_copy_bits(skb, offset, &hdr, sizeof(hdr)); 542 + if (ret < 0) { 543 + ret = rxrpc_abort_eproto(call, skb, RXGK_PACKETSHORT, 544 + rxgk_abort_2_short_encdata); 545 + goto error; 546 + } 547 + offset += sizeof(hdr); 548 + len -= sizeof(hdr); 549 + 550 + if (ntohl(hdr.epoch) != call->conn->proto.epoch || 551 + ntohl(hdr.cid) != call->cid || 552 + ntohl(hdr.call_number) != call->call_id || 553 + ntohl(hdr.seq) != sp->hdr.seq || 554 + ntohl(hdr.sec_index) != call->security_ix || 555 + ntohl(hdr.data_len) > len) { 556 + ret = rxrpc_abort_eproto(call, skb, RXGK_SEALEDINCON, 557 + rxgk_abort_2_short_data); 558 + goto error; 559 + } 560 + 561 + sp->offset = offset; 562 + sp->len = ntohl(hdr.data_len); 563 + ret = 0; 564 + error: 565 + rxgk_put(gk); 566 + _leave(" = %d", ret); 567 + return ret; 568 + } 569 + 570 + /* 571 + * Verify the security on a received packet or subpacket (if part of a 572 + * jumbo packet). 573 + */ 574 + static int rxgk_verify_packet(struct rxrpc_call *call, struct sk_buff *skb) 575 + { 576 + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 577 + struct rxgk_context *gk; 578 + u16 key_number = sp->hdr.cksum; 579 + 580 + _enter("{%d{%x}},{#%u}", 581 + call->debug_id, key_serial(call->conn->key), sp->hdr.seq); 582 + 583 + gk = rxgk_get_key(call->conn, &key_number); 584 + if (IS_ERR(gk)) { 585 + switch (PTR_ERR(gk)) { 586 + case -ESTALE: 587 + return rxrpc_abort_eproto(call, skb, RXGK_BADKEYNO, 588 + rxgk_abort_bad_key_number); 589 + default: 590 + return PTR_ERR(gk); 591 + } 592 + } 593 + 594 + call->security_enctype = gk->krb5->etype; 595 + switch (call->conn->security_level) { 596 + case RXRPC_SECURITY_PLAIN: 597 + return 0; 598 + case RXRPC_SECURITY_AUTH: 599 + return rxgk_verify_packet_integrity(call, gk, skb); 600 + case RXRPC_SECURITY_ENCRYPT: 601 + return rxgk_verify_packet_encrypted(call, gk, skb); 602 + default: 603 + rxgk_put(gk); 604 + return -ENOANO; 605 + } 606 + } 607 + 608 + /* 609 + * Allocate memory to hold a challenge or a response packet. We're not running 610 + * in the io_thread, so we can't use ->tx_alloc. 611 + */ 612 + static struct page *rxgk_alloc_packet(size_t total_len) 613 + { 614 + gfp_t gfp = GFP_NOFS; 615 + int order; 616 + 617 + order = get_order(total_len); 618 + if (order > 0) 619 + gfp |= __GFP_COMP; 620 + return alloc_pages(gfp, order); 621 + } 622 + 623 + /* 624 + * Issue a challenge. 625 + */ 626 + static int rxgk_issue_challenge(struct rxrpc_connection *conn) 627 + { 628 + struct rxrpc_wire_header *whdr; 629 + struct bio_vec bvec[1]; 630 + struct msghdr msg; 631 + struct page *page; 632 + size_t len = sizeof(*whdr) + sizeof(conn->rxgk.nonce); 633 + u32 serial; 634 + int ret; 635 + 636 + _enter("{%d}", conn->debug_id); 637 + 638 + get_random_bytes(&conn->rxgk.nonce, sizeof(conn->rxgk.nonce)); 639 + 640 + /* We can't use conn->tx_alloc without a lock */ 641 + page = rxgk_alloc_packet(sizeof(*whdr) + sizeof(conn->rxgk.nonce)); 642 + if (!page) 643 + return -ENOMEM; 644 + 645 + bvec_set_page(&bvec[0], page, len, 0); 646 + iov_iter_bvec(&msg.msg_iter, WRITE, bvec, 1, len); 647 + 648 + msg.msg_name = &conn->peer->srx.transport; 649 + msg.msg_namelen = conn->peer->srx.transport_len; 650 + msg.msg_control = NULL; 651 + msg.msg_controllen = 0; 652 + msg.msg_flags = MSG_SPLICE_PAGES; 653 + 654 + whdr = page_address(page); 655 + whdr->epoch = htonl(conn->proto.epoch); 656 + whdr->cid = htonl(conn->proto.cid); 657 + whdr->callNumber = 0; 658 + whdr->seq = 0; 659 + whdr->type = RXRPC_PACKET_TYPE_CHALLENGE; 660 + whdr->flags = conn->out_clientflag; 661 + whdr->userStatus = 0; 662 + whdr->securityIndex = conn->security_ix; 663 + whdr->_rsvd = 0; 664 + whdr->serviceId = htons(conn->service_id); 665 + 666 + memcpy(whdr + 1, conn->rxgk.nonce, sizeof(conn->rxgk.nonce)); 667 + 668 + serial = rxrpc_get_next_serials(conn, 1); 669 + whdr->serial = htonl(serial); 670 + 671 + trace_rxrpc_tx_challenge(conn, serial, 0, *(u32 *)&conn->rxgk.nonce); 672 + 673 + ret = do_udp_sendmsg(conn->local->socket, &msg, len); 674 + if (ret > 0) 675 + conn->peer->last_tx_at = ktime_get_seconds(); 676 + __free_page(page); 677 + 678 + if (ret < 0) { 679 + trace_rxrpc_tx_fail(conn->debug_id, serial, ret, 680 + rxrpc_tx_point_rxgk_challenge); 681 + return -EAGAIN; 682 + } 683 + 684 + trace_rxrpc_tx_packet(conn->debug_id, whdr, 685 + rxrpc_tx_point_rxgk_challenge); 686 + _leave(" = 0"); 687 + return 0; 688 + } 689 + 690 + /* 691 + * Validate a challenge packet. 692 + */ 693 + static bool rxgk_validate_challenge(struct rxrpc_connection *conn, 694 + struct sk_buff *skb) 695 + { 696 + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 697 + u8 nonce[20]; 698 + 699 + if (!conn->key) { 700 + rxrpc_abort_conn(conn, skb, RX_PROTOCOL_ERROR, -EPROTO, 701 + rxgk_abort_chall_no_key); 702 + return false; 703 + } 704 + 705 + if (key_validate(conn->key) < 0) { 706 + rxrpc_abort_conn(conn, skb, RXGK_EXPIRED, -EPROTO, 707 + rxgk_abort_chall_key_expired); 708 + return false; 709 + } 710 + 711 + if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header), 712 + nonce, sizeof(nonce)) < 0) { 713 + rxrpc_abort_conn(conn, skb, RXGK_PACKETSHORT, -EPROTO, 714 + rxgk_abort_chall_short); 715 + return false; 716 + } 717 + 718 + trace_rxrpc_rx_challenge(conn, sp->hdr.serial, 0, *(u32 *)nonce, 0); 719 + return true; 720 + } 721 + 722 + /** 723 + * rxgk_kernel_query_challenge - Query RxGK-specific challenge parameters 724 + * @challenge: The challenge packet to query 725 + * 726 + * Return: The Kerberos 5 encoding type for the challenged connection. 727 + */ 728 + u32 rxgk_kernel_query_challenge(struct sk_buff *challenge) 729 + { 730 + struct rxrpc_skb_priv *sp = rxrpc_skb(challenge); 731 + 732 + return sp->chall.conn->rxgk.enctype; 733 + } 734 + EXPORT_SYMBOL(rxgk_kernel_query_challenge); 735 + 736 + /* 737 + * Fill out the control message to pass to userspace to inform about the 738 + * challenge. 739 + */ 740 + static int rxgk_challenge_to_recvmsg(struct rxrpc_connection *conn, 741 + struct sk_buff *challenge, 742 + struct msghdr *msg) 743 + { 744 + struct rxgk_challenge chall; 745 + 746 + chall.base.service_id = conn->service_id; 747 + chall.base.security_index = conn->security_ix; 748 + chall.enctype = conn->rxgk.enctype; 749 + 750 + return put_cmsg(msg, SOL_RXRPC, RXRPC_CHALLENGED, sizeof(chall), &chall); 751 + } 752 + 753 + /* 754 + * Insert the requisite amount of XDR padding for the length given. 755 + */ 756 + static int rxgk_pad_out(struct sk_buff *response, size_t len, size_t offset) 757 + { 758 + __be32 zero = 0; 759 + size_t pad = xdr_round_up(len) - len; 760 + int ret; 761 + 762 + if (!pad) 763 + return 0; 764 + 765 + ret = skb_store_bits(response, offset, &zero, pad); 766 + if (ret < 0) 767 + return ret; 768 + return pad; 769 + } 770 + 771 + /* 772 + * Insert the header into the response. 773 + */ 774 + static noinline ssize_t rxgk_insert_response_header(struct rxrpc_connection *conn, 775 + struct rxgk_context *gk, 776 + struct sk_buff *response, 777 + size_t offset) 778 + { 779 + struct rxrpc_skb_priv *rsp = rxrpc_skb(response); 780 + 781 + struct { 782 + struct rxrpc_wire_header whdr; 783 + __be32 start_time_msw; 784 + __be32 start_time_lsw; 785 + __be32 ticket_len; 786 + } h; 787 + int ret; 788 + 789 + rsp->resp.kvno = gk->key_number; 790 + rsp->resp.version = gk->krb5->etype; 791 + 792 + h.whdr.epoch = htonl(conn->proto.epoch); 793 + h.whdr.cid = htonl(conn->proto.cid); 794 + h.whdr.callNumber = 0; 795 + h.whdr.serial = 0; 796 + h.whdr.seq = 0; 797 + h.whdr.type = RXRPC_PACKET_TYPE_RESPONSE; 798 + h.whdr.flags = conn->out_clientflag; 799 + h.whdr.userStatus = 0; 800 + h.whdr.securityIndex = conn->security_ix; 801 + h.whdr.cksum = htons(gk->key_number); 802 + h.whdr.serviceId = htons(conn->service_id); 803 + h.start_time_msw = htonl(upper_32_bits(conn->rxgk.start_time)); 804 + h.start_time_lsw = htonl(lower_32_bits(conn->rxgk.start_time)); 805 + h.ticket_len = htonl(gk->key->ticket.len); 806 + 807 + ret = skb_store_bits(response, offset, &h, sizeof(h)); 808 + return ret < 0 ? ret : sizeof(h); 809 + } 810 + 811 + /* 812 + * Construct the authenticator to go in the response packet 813 + * 814 + * struct RXGK_Authenticator { 815 + * opaque nonce[20]; 816 + * opaque appdata<>; 817 + * RXGK_Level level; 818 + * unsigned int epoch; 819 + * unsigned int cid; 820 + * unsigned int call_numbers<>; 821 + * }; 822 + */ 823 + static ssize_t rxgk_construct_authenticator(struct rxrpc_connection *conn, 824 + struct sk_buff *challenge, 825 + const struct krb5_buffer *appdata, 826 + struct sk_buff *response, 827 + size_t offset) 828 + { 829 + struct { 830 + u8 nonce[20]; 831 + __be32 appdata_len; 832 + } a; 833 + struct { 834 + __be32 level; 835 + __be32 epoch; 836 + __be32 cid; 837 + __be32 call_numbers_count; 838 + __be32 call_numbers[4]; 839 + } b; 840 + int ret; 841 + 842 + ret = skb_copy_bits(challenge, sizeof(struct rxrpc_wire_header), 843 + a.nonce, sizeof(a.nonce)); 844 + if (ret < 0) 845 + return -EPROTO; 846 + 847 + a.appdata_len = htonl(appdata->len); 848 + 849 + ret = skb_store_bits(response, offset, &a, sizeof(a)); 850 + if (ret < 0) 851 + return ret; 852 + offset += sizeof(a); 853 + 854 + if (appdata->len) { 855 + ret = skb_store_bits(response, offset, appdata->data, appdata->len); 856 + if (ret < 0) 857 + return ret; 858 + offset += appdata->len; 859 + 860 + ret = rxgk_pad_out(response, appdata->len, offset); 861 + if (ret < 0) 862 + return ret; 863 + offset += ret; 864 + } 865 + 866 + b.level = htonl(conn->security_level); 867 + b.epoch = htonl(conn->proto.epoch); 868 + b.cid = htonl(conn->proto.cid); 869 + b.call_numbers_count = htonl(4); 870 + b.call_numbers[0] = htonl(conn->channels[0].call_counter); 871 + b.call_numbers[1] = htonl(conn->channels[1].call_counter); 872 + b.call_numbers[2] = htonl(conn->channels[2].call_counter); 873 + b.call_numbers[3] = htonl(conn->channels[3].call_counter); 874 + 875 + ret = skb_store_bits(response, offset, &b, sizeof(b)); 876 + if (ret < 0) 877 + return ret; 878 + return sizeof(a) + xdr_round_up(appdata->len) + sizeof(b); 879 + } 880 + 881 + static ssize_t rxgk_encrypt_authenticator(struct rxrpc_connection *conn, 882 + struct rxgk_context *gk, 883 + struct sk_buff *response, 884 + size_t offset, 885 + size_t alloc_len, 886 + size_t auth_offset, 887 + size_t auth_len) 888 + { 889 + struct scatterlist sg[16]; 890 + int nr_sg; 891 + 892 + sg_init_table(sg, ARRAY_SIZE(sg)); 893 + nr_sg = skb_to_sgvec(response, sg, offset, alloc_len); 894 + if (unlikely(nr_sg < 0)) 895 + return nr_sg; 896 + return crypto_krb5_encrypt(gk->krb5, gk->resp_enc, sg, nr_sg, alloc_len, 897 + auth_offset, auth_len, false); 898 + } 899 + 900 + /* 901 + * Construct the response. 902 + * 903 + * struct RXGK_Response { 904 + * rxgkTime start_time; 905 + * RXGK_Data token; 906 + * opaque authenticator<RXGK_MAXAUTHENTICATOR> 907 + * }; 908 + */ 909 + static int rxgk_construct_response(struct rxrpc_connection *conn, 910 + struct sk_buff *challenge, 911 + struct krb5_buffer *appdata) 912 + { 913 + struct rxrpc_skb_priv *csp, *rsp; 914 + struct rxgk_context *gk; 915 + struct sk_buff *response; 916 + size_t len, auth_len, authx_len, offset, auth_offset, authx_offset; 917 + __be32 tmp; 918 + int ret; 919 + 920 + gk = rxgk_get_key(conn, NULL); 921 + if (IS_ERR(gk)) 922 + return PTR_ERR(gk); 923 + 924 + auth_len = 20 + (4 + appdata->len) + 12 + (1 + 4) * 4; 925 + authx_len = crypto_krb5_how_much_buffer(gk->krb5, KRB5_ENCRYPT_MODE, 926 + auth_len, &auth_offset); 927 + len = sizeof(struct rxrpc_wire_header) + 928 + 8 + (4 + xdr_round_up(gk->key->ticket.len)) + (4 + authx_len); 929 + 930 + response = alloc_skb_with_frags(0, len, 0, &ret, GFP_NOFS); 931 + if (!response) 932 + goto error; 933 + rxrpc_new_skb(response, rxrpc_skb_new_response_rxgk); 934 + response->len = len; 935 + response->data_len = len; 936 + 937 + ret = rxgk_insert_response_header(conn, gk, response, 0); 938 + if (ret < 0) 939 + goto error; 940 + offset = ret; 941 + 942 + ret = skb_store_bits(response, offset, gk->key->ticket.data, gk->key->ticket.len); 943 + if (ret < 0) 944 + goto error; 945 + offset += gk->key->ticket.len; 946 + ret = rxgk_pad_out(response, gk->key->ticket.len, offset); 947 + if (ret < 0) 948 + goto error; 949 + 950 + authx_offset = offset + ret + 4; /* Leave a gap for the length. */ 951 + 952 + ret = rxgk_construct_authenticator(conn, challenge, appdata, response, 953 + authx_offset + auth_offset); 954 + if (ret < 0) 955 + goto error; 956 + auth_len = ret; 957 + 958 + ret = rxgk_encrypt_authenticator(conn, gk, response, 959 + authx_offset, authx_len, 960 + auth_offset, auth_len); 961 + if (ret < 0) 962 + goto error; 963 + authx_len = ret; 964 + 965 + tmp = htonl(authx_len); 966 + ret = skb_store_bits(response, authx_offset - 4, &tmp, 4); 967 + if (ret < 0) 968 + goto error; 969 + 970 + ret = rxgk_pad_out(response, authx_len, authx_offset + authx_len); 971 + if (ret < 0) 972 + return ret; 973 + len = authx_offset + authx_len + ret; 974 + 975 + if (len != response->len) { 976 + response->len = len; 977 + response->data_len = len; 978 + } 979 + 980 + csp = rxrpc_skb(challenge); 981 + rsp = rxrpc_skb(response); 982 + rsp->resp.len = len; 983 + rsp->resp.challenge_serial = csp->hdr.serial; 984 + rxrpc_post_response(conn, response); 985 + response = NULL; 986 + ret = 0; 987 + 988 + error: 989 + rxrpc_free_skb(response, rxrpc_skb_put_response); 990 + rxgk_put(gk); 991 + _leave(" = %d", ret); 992 + return ret; 993 + } 994 + 995 + /* 996 + * Respond to a challenge packet. 997 + */ 998 + static int rxgk_respond_to_challenge(struct rxrpc_connection *conn, 999 + struct sk_buff *challenge, 1000 + struct krb5_buffer *appdata) 1001 + { 1002 + _enter("{%d,%x}", conn->debug_id, key_serial(conn->key)); 1003 + 1004 + if (key_validate(conn->key) < 0) 1005 + return rxrpc_abort_conn(conn, NULL, RXGK_EXPIRED, -EPROTO, 1006 + rxgk_abort_chall_key_expired); 1007 + 1008 + return rxgk_construct_response(conn, challenge, appdata); 1009 + } 1010 + 1011 + static int rxgk_respond_to_challenge_no_appdata(struct rxrpc_connection *conn, 1012 + struct sk_buff *challenge) 1013 + { 1014 + struct krb5_buffer appdata = {}; 1015 + 1016 + return rxgk_respond_to_challenge(conn, challenge, &appdata); 1017 + } 1018 + 1019 + /** 1020 + * rxgk_kernel_respond_to_challenge - Respond to a challenge with appdata 1021 + * @challenge: The challenge to respond to 1022 + * @appdata: The application data to include in the RESPONSE authenticator 1023 + * 1024 + * Allow a kernel application to respond to a CHALLENGE with application data 1025 + * to be included in the RxGK RESPONSE Authenticator. 1026 + * 1027 + * Return: %0 if successful and a negative error code otherwise. 1028 + */ 1029 + int rxgk_kernel_respond_to_challenge(struct sk_buff *challenge, 1030 + struct krb5_buffer *appdata) 1031 + { 1032 + struct rxrpc_skb_priv *csp = rxrpc_skb(challenge); 1033 + 1034 + return rxgk_respond_to_challenge(csp->chall.conn, challenge, appdata); 1035 + } 1036 + EXPORT_SYMBOL(rxgk_kernel_respond_to_challenge); 1037 + 1038 + /* 1039 + * Parse sendmsg() control message and respond to challenge. We need to see if 1040 + * there's an appdata to fish out. 1041 + */ 1042 + static int rxgk_sendmsg_respond_to_challenge(struct sk_buff *challenge, 1043 + struct msghdr *msg) 1044 + { 1045 + struct krb5_buffer appdata = {}; 1046 + struct cmsghdr *cmsg; 1047 + 1048 + for_each_cmsghdr(cmsg, msg) { 1049 + if (cmsg->cmsg_level != SOL_RXRPC || 1050 + cmsg->cmsg_type != RXRPC_RESP_RXGK_APPDATA) 1051 + continue; 1052 + if (appdata.data) 1053 + return -EINVAL; 1054 + appdata.data = CMSG_DATA(cmsg); 1055 + appdata.len = cmsg->cmsg_len - sizeof(struct cmsghdr); 1056 + } 1057 + 1058 + return rxgk_kernel_respond_to_challenge(challenge, &appdata); 1059 + } 1060 + 1061 + /* 1062 + * Verify the authenticator. 1063 + * 1064 + * struct RXGK_Authenticator { 1065 + * opaque nonce[20]; 1066 + * opaque appdata<>; 1067 + * RXGK_Level level; 1068 + * unsigned int epoch; 1069 + * unsigned int cid; 1070 + * unsigned int call_numbers<>; 1071 + * }; 1072 + */ 1073 + static int rxgk_do_verify_authenticator(struct rxrpc_connection *conn, 1074 + const struct krb5_enctype *krb5, 1075 + struct sk_buff *skb, 1076 + __be32 *p, __be32 *end) 1077 + { 1078 + u32 app_len, call_count, level, epoch, cid, i; 1079 + 1080 + _enter(""); 1081 + 1082 + if (memcmp(p, conn->rxgk.nonce, 20) != 0) 1083 + return rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EPROTO, 1084 + rxgk_abort_resp_bad_nonce); 1085 + p += 20 / sizeof(__be32); 1086 + 1087 + app_len = ntohl(*p++); 1088 + if (app_len > (end - p) * sizeof(__be32)) 1089 + return rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EPROTO, 1090 + rxgk_abort_resp_short_applen); 1091 + 1092 + p += xdr_round_up(app_len) / sizeof(__be32); 1093 + if (end - p < 4) 1094 + return rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EPROTO, 1095 + rxgk_abort_resp_short_applen); 1096 + 1097 + level = ntohl(*p++); 1098 + epoch = ntohl(*p++); 1099 + cid = ntohl(*p++); 1100 + call_count = ntohl(*p++); 1101 + 1102 + if (level != conn->security_level || 1103 + epoch != conn->proto.epoch || 1104 + cid != conn->proto.cid || 1105 + call_count > 4) 1106 + return rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EPROTO, 1107 + rxgk_abort_resp_bad_param); 1108 + 1109 + if (end - p < call_count) 1110 + return rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EPROTO, 1111 + rxgk_abort_resp_short_call_list); 1112 + 1113 + for (i = 0; i < call_count; i++) { 1114 + u32 call_id = ntohl(*p++); 1115 + 1116 + if (call_id > INT_MAX) 1117 + return rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EPROTO, 1118 + rxgk_abort_resp_bad_callid); 1119 + 1120 + if (call_id < conn->channels[i].call_counter) 1121 + return rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EPROTO, 1122 + rxgk_abort_resp_call_ctr); 1123 + 1124 + if (call_id > conn->channels[i].call_counter) { 1125 + if (conn->channels[i].call) 1126 + return rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EPROTO, 1127 + rxgk_abort_resp_call_state); 1128 + 1129 + conn->channels[i].call_counter = call_id; 1130 + } 1131 + } 1132 + 1133 + _leave(" = 0"); 1134 + return 0; 1135 + } 1136 + 1137 + /* 1138 + * Extract the authenticator and verify it. 1139 + */ 1140 + static int rxgk_verify_authenticator(struct rxrpc_connection *conn, 1141 + const struct krb5_enctype *krb5, 1142 + struct sk_buff *skb, 1143 + unsigned int auth_offset, unsigned int auth_len) 1144 + { 1145 + void *auth; 1146 + __be32 *p; 1147 + int ret; 1148 + 1149 + auth = kmalloc(auth_len, GFP_NOFS); 1150 + if (!auth) 1151 + return -ENOMEM; 1152 + 1153 + ret = skb_copy_bits(skb, auth_offset, auth, auth_len); 1154 + if (ret < 0) { 1155 + ret = rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EPROTO, 1156 + rxgk_abort_resp_short_auth); 1157 + goto error; 1158 + } 1159 + 1160 + p = auth; 1161 + ret = rxgk_do_verify_authenticator(conn, krb5, skb, p, p + auth_len); 1162 + error: 1163 + kfree(auth); 1164 + return ret; 1165 + } 1166 + 1167 + /* 1168 + * Verify a response. 1169 + * 1170 + * struct RXGK_Response { 1171 + * rxgkTime start_time; 1172 + * RXGK_Data token; 1173 + * opaque authenticator<RXGK_MAXAUTHENTICATOR> 1174 + * }; 1175 + */ 1176 + static int rxgk_verify_response(struct rxrpc_connection *conn, 1177 + struct sk_buff *skb) 1178 + { 1179 + const struct krb5_enctype *krb5; 1180 + struct rxrpc_key_token *token; 1181 + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 1182 + struct rxgk_response rhdr; 1183 + struct rxgk_context *gk; 1184 + struct key *key = NULL; 1185 + unsigned int offset = sizeof(struct rxrpc_wire_header); 1186 + unsigned int len = skb->len - sizeof(struct rxrpc_wire_header); 1187 + unsigned int token_offset, token_len; 1188 + unsigned int auth_offset, auth_len; 1189 + __be32 xauth_len; 1190 + int ret, ec; 1191 + 1192 + _enter("{%d}", conn->debug_id); 1193 + 1194 + /* Parse the RXGK_Response object */ 1195 + if (sizeof(rhdr) + sizeof(__be32) > len) 1196 + goto short_packet; 1197 + 1198 + if (skb_copy_bits(skb, offset, &rhdr, sizeof(rhdr)) < 0) 1199 + goto short_packet; 1200 + offset += sizeof(rhdr); 1201 + len -= sizeof(rhdr); 1202 + 1203 + token_offset = offset; 1204 + token_len = ntohl(rhdr.token_len); 1205 + if (xdr_round_up(token_len) + sizeof(__be32) > len) 1206 + goto short_packet; 1207 + 1208 + trace_rxrpc_rx_response(conn, sp->hdr.serial, 0, sp->hdr.cksum, token_len); 1209 + 1210 + offset += xdr_round_up(token_len); 1211 + len -= xdr_round_up(token_len); 1212 + 1213 + if (skb_copy_bits(skb, offset, &xauth_len, sizeof(xauth_len)) < 0) 1214 + goto short_packet; 1215 + offset += sizeof(xauth_len); 1216 + len -= sizeof(xauth_len); 1217 + 1218 + auth_offset = offset; 1219 + auth_len = ntohl(xauth_len); 1220 + if (auth_len < len) 1221 + goto short_packet; 1222 + if (auth_len & 3) 1223 + goto inconsistent; 1224 + if (auth_len < 20 + 9 * 4) 1225 + goto auth_too_short; 1226 + 1227 + /* We need to extract and decrypt the token and instantiate a session 1228 + * key for it. This bit, however, is application-specific. If 1229 + * possible, we use a default parser, but we might end up bumping this 1230 + * to the app to deal with - which might mean a round trip to 1231 + * userspace. 1232 + */ 1233 + ret = rxgk_extract_token(conn, skb, token_offset, token_len, &key); 1234 + if (ret < 0) 1235 + goto out; 1236 + 1237 + /* We now have a key instantiated from the decrypted ticket. We can 1238 + * pass this to the application so that they can parse the ticket 1239 + * content and we can use the session key it contains to derive the 1240 + * keys we need. 1241 + * 1242 + * Note that we have to switch enctype at this point as the enctype of 1243 + * the ticket doesn't necessarily match that of the transport. 1244 + */ 1245 + token = key->payload.data[0]; 1246 + conn->security_level = token->rxgk->level; 1247 + conn->rxgk.start_time = __be64_to_cpu(rhdr.start_time); 1248 + 1249 + gk = rxgk_generate_transport_key(conn, token->rxgk, sp->hdr.cksum, GFP_NOFS); 1250 + if (IS_ERR(gk)) { 1251 + ret = PTR_ERR(gk); 1252 + goto cant_get_token; 1253 + } 1254 + 1255 + krb5 = gk->krb5; 1256 + 1257 + trace_rxrpc_rx_response(conn, sp->hdr.serial, krb5->etype, sp->hdr.cksum, token_len); 1258 + 1259 + /* Decrypt, parse and verify the authenticator. */ 1260 + ret = rxgk_decrypt_skb(krb5, gk->resp_enc, skb, 1261 + &auth_offset, &auth_len, &ec); 1262 + if (ret < 0) { 1263 + rxrpc_abort_conn(conn, skb, RXGK_SEALEDINCON, ret, 1264 + rxgk_abort_resp_auth_dec); 1265 + goto out; 1266 + } 1267 + 1268 + ret = rxgk_verify_authenticator(conn, krb5, skb, auth_offset, auth_len); 1269 + if (ret < 0) 1270 + goto out; 1271 + 1272 + conn->key = key; 1273 + key = NULL; 1274 + ret = 0; 1275 + out: 1276 + key_put(key); 1277 + _leave(" = %d", ret); 1278 + return ret; 1279 + 1280 + inconsistent: 1281 + ret = rxrpc_abort_conn(conn, skb, RXGK_INCONSISTENCY, -EPROTO, 1282 + rxgk_abort_resp_xdr_align); 1283 + goto out; 1284 + auth_too_short: 1285 + ret = rxrpc_abort_conn(conn, skb, RXGK_PACKETSHORT, -EPROTO, 1286 + rxgk_abort_resp_short_auth); 1287 + goto out; 1288 + short_packet: 1289 + ret = rxrpc_abort_conn(conn, skb, RXGK_PACKETSHORT, -EPROTO, 1290 + rxgk_abort_resp_short_packet); 1291 + goto out; 1292 + 1293 + cant_get_token: 1294 + switch (ret) { 1295 + case -ENOMEM: 1296 + goto temporary_error; 1297 + case -EINVAL: 1298 + ret = rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EKEYREJECTED, 1299 + rxgk_abort_resp_internal_error); 1300 + goto out; 1301 + case -ENOPKG: 1302 + ret = rxrpc_abort_conn(conn, skb, KRB5_PROG_KEYTYPE_NOSUPP, 1303 + -EKEYREJECTED, rxgk_abort_resp_nopkg); 1304 + goto out; 1305 + } 1306 + 1307 + temporary_error: 1308 + /* Ignore the response packet if we got a temporary error such as 1309 + * ENOMEM. We just want to send the challenge again. Note that we 1310 + * also come out this way if the ticket decryption fails. 1311 + */ 1312 + goto out; 1313 + } 1314 + 1315 + /* 1316 + * clear the connection security 1317 + */ 1318 + static void rxgk_clear(struct rxrpc_connection *conn) 1319 + { 1320 + int i; 1321 + 1322 + for (i = 0; i < ARRAY_SIZE(conn->rxgk.keys); i++) 1323 + rxgk_put(conn->rxgk.keys[i]); 1324 + } 1325 + 1326 + /* 1327 + * Initialise the RxGK security service. 1328 + */ 1329 + static int rxgk_init(void) 1330 + { 1331 + return 0; 1332 + } 1333 + 1334 + /* 1335 + * Clean up the RxGK security service. 1336 + */ 1337 + static void rxgk_exit(void) 1338 + { 1339 + } 1340 + 1341 + /* 1342 + * RxRPC YFS GSSAPI-based security 1343 + */ 1344 + const struct rxrpc_security rxgk_yfs = { 1345 + .name = "yfs-rxgk", 1346 + .security_index = RXRPC_SECURITY_YFS_RXGK, 1347 + .no_key_abort = RXGK_NOTAUTH, 1348 + .init = rxgk_init, 1349 + .exit = rxgk_exit, 1350 + .preparse_server_key = rxgk_preparse_server_key, 1351 + .free_preparse_server_key = rxgk_free_preparse_server_key, 1352 + .destroy_server_key = rxgk_destroy_server_key, 1353 + .describe_server_key = rxgk_describe_server_key, 1354 + .init_connection_security = rxgk_init_connection_security, 1355 + .alloc_txbuf = rxgk_alloc_txbuf, 1356 + .secure_packet = rxgk_secure_packet, 1357 + .verify_packet = rxgk_verify_packet, 1358 + .free_call_crypto = rxgk_free_call_crypto, 1359 + .issue_challenge = rxgk_issue_challenge, 1360 + .validate_challenge = rxgk_validate_challenge, 1361 + .challenge_to_recvmsg = rxgk_challenge_to_recvmsg, 1362 + .sendmsg_respond_to_challenge = rxgk_sendmsg_respond_to_challenge, 1363 + .respond_to_challenge = rxgk_respond_to_challenge_no_appdata, 1364 + .verify_response = rxgk_verify_response, 1365 + .clear = rxgk_clear, 1366 + .default_decode_ticket = rxgk_yfs_decode_ticket, 1367 + };
+285
net/rxrpc/rxgk_app.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* Application-specific bits for GSSAPI-based RxRPC security 3 + * 4 + * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved. 5 + * Written by David Howells (dhowells@redhat.com) 6 + */ 7 + 8 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 + 10 + #include <linux/net.h> 11 + #include <linux/skbuff.h> 12 + #include <linux/slab.h> 13 + #include <linux/key-type.h> 14 + #include "ar-internal.h" 15 + #include "rxgk_common.h" 16 + 17 + /* 18 + * Decode a default-style YFS ticket in a response and turn it into an 19 + * rxrpc-type key. 20 + * 21 + * struct rxgk_key { 22 + * afs_uint32 enctype; 23 + * opaque key<>; 24 + * }; 25 + * 26 + * struct RXGK_AuthName { 27 + * afs_int32 kind; 28 + * opaque data<AUTHDATAMAX>; 29 + * opaque display<AUTHPRINTABLEMAX>; 30 + * }; 31 + * 32 + * struct RXGK_Token { 33 + * rxgk_key K0; 34 + * RXGK_Level level; 35 + * rxgkTime starttime; 36 + * afs_int32 lifetime; 37 + * afs_int32 bytelife; 38 + * rxgkTime expirationtime; 39 + * struct RXGK_AuthName identities<>; 40 + * }; 41 + */ 42 + int rxgk_yfs_decode_ticket(struct rxrpc_connection *conn, struct sk_buff *skb, 43 + unsigned int ticket_offset, unsigned int ticket_len, 44 + struct key **_key) 45 + { 46 + struct rxrpc_key_token *token; 47 + const struct cred *cred = current_cred(); // TODO - use socket creds 48 + struct key *key; 49 + size_t pre_ticket_len, payload_len; 50 + unsigned int klen, enctype; 51 + void *payload, *ticket; 52 + __be32 *t, *p, *q, tmp[2]; 53 + int ret; 54 + 55 + _enter(""); 56 + 57 + /* Get the session key length */ 58 + ret = skb_copy_bits(skb, ticket_offset, tmp, sizeof(tmp)); 59 + if (ret < 0) 60 + return rxrpc_abort_conn(conn, skb, RXGK_INCONSISTENCY, -EPROTO, 61 + rxgk_abort_resp_short_yfs_klen); 62 + enctype = ntohl(tmp[0]); 63 + klen = ntohl(tmp[1]); 64 + 65 + if (klen > ticket_len - 10 * sizeof(__be32)) 66 + return rxrpc_abort_conn(conn, skb, RXGK_INCONSISTENCY, -EPROTO, 67 + rxgk_abort_resp_short_yfs_key); 68 + 69 + pre_ticket_len = ((5 + 14) * sizeof(__be32) + 70 + xdr_round_up(klen) + 71 + sizeof(__be32)); 72 + payload_len = pre_ticket_len + xdr_round_up(ticket_len); 73 + 74 + payload = kzalloc(payload_len, GFP_NOFS); 75 + if (!payload) 76 + return -ENOMEM; 77 + 78 + /* We need to fill out the XDR form for a key payload that we can pass 79 + * to add_key(). Start by copying in the ticket so that we can parse 80 + * it. 81 + */ 82 + ticket = payload + pre_ticket_len; 83 + ret = skb_copy_bits(skb, ticket_offset, ticket, ticket_len); 84 + if (ret < 0) { 85 + ret = rxrpc_abort_conn(conn, skb, RXGK_INCONSISTENCY, -EPROTO, 86 + rxgk_abort_resp_short_yfs_tkt); 87 + goto error; 88 + } 89 + 90 + /* Fill out the form header. */ 91 + p = payload; 92 + p[0] = htonl(0); /* Flags */ 93 + p[1] = htonl(1); /* len(cellname) */ 94 + p[2] = htonl(0x20000000); /* Cellname " " */ 95 + p[3] = htonl(1); /* #tokens */ 96 + p[4] = htonl(15 * sizeof(__be32) + xdr_round_up(klen) + 97 + xdr_round_up(ticket_len)); /* Token len */ 98 + 99 + /* Now fill in the body. Most of this we can just scrape directly from 100 + * the ticket. 101 + */ 102 + t = ticket + sizeof(__be32) * 2 + xdr_round_up(klen); 103 + q = payload + 5 * sizeof(__be32); 104 + q[0] = htonl(RXRPC_SECURITY_YFS_RXGK); 105 + q[1] = t[1]; /* begintime - msw */ 106 + q[2] = t[2]; /* - lsw */ 107 + q[3] = t[5]; /* endtime - msw */ 108 + q[4] = t[6]; /* - lsw */ 109 + q[5] = 0; /* level - msw */ 110 + q[6] = t[0]; /* - lsw */ 111 + q[7] = 0; /* lifetime - msw */ 112 + q[8] = t[3]; /* - lsw */ 113 + q[9] = 0; /* bytelife - msw */ 114 + q[10] = t[4]; /* - lsw */ 115 + q[11] = 0; /* enctype - msw */ 116 + q[12] = htonl(enctype); /* - lsw */ 117 + q[13] = htonl(klen); /* Key length */ 118 + 119 + q += 14; 120 + 121 + memcpy(q, ticket + sizeof(__be32) * 2, klen); 122 + q += xdr_round_up(klen) / 4; 123 + q[0] = htonl(ticket_len); 124 + q++; 125 + if (WARN_ON((unsigned long)q != (unsigned long)ticket)) { 126 + ret = -EIO; 127 + goto error; 128 + } 129 + 130 + /* Ticket read in with skb_copy_bits above */ 131 + q += xdr_round_up(ticket_len) / 4; 132 + if (WARN_ON((unsigned long)q - (unsigned long)payload != payload_len)) { 133 + ret = -EIO; 134 + goto error; 135 + } 136 + 137 + /* Now turn that into a key. */ 138 + key = key_alloc(&key_type_rxrpc, "x", 139 + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, // TODO: Use socket owner 140 + KEY_USR_VIEW, 141 + KEY_ALLOC_NOT_IN_QUOTA, NULL); 142 + if (IS_ERR(key)) { 143 + _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); 144 + goto error; 145 + } 146 + 147 + _debug("key %d", key_serial(key)); 148 + 149 + ret = key_instantiate_and_link(key, payload, payload_len, NULL, NULL); 150 + if (ret < 0) 151 + goto error_key; 152 + 153 + token = key->payload.data[0]; 154 + token->no_leak_key = true; 155 + *_key = key; 156 + key = NULL; 157 + ret = 0; 158 + goto error; 159 + 160 + error_key: 161 + key_put(key); 162 + error: 163 + kfree_sensitive(payload); 164 + _leave(" = %d", ret); 165 + return ret; 166 + } 167 + 168 + /* 169 + * Extract the token and set up a session key from the details. 170 + * 171 + * struct RXGK_TokenContainer { 172 + * afs_int32 kvno; 173 + * afs_int32 enctype; 174 + * opaque encrypted_token<>; 175 + * }; 176 + * 177 + * [tools.ietf.org/html/draft-wilkinson-afs3-rxgk-afs-08 sec 6.1] 178 + */ 179 + int rxgk_extract_token(struct rxrpc_connection *conn, struct sk_buff *skb, 180 + unsigned int token_offset, unsigned int token_len, 181 + struct key **_key) 182 + { 183 + const struct krb5_enctype *krb5; 184 + const struct krb5_buffer *server_secret; 185 + struct crypto_aead *token_enc = NULL; 186 + struct key *server_key; 187 + unsigned int ticket_offset, ticket_len; 188 + u32 kvno, enctype; 189 + int ret, ec; 190 + 191 + struct { 192 + __be32 kvno; 193 + __be32 enctype; 194 + __be32 token_len; 195 + } container; 196 + 197 + /* Decode the RXGK_TokenContainer object. This tells us which server 198 + * key we should be using. We can then fetch the key, get the secret 199 + * and set up the crypto to extract the token. 200 + */ 201 + if (skb_copy_bits(skb, token_offset, &container, sizeof(container)) < 0) 202 + return rxrpc_abort_conn(conn, skb, RXGK_PACKETSHORT, -EPROTO, 203 + rxgk_abort_resp_tok_short); 204 + 205 + kvno = ntohl(container.kvno); 206 + enctype = ntohl(container.enctype); 207 + ticket_len = ntohl(container.token_len); 208 + ticket_offset = token_offset + sizeof(container); 209 + 210 + if (xdr_round_up(ticket_len) > token_len - 3 * 4) 211 + return rxrpc_abort_conn(conn, skb, RXGK_PACKETSHORT, -EPROTO, 212 + rxgk_abort_resp_tok_short); 213 + 214 + _debug("KVNO %u", kvno); 215 + _debug("ENC %u", enctype); 216 + _debug("TLEN %u", ticket_len); 217 + 218 + server_key = rxrpc_look_up_server_security(conn, skb, kvno, enctype); 219 + if (IS_ERR(server_key)) 220 + goto cant_get_server_key; 221 + 222 + down_read(&server_key->sem); 223 + server_secret = (const void *)&server_key->payload.data[2]; 224 + ret = rxgk_set_up_token_cipher(server_secret, &token_enc, enctype, &krb5, GFP_NOFS); 225 + up_read(&server_key->sem); 226 + key_put(server_key); 227 + if (ret < 0) 228 + goto cant_get_token; 229 + 230 + /* We can now decrypt and parse the token/ticket. This allows us to 231 + * gain access to K0, from which we can derive the transport key and 232 + * thence decode the authenticator. 233 + */ 234 + ret = rxgk_decrypt_skb(krb5, token_enc, skb, 235 + &ticket_offset, &ticket_len, &ec); 236 + crypto_free_aead(token_enc); 237 + token_enc = NULL; 238 + if (ret < 0) 239 + return rxrpc_abort_conn(conn, skb, ec, ret, 240 + rxgk_abort_resp_tok_dec); 241 + 242 + ret = conn->security->default_decode_ticket(conn, skb, ticket_offset, 243 + ticket_len, _key); 244 + if (ret < 0) 245 + goto cant_get_token; 246 + 247 + _leave(" = 0"); 248 + return ret; 249 + 250 + cant_get_server_key: 251 + ret = PTR_ERR(server_key); 252 + switch (ret) { 253 + case -ENOMEM: 254 + goto temporary_error; 255 + case -ENOKEY: 256 + case -EKEYREJECTED: 257 + case -EKEYEXPIRED: 258 + case -EKEYREVOKED: 259 + case -EPERM: 260 + return rxrpc_abort_conn(conn, skb, RXGK_BADKEYNO, -EKEYREJECTED, 261 + rxgk_abort_resp_tok_nokey); 262 + default: 263 + return rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EKEYREJECTED, 264 + rxgk_abort_resp_tok_keyerr); 265 + } 266 + 267 + cant_get_token: 268 + switch (ret) { 269 + case -ENOMEM: 270 + goto temporary_error; 271 + case -EINVAL: 272 + return rxrpc_abort_conn(conn, skb, RXGK_NOTAUTH, -EKEYREJECTED, 273 + rxgk_abort_resp_tok_internal_error); 274 + case -ENOPKG: 275 + return rxrpc_abort_conn(conn, skb, KRB5_PROG_KEYTYPE_NOSUPP, 276 + -EKEYREJECTED, rxgk_abort_resp_tok_nopkg); 277 + } 278 + 279 + temporary_error: 280 + /* Ignore the response packet if we got a temporary error such as 281 + * ENOMEM. We just want to send the challenge again. Note that we 282 + * also come out this way if the ticket decryption fails. 283 + */ 284 + return ret; 285 + }
+139
net/rxrpc/rxgk_common.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* Common bits for GSSAPI-based RxRPC security. 3 + * 4 + * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved. 5 + * Written by David Howells (dhowells@redhat.com) 6 + */ 7 + 8 + #include <crypto/krb5.h> 9 + #include <crypto/skcipher.h> 10 + #include <crypto/hash.h> 11 + 12 + /* 13 + * Per-key number context. This is replaced when the connection is rekeyed. 14 + */ 15 + struct rxgk_context { 16 + refcount_t usage; 17 + unsigned int key_number; /* Rekeying number (goes in the rx header) */ 18 + unsigned long flags; 19 + #define RXGK_TK_NEEDS_REKEY 0 /* Set if this needs rekeying */ 20 + unsigned long expiry; /* Expiration time of this key */ 21 + long long bytes_remaining; /* Remaining Tx lifetime of this key */ 22 + const struct krb5_enctype *krb5; /* RxGK encryption type */ 23 + const struct rxgk_key *key; 24 + 25 + /* We need up to 7 keys derived from the transport key, but we don't 26 + * actually need the transport key. Each key is derived by 27 + * DK(TK,constant). 28 + */ 29 + struct crypto_aead *tx_enc; /* Transmission key */ 30 + struct crypto_aead *rx_enc; /* Reception key */ 31 + struct crypto_shash *tx_Kc; /* Transmission checksum key */ 32 + struct crypto_shash *rx_Kc; /* Reception checksum key */ 33 + struct crypto_aead *resp_enc; /* Response packet enc key */ 34 + }; 35 + 36 + #define xdr_round_up(x) (round_up((x), sizeof(__be32))) 37 + #define xdr_object_len(x) (4 + xdr_round_up(x)) 38 + 39 + /* 40 + * rxgk_app.c 41 + */ 42 + int rxgk_yfs_decode_ticket(struct rxrpc_connection *conn, struct sk_buff *skb, 43 + unsigned int ticket_offset, unsigned int ticket_len, 44 + struct key **_key); 45 + int rxgk_extract_token(struct rxrpc_connection *conn, struct sk_buff *skb, 46 + unsigned int token_offset, unsigned int token_len, 47 + struct key **_key); 48 + 49 + /* 50 + * rxgk_kdf.c 51 + */ 52 + void rxgk_put(struct rxgk_context *gk); 53 + struct rxgk_context *rxgk_generate_transport_key(struct rxrpc_connection *conn, 54 + const struct rxgk_key *key, 55 + unsigned int key_number, 56 + gfp_t gfp); 57 + int rxgk_set_up_token_cipher(const struct krb5_buffer *server_key, 58 + struct crypto_aead **token_key, 59 + unsigned int enctype, 60 + const struct krb5_enctype **_krb5, 61 + gfp_t gfp); 62 + 63 + /* 64 + * Apply decryption and checksumming functions to part of an skbuff. The 65 + * offset and length are updated to reflect the actual content of the encrypted 66 + * region. 67 + */ 68 + static inline 69 + int rxgk_decrypt_skb(const struct krb5_enctype *krb5, 70 + struct crypto_aead *aead, 71 + struct sk_buff *skb, 72 + unsigned int *_offset, unsigned int *_len, 73 + int *_error_code) 74 + { 75 + struct scatterlist sg[16]; 76 + size_t offset = 0, len = *_len; 77 + int nr_sg, ret; 78 + 79 + sg_init_table(sg, ARRAY_SIZE(sg)); 80 + nr_sg = skb_to_sgvec(skb, sg, *_offset, len); 81 + if (unlikely(nr_sg < 0)) 82 + return nr_sg; 83 + 84 + ret = crypto_krb5_decrypt(krb5, aead, sg, nr_sg, 85 + &offset, &len); 86 + switch (ret) { 87 + case 0: 88 + *_offset += offset; 89 + *_len = len; 90 + break; 91 + case -EPROTO: 92 + case -EBADMSG: 93 + *_error_code = RXGK_SEALEDINCON; 94 + break; 95 + default: 96 + break; 97 + } 98 + 99 + return ret; 100 + } 101 + 102 + /* 103 + * Check the MIC on a region of an skbuff. The offset and length are updated 104 + * to reflect the actual content of the secure region. 105 + */ 106 + static inline 107 + int rxgk_verify_mic_skb(const struct krb5_enctype *krb5, 108 + struct crypto_shash *shash, 109 + const struct krb5_buffer *metadata, 110 + struct sk_buff *skb, 111 + unsigned int *_offset, unsigned int *_len, 112 + u32 *_error_code) 113 + { 114 + struct scatterlist sg[16]; 115 + size_t offset = 0, len = *_len; 116 + int nr_sg, ret; 117 + 118 + sg_init_table(sg, ARRAY_SIZE(sg)); 119 + nr_sg = skb_to_sgvec(skb, sg, *_offset, len); 120 + if (unlikely(nr_sg < 0)) 121 + return nr_sg; 122 + 123 + ret = crypto_krb5_verify_mic(krb5, shash, metadata, sg, nr_sg, 124 + &offset, &len); 125 + switch (ret) { 126 + case 0: 127 + *_offset += offset; 128 + *_len = len; 129 + break; 130 + case -EPROTO: 131 + case -EBADMSG: 132 + *_error_code = RXGK_SEALEDINCON; 133 + break; 134 + default: 135 + break; 136 + } 137 + 138 + return ret; 139 + }
+288
net/rxrpc/rxgk_kdf.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* RxGK transport key derivation. 3 + * 4 + * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved. 5 + * Written by David Howells (dhowells@redhat.com) 6 + */ 7 + 8 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 + 10 + #include <linux/key-type.h> 11 + #include <linux/slab.h> 12 + #include <keys/rxrpc-type.h> 13 + #include "ar-internal.h" 14 + #include "rxgk_common.h" 15 + 16 + #define round16(x) (((x) + 15) & ~15) 17 + 18 + /* 19 + * Constants used to derive the keys and hmacs actually used for doing stuff. 20 + */ 21 + #define RXGK_CLIENT_ENC_PACKET 1026U // 0x402 22 + #define RXGK_CLIENT_MIC_PACKET 1027U // 0x403 23 + #define RXGK_SERVER_ENC_PACKET 1028U // 0x404 24 + #define RXGK_SERVER_MIC_PACKET 1029U // 0x405 25 + #define RXGK_CLIENT_ENC_RESPONSE 1030U // 0x406 26 + #define RXGK_SERVER_ENC_TOKEN 1036U // 0x40c 27 + 28 + static void rxgk_free(struct rxgk_context *gk) 29 + { 30 + if (gk->tx_Kc) 31 + crypto_free_shash(gk->tx_Kc); 32 + if (gk->rx_Kc) 33 + crypto_free_shash(gk->rx_Kc); 34 + if (gk->tx_enc) 35 + crypto_free_aead(gk->tx_enc); 36 + if (gk->rx_enc) 37 + crypto_free_aead(gk->rx_enc); 38 + if (gk->resp_enc) 39 + crypto_free_aead(gk->resp_enc); 40 + kfree(gk); 41 + } 42 + 43 + void rxgk_put(struct rxgk_context *gk) 44 + { 45 + if (gk && refcount_dec_and_test(&gk->usage)) 46 + rxgk_free(gk); 47 + } 48 + 49 + /* 50 + * Transport key derivation function. 51 + * 52 + * TK = random-to-key(PRF+(K0, L, 53 + * epoch || cid || start_time || key_number)) 54 + * [tools.ietf.org/html/draft-wilkinson-afs3-rxgk-11 sec 8.3] 55 + */ 56 + static int rxgk_derive_transport_key(struct rxrpc_connection *conn, 57 + struct rxgk_context *gk, 58 + const struct rxgk_key *rxgk, 59 + struct krb5_buffer *TK, 60 + gfp_t gfp) 61 + { 62 + const struct krb5_enctype *krb5 = gk->krb5; 63 + struct krb5_buffer conn_info; 64 + unsigned int L = krb5->key_bytes; 65 + __be32 *info; 66 + u8 *buffer; 67 + int ret; 68 + 69 + _enter(""); 70 + 71 + conn_info.len = sizeof(__be32) * 5; 72 + 73 + buffer = kzalloc(round16(conn_info.len), gfp); 74 + if (!buffer) 75 + return -ENOMEM; 76 + 77 + conn_info.data = buffer; 78 + 79 + info = (__be32 *)conn_info.data; 80 + info[0] = htonl(conn->proto.epoch); 81 + info[1] = htonl(conn->proto.cid); 82 + info[2] = htonl(conn->rxgk.start_time >> 32); 83 + info[3] = htonl(conn->rxgk.start_time >> 0); 84 + info[4] = htonl(gk->key_number); 85 + 86 + ret = crypto_krb5_calc_PRFplus(krb5, &rxgk->key, L, &conn_info, TK, gfp); 87 + kfree_sensitive(buffer); 88 + _leave(" = %d", ret); 89 + return ret; 90 + } 91 + 92 + /* 93 + * Set up the ciphers for the usage keys. 94 + */ 95 + static int rxgk_set_up_ciphers(struct rxrpc_connection *conn, 96 + struct rxgk_context *gk, 97 + const struct rxgk_key *rxgk, 98 + gfp_t gfp) 99 + { 100 + const struct krb5_enctype *krb5 = gk->krb5; 101 + struct crypto_shash *shash; 102 + struct crypto_aead *aead; 103 + struct krb5_buffer TK; 104 + bool service = rxrpc_conn_is_service(conn); 105 + int ret; 106 + u8 *buffer; 107 + 108 + buffer = kzalloc(krb5->key_bytes, gfp); 109 + if (!buffer) 110 + return -ENOMEM; 111 + 112 + TK.len = krb5->key_bytes; 113 + TK.data = buffer; 114 + 115 + ret = rxgk_derive_transport_key(conn, gk, rxgk, &TK, gfp); 116 + if (ret < 0) 117 + goto out; 118 + 119 + aead = crypto_krb5_prepare_encryption(krb5, &TK, RXGK_CLIENT_ENC_RESPONSE, gfp); 120 + if (IS_ERR(aead)) 121 + goto aead_error; 122 + gk->resp_enc = aead; 123 + 124 + if (crypto_aead_blocksize(gk->resp_enc) != krb5->block_len || 125 + crypto_aead_authsize(gk->resp_enc) != krb5->cksum_len) { 126 + pr_notice("algo inconsistent with krb5 table %u!=%u or %u!=%u\n", 127 + crypto_aead_blocksize(gk->resp_enc), krb5->block_len, 128 + crypto_aead_authsize(gk->resp_enc), krb5->cksum_len); 129 + ret = -EINVAL; 130 + goto out; 131 + } 132 + 133 + if (service) { 134 + switch (conn->security_level) { 135 + case RXRPC_SECURITY_AUTH: 136 + shash = crypto_krb5_prepare_checksum( 137 + krb5, &TK, RXGK_SERVER_MIC_PACKET, gfp); 138 + if (IS_ERR(shash)) 139 + goto hash_error; 140 + gk->tx_Kc = shash; 141 + shash = crypto_krb5_prepare_checksum( 142 + krb5, &TK, RXGK_CLIENT_MIC_PACKET, gfp); 143 + if (IS_ERR(shash)) 144 + goto hash_error; 145 + gk->rx_Kc = shash; 146 + break; 147 + case RXRPC_SECURITY_ENCRYPT: 148 + aead = crypto_krb5_prepare_encryption( 149 + krb5, &TK, RXGK_SERVER_ENC_PACKET, gfp); 150 + if (IS_ERR(aead)) 151 + goto aead_error; 152 + gk->tx_enc = aead; 153 + aead = crypto_krb5_prepare_encryption( 154 + krb5, &TK, RXGK_CLIENT_ENC_PACKET, gfp); 155 + if (IS_ERR(aead)) 156 + goto aead_error; 157 + gk->rx_enc = aead; 158 + break; 159 + } 160 + } else { 161 + switch (conn->security_level) { 162 + case RXRPC_SECURITY_AUTH: 163 + shash = crypto_krb5_prepare_checksum( 164 + krb5, &TK, RXGK_CLIENT_MIC_PACKET, gfp); 165 + if (IS_ERR(shash)) 166 + goto hash_error; 167 + gk->tx_Kc = shash; 168 + shash = crypto_krb5_prepare_checksum( 169 + krb5, &TK, RXGK_SERVER_MIC_PACKET, gfp); 170 + if (IS_ERR(shash)) 171 + goto hash_error; 172 + gk->rx_Kc = shash; 173 + break; 174 + case RXRPC_SECURITY_ENCRYPT: 175 + aead = crypto_krb5_prepare_encryption( 176 + krb5, &TK, RXGK_CLIENT_ENC_PACKET, gfp); 177 + if (IS_ERR(aead)) 178 + goto aead_error; 179 + gk->tx_enc = aead; 180 + aead = crypto_krb5_prepare_encryption( 181 + krb5, &TK, RXGK_SERVER_ENC_PACKET, gfp); 182 + if (IS_ERR(aead)) 183 + goto aead_error; 184 + gk->rx_enc = aead; 185 + break; 186 + } 187 + } 188 + 189 + ret = 0; 190 + out: 191 + kfree_sensitive(buffer); 192 + return ret; 193 + aead_error: 194 + ret = PTR_ERR(aead); 195 + goto out; 196 + hash_error: 197 + ret = PTR_ERR(shash); 198 + goto out; 199 + } 200 + 201 + /* 202 + * Derive a transport key for a connection and then derive a bunch of usage 203 + * keys from it and set up ciphers using them. 204 + */ 205 + struct rxgk_context *rxgk_generate_transport_key(struct rxrpc_connection *conn, 206 + const struct rxgk_key *key, 207 + unsigned int key_number, 208 + gfp_t gfp) 209 + { 210 + struct rxgk_context *gk; 211 + unsigned long lifetime; 212 + int ret = -ENOPKG; 213 + 214 + _enter(""); 215 + 216 + gk = kzalloc(sizeof(*gk), GFP_KERNEL); 217 + if (!gk) 218 + return ERR_PTR(-ENOMEM); 219 + refcount_set(&gk->usage, 1); 220 + gk->key = key; 221 + gk->key_number = key_number; 222 + 223 + gk->krb5 = crypto_krb5_find_enctype(key->enctype); 224 + if (!gk->krb5) 225 + goto err_tk; 226 + 227 + ret = rxgk_set_up_ciphers(conn, gk, key, gfp); 228 + if (ret) 229 + goto err_tk; 230 + 231 + /* Set the remaining number of bytes encrypted with this key that may 232 + * be transmitted before rekeying. Note that the spec has been 233 + * interpreted differently on this point... 234 + */ 235 + switch (key->bytelife) { 236 + case 0: 237 + case 63: 238 + gk->bytes_remaining = LLONG_MAX; 239 + break; 240 + case 1 ... 62: 241 + gk->bytes_remaining = 1LL << key->bytelife; 242 + break; 243 + default: 244 + gk->bytes_remaining = key->bytelife; 245 + break; 246 + } 247 + 248 + /* Set the time after which rekeying must occur */ 249 + if (key->lifetime) { 250 + lifetime = min_t(u64, key->lifetime, INT_MAX / HZ); 251 + lifetime *= HZ; 252 + } else { 253 + lifetime = MAX_JIFFY_OFFSET; 254 + } 255 + gk->expiry = jiffies + lifetime; 256 + return gk; 257 + 258 + err_tk: 259 + rxgk_put(gk); 260 + _leave(" = %d", ret); 261 + return ERR_PTR(ret); 262 + } 263 + 264 + /* 265 + * Use the server secret key to set up the ciphers that will be used to extract 266 + * the token from a response packet. 267 + */ 268 + int rxgk_set_up_token_cipher(const struct krb5_buffer *server_key, 269 + struct crypto_aead **token_aead, 270 + unsigned int enctype, 271 + const struct krb5_enctype **_krb5, 272 + gfp_t gfp) 273 + { 274 + const struct krb5_enctype *krb5; 275 + struct crypto_aead *aead; 276 + 277 + krb5 = crypto_krb5_find_enctype(enctype); 278 + if (!krb5) 279 + return -ENOPKG; 280 + 281 + aead = crypto_krb5_prepare_encryption(krb5, server_key, RXGK_SERVER_ENC_TOKEN, gfp); 282 + if (IS_ERR(aead)) 283 + return PTR_ERR(aead); 284 + 285 + *_krb5 = krb5; 286 + *token_aead = aead; 287 + return 0; 288 + }
+190 -114
net/rxrpc/rxkad.c
··· 177 177 if (!txb) 178 178 return NULL; 179 179 180 - txb->offset += shdr; 181 - txb->space = part; 180 + txb->crypto_header = 0; 181 + txb->sec_header = shdr; 182 + txb->offset += shdr; 183 + txb->space = part; 182 184 return txb; 183 185 } 184 186 ··· 685 683 serial = rxrpc_get_next_serial(conn); 686 684 whdr.serial = htonl(serial); 687 685 686 + trace_rxrpc_tx_challenge(conn, serial, 0, conn->rxkad.nonce); 687 + 688 688 ret = kernel_sendmsg(conn->local->socket, &msg, iov, 2, len); 689 689 if (ret < 0) { 690 690 trace_rxrpc_tx_fail(conn->debug_id, serial, ret, ··· 697 693 conn->peer->last_tx_at = ktime_get_seconds(); 698 694 trace_rxrpc_tx_packet(conn->debug_id, &whdr, 699 695 rxrpc_tx_point_rxkad_challenge); 700 - _leave(" = 0"); 701 - return 0; 702 - } 703 - 704 - /* 705 - * send a Kerberos security response 706 - */ 707 - static int rxkad_send_response(struct rxrpc_connection *conn, 708 - struct rxrpc_host_header *hdr, 709 - struct rxkad_response *resp, 710 - const struct rxkad_key *s2) 711 - { 712 - struct rxrpc_wire_header whdr; 713 - struct msghdr msg; 714 - struct kvec iov[3]; 715 - size_t len; 716 - u32 serial; 717 - int ret; 718 - 719 - _enter(""); 720 - 721 - msg.msg_name = &conn->peer->srx.transport; 722 - msg.msg_namelen = conn->peer->srx.transport_len; 723 - msg.msg_control = NULL; 724 - msg.msg_controllen = 0; 725 - msg.msg_flags = 0; 726 - 727 - memset(&whdr, 0, sizeof(whdr)); 728 - whdr.epoch = htonl(hdr->epoch); 729 - whdr.cid = htonl(hdr->cid); 730 - whdr.type = RXRPC_PACKET_TYPE_RESPONSE; 731 - whdr.flags = conn->out_clientflag; 732 - whdr.securityIndex = hdr->securityIndex; 733 - whdr.serviceId = htons(hdr->serviceId); 734 - 735 - iov[0].iov_base = &whdr; 736 - iov[0].iov_len = sizeof(whdr); 737 - iov[1].iov_base = resp; 738 - iov[1].iov_len = sizeof(*resp); 739 - iov[2].iov_base = (void *)s2->ticket; 740 - iov[2].iov_len = s2->ticket_len; 741 - 742 - len = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len; 743 - 744 - serial = rxrpc_get_next_serial(conn); 745 - whdr.serial = htonl(serial); 746 - 747 - rxrpc_local_dont_fragment(conn->local, false); 748 - ret = kernel_sendmsg(conn->local->socket, &msg, iov, 3, len); 749 - if (ret < 0) { 750 - trace_rxrpc_tx_fail(conn->debug_id, serial, ret, 751 - rxrpc_tx_point_rxkad_response); 752 - return -EAGAIN; 753 - } 754 - 755 - conn->peer->last_tx_at = ktime_get_seconds(); 756 696 _leave(" = 0"); 757 697 return 0; 758 698 } ··· 720 772 * encrypt the response packet 721 773 */ 722 774 static int rxkad_encrypt_response(struct rxrpc_connection *conn, 723 - struct rxkad_response *resp, 775 + struct sk_buff *response, 724 776 const struct rxkad_key *s2) 725 777 { 726 778 struct skcipher_request *req; 727 779 struct rxrpc_crypt iv; 728 780 struct scatterlist sg[1]; 781 + size_t encsize = sizeof(((struct rxkad_response *)0)->encrypted); 782 + int ret; 783 + 784 + sg_init_table(sg, ARRAY_SIZE(sg)); 785 + ret = skb_to_sgvec(response, sg, 786 + sizeof(struct rxrpc_wire_header) + 787 + offsetof(struct rxkad_response, encrypted), encsize); 788 + if (ret < 0) 789 + return ret; 729 790 730 791 req = skcipher_request_alloc(&conn->rxkad.cipher->base, GFP_NOFS); 731 792 if (!req) ··· 743 786 /* continue encrypting from where we left off */ 744 787 memcpy(&iv, s2->session_key, sizeof(iv)); 745 788 746 - sg_init_table(sg, 1); 747 - sg_set_buf(sg, &resp->encrypted, sizeof(resp->encrypted)); 748 789 skcipher_request_set_sync_tfm(req, conn->rxkad.cipher); 749 790 skcipher_request_set_callback(req, 0, NULL, NULL); 750 - skcipher_request_set_crypt(req, sg, sg, sizeof(resp->encrypted), iv.x); 751 - crypto_skcipher_encrypt(req); 791 + skcipher_request_set_crypt(req, sg, sg, encsize, iv.x); 792 + ret = crypto_skcipher_encrypt(req); 752 793 skcipher_request_free(req); 753 - return 0; 794 + return ret; 795 + } 796 + 797 + /* 798 + * Validate a challenge packet. 799 + */ 800 + static bool rxkad_validate_challenge(struct rxrpc_connection *conn, 801 + struct sk_buff *skb) 802 + { 803 + struct rxkad_challenge challenge; 804 + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 805 + u32 version, min_level; 806 + int ret; 807 + 808 + _enter("{%d,%x}", conn->debug_id, key_serial(conn->key)); 809 + 810 + if (!conn->key) { 811 + rxrpc_abort_conn(conn, skb, RX_PROTOCOL_ERROR, -EPROTO, 812 + rxkad_abort_chall_no_key); 813 + return false; 814 + } 815 + 816 + ret = key_validate(conn->key); 817 + if (ret < 0) { 818 + rxrpc_abort_conn(conn, skb, RXKADEXPIRED, ret, 819 + rxkad_abort_chall_key_expired); 820 + return false; 821 + } 822 + 823 + if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header), 824 + &challenge, sizeof(challenge)) < 0) { 825 + rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO, 826 + rxkad_abort_chall_short); 827 + return false; 828 + } 829 + 830 + version = ntohl(challenge.version); 831 + sp->chall.rxkad_nonce = ntohl(challenge.nonce); 832 + min_level = ntohl(challenge.min_level); 833 + 834 + trace_rxrpc_rx_challenge(conn, sp->hdr.serial, version, 835 + sp->chall.rxkad_nonce, min_level); 836 + 837 + if (version != RXKAD_VERSION) { 838 + rxrpc_abort_conn(conn, skb, RXKADINCONSISTENCY, -EPROTO, 839 + rxkad_abort_chall_version); 840 + return false; 841 + } 842 + 843 + if (conn->security_level < min_level) { 844 + rxrpc_abort_conn(conn, skb, RXKADLEVELFAIL, -EACCES, 845 + rxkad_abort_chall_level); 846 + return false; 847 + } 848 + return true; 849 + } 850 + 851 + /* 852 + * Insert the header into the response. 853 + */ 854 + static noinline 855 + int rxkad_insert_response_header(struct rxrpc_connection *conn, 856 + const struct rxrpc_key_token *token, 857 + struct sk_buff *challenge, 858 + struct sk_buff *response, 859 + size_t *offset) 860 + { 861 + struct rxrpc_skb_priv *csp = rxrpc_skb(challenge); 862 + struct { 863 + struct rxrpc_wire_header whdr; 864 + struct rxkad_response resp; 865 + } h; 866 + int ret; 867 + 868 + h.whdr.epoch = htonl(conn->proto.epoch); 869 + h.whdr.cid = htonl(conn->proto.cid); 870 + h.whdr.callNumber = 0; 871 + h.whdr.serial = 0; 872 + h.whdr.seq = 0; 873 + h.whdr.type = RXRPC_PACKET_TYPE_RESPONSE; 874 + h.whdr.flags = conn->out_clientflag; 875 + h.whdr.userStatus = 0; 876 + h.whdr.securityIndex = conn->security_ix; 877 + h.whdr.cksum = 0; 878 + h.whdr.serviceId = htons(conn->service_id); 879 + h.resp.version = htonl(RXKAD_VERSION); 880 + h.resp.__pad = 0; 881 + h.resp.encrypted.epoch = htonl(conn->proto.epoch); 882 + h.resp.encrypted.cid = htonl(conn->proto.cid); 883 + h.resp.encrypted.checksum = 0; 884 + h.resp.encrypted.securityIndex = htonl(conn->security_ix); 885 + h.resp.encrypted.call_id[0] = htonl(conn->channels[0].call_counter); 886 + h.resp.encrypted.call_id[1] = htonl(conn->channels[1].call_counter); 887 + h.resp.encrypted.call_id[2] = htonl(conn->channels[2].call_counter); 888 + h.resp.encrypted.call_id[3] = htonl(conn->channels[3].call_counter); 889 + h.resp.encrypted.inc_nonce = htonl(csp->chall.rxkad_nonce + 1); 890 + h.resp.encrypted.level = htonl(conn->security_level); 891 + h.resp.kvno = htonl(token->kad->kvno); 892 + h.resp.ticket_len = htonl(token->kad->ticket_len); 893 + 894 + rxkad_calc_response_checksum(&h.resp); 895 + 896 + ret = skb_store_bits(response, *offset, &h, sizeof(h)); 897 + *offset += sizeof(h); 898 + return ret; 754 899 } 755 900 756 901 /* 757 902 * respond to a challenge packet 758 903 */ 759 904 static int rxkad_respond_to_challenge(struct rxrpc_connection *conn, 760 - struct sk_buff *skb) 905 + struct sk_buff *challenge) 761 906 { 762 907 const struct rxrpc_key_token *token; 763 - struct rxkad_challenge challenge; 764 - struct rxkad_response *resp; 765 - struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 766 - u32 version, nonce, min_level; 908 + struct rxrpc_skb_priv *csp, *rsp; 909 + struct sk_buff *response; 910 + size_t len, offset = 0; 767 911 int ret = -EPROTO; 768 912 769 913 _enter("{%d,%x}", conn->debug_id, key_serial(conn->key)); 770 914 771 - if (!conn->key) 772 - return rxrpc_abort_conn(conn, skb, RX_PROTOCOL_ERROR, -EPROTO, 773 - rxkad_abort_chall_no_key); 774 - 775 915 ret = key_validate(conn->key); 776 916 if (ret < 0) 777 - return rxrpc_abort_conn(conn, skb, RXKADEXPIRED, ret, 917 + return rxrpc_abort_conn(conn, challenge, RXKADEXPIRED, ret, 778 918 rxkad_abort_chall_key_expired); 779 - 780 - if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header), 781 - &challenge, sizeof(challenge)) < 0) 782 - return rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO, 783 - rxkad_abort_chall_short); 784 - 785 - version = ntohl(challenge.version); 786 - nonce = ntohl(challenge.nonce); 787 - min_level = ntohl(challenge.min_level); 788 - 789 - trace_rxrpc_rx_challenge(conn, sp->hdr.serial, version, nonce, min_level); 790 - 791 - if (version != RXKAD_VERSION) 792 - return rxrpc_abort_conn(conn, skb, RXKADINCONSISTENCY, -EPROTO, 793 - rxkad_abort_chall_version); 794 - 795 - if (conn->security_level < min_level) 796 - return rxrpc_abort_conn(conn, skb, RXKADLEVELFAIL, -EACCES, 797 - rxkad_abort_chall_level); 798 919 799 920 token = conn->key->payload.data[0]; 800 921 801 922 /* build the response packet */ 802 - resp = kzalloc(sizeof(struct rxkad_response), GFP_NOFS); 803 - if (!resp) 804 - return -ENOMEM; 923 + len = sizeof(struct rxrpc_wire_header) + 924 + sizeof(struct rxkad_response) + 925 + token->kad->ticket_len; 805 926 806 - resp->version = htonl(RXKAD_VERSION); 807 - resp->encrypted.epoch = htonl(conn->proto.epoch); 808 - resp->encrypted.cid = htonl(conn->proto.cid); 809 - resp->encrypted.securityIndex = htonl(conn->security_ix); 810 - resp->encrypted.inc_nonce = htonl(nonce + 1); 811 - resp->encrypted.level = htonl(conn->security_level); 812 - resp->kvno = htonl(token->kad->kvno); 813 - resp->ticket_len = htonl(token->kad->ticket_len); 814 - resp->encrypted.call_id[0] = htonl(conn->channels[0].call_counter); 815 - resp->encrypted.call_id[1] = htonl(conn->channels[1].call_counter); 816 - resp->encrypted.call_id[2] = htonl(conn->channels[2].call_counter); 817 - resp->encrypted.call_id[3] = htonl(conn->channels[3].call_counter); 927 + response = alloc_skb_with_frags(0, len, 0, &ret, GFP_NOFS); 928 + if (!response) 929 + goto error; 930 + rxrpc_new_skb(response, rxrpc_skb_new_response_rxkad); 931 + response->len = len; 932 + response->data_len = len; 818 933 819 - /* calculate the response checksum and then do the encryption */ 820 - rxkad_calc_response_checksum(resp); 821 - ret = rxkad_encrypt_response(conn, resp, token->kad); 822 - if (ret == 0) 823 - ret = rxkad_send_response(conn, &sp->hdr, resp, token->kad); 824 - kfree(resp); 934 + offset = 0; 935 + ret = rxkad_insert_response_header(conn, token, challenge, response, 936 + &offset); 937 + if (ret < 0) 938 + goto error; 939 + 940 + ret = rxkad_encrypt_response(conn, response, token->kad); 941 + if (ret < 0) 942 + goto error; 943 + 944 + ret = skb_store_bits(response, offset, token->kad->ticket, 945 + token->kad->ticket_len); 946 + if (ret < 0) 947 + goto error; 948 + 949 + csp = rxrpc_skb(challenge); 950 + rsp = rxrpc_skb(response); 951 + rsp->resp.len = len; 952 + rsp->resp.challenge_serial = csp->hdr.serial; 953 + rxrpc_post_response(conn, response); 954 + response = NULL; 955 + ret = 0; 956 + 957 + error: 958 + rxrpc_free_skb(response, rxrpc_skb_put_response); 825 959 return ret; 826 960 } 961 + 962 + /* 963 + * RxKAD does automatic response only as there's nothing to manage that isn't 964 + * already in the key. 965 + */ 966 + static int rxkad_sendmsg_respond_to_challenge(struct sk_buff *challenge, 967 + struct msghdr *msg) 968 + { 969 + return -EINVAL; 970 + } 971 + 972 + /** 973 + * rxkad_kernel_respond_to_challenge - Respond to a challenge with appdata 974 + * @challenge: The challenge to respond to 975 + * 976 + * Allow a kernel application to respond to a CHALLENGE. 977 + * 978 + * Return: %0 if successful and a negative error code otherwise. 979 + */ 980 + int rxkad_kernel_respond_to_challenge(struct sk_buff *challenge) 981 + { 982 + struct rxrpc_skb_priv *csp = rxrpc_skb(challenge); 983 + 984 + return rxkad_respond_to_challenge(csp->chall.conn, challenge); 985 + } 986 + EXPORT_SYMBOL(rxkad_kernel_respond_to_challenge); 827 987 828 988 /* 829 989 * decrypt the kerberos IV ticket in the response ··· 1350 1276 .verify_packet = rxkad_verify_packet, 1351 1277 .free_call_crypto = rxkad_free_call_crypto, 1352 1278 .issue_challenge = rxkad_issue_challenge, 1279 + .validate_challenge = rxkad_validate_challenge, 1280 + .sendmsg_respond_to_challenge = rxkad_sendmsg_respond_to_challenge, 1353 1281 .respond_to_challenge = rxkad_respond_to_challenge, 1354 1282 .verify_response = rxkad_verify_response, 1355 1283 .clear = rxkad_clear,
+72 -6
net/rxrpc/rxperf.c
··· 8 8 #define pr_fmt(fmt) "rxperf: " fmt 9 9 #include <linux/module.h> 10 10 #include <linux/slab.h> 11 + #include <crypto/krb5.h> 11 12 #include <net/sock.h> 12 13 #include <net/af_rxrpc.h> 13 14 #define RXRPC_TRACE_ONLY_DEFINE_ENUMS ··· 137 136 RXPERF_CALL_SV_AWAIT_ACK); 138 137 } 139 138 139 + static const struct rxrpc_kernel_ops rxperf_rxrpc_callback_ops = { 140 + .notify_new_call = rxperf_rx_new_call, 141 + .discard_new_call = rxperf_rx_discard_new_call, 142 + .user_attach_call = rxperf_rx_attach, 143 + }; 144 + 140 145 /* 141 146 * Charge the incoming call preallocation. 142 147 */ ··· 168 161 169 162 if (rxrpc_kernel_charge_accept(rxperf_socket, 170 163 rxperf_notify_rx, 171 - rxperf_rx_attach, 172 164 (unsigned long)call, 173 165 GFP_KERNEL, 174 166 call->debug_id) < 0) ··· 215 209 if (ret < 0) 216 210 goto error_2; 217 211 218 - rxrpc_kernel_new_call_notification(socket, rxperf_rx_new_call, 219 - rxperf_rx_discard_new_call); 212 + rxrpc_kernel_set_notifications(socket, &rxperf_rxrpc_callback_ops); 220 213 221 214 ret = kernel_listen(socket, INT_MAX); 222 215 if (ret < 0) ··· 551 546 } 552 547 553 548 /* 554 - * Add a key to the security keyring. 549 + * Add an rxkad key to the security keyring. 555 550 */ 556 - static int rxperf_add_key(struct key *keyring) 551 + static int rxperf_add_rxkad_key(struct key *keyring) 557 552 { 558 553 key_ref_t kref; 559 554 int ret; ··· 578 573 key_ref_put(kref); 579 574 return ret; 580 575 } 576 + 577 + #ifdef CONFIG_RXGK 578 + /* 579 + * Add a yfs-rxgk key to the security keyring. 580 + */ 581 + static int rxperf_add_yfs_rxgk_key(struct key *keyring, u32 enctype) 582 + { 583 + const struct krb5_enctype *krb5 = crypto_krb5_find_enctype(enctype); 584 + key_ref_t kref; 585 + char name[64]; 586 + int ret; 587 + u8 key[32]; 588 + 589 + if (!krb5 || krb5->key_len > sizeof(key)) 590 + return 0; 591 + 592 + /* The key is just { 0, 1, 2, 3, 4, ... } */ 593 + for (int i = 0; i < krb5->key_len; i++) 594 + key[i] = i; 595 + 596 + sprintf(name, "%u:6:1:%u", RX_PERF_SERVICE, enctype); 597 + 598 + kref = key_create_or_update(make_key_ref(keyring, true), 599 + "rxrpc_s", name, 600 + key, krb5->key_len, 601 + KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | 602 + KEY_USR_VIEW, 603 + KEY_ALLOC_NOT_IN_QUOTA); 604 + 605 + if (IS_ERR(kref)) { 606 + pr_err("Can't allocate rxperf server key: %ld\n", PTR_ERR(kref)); 607 + return PTR_ERR(kref); 608 + } 609 + 610 + ret = key_link(keyring, key_ref_to_ptr(kref)); 611 + if (ret < 0) 612 + pr_err("Can't link rxperf server key: %d\n", ret); 613 + key_ref_put(kref); 614 + return ret; 615 + } 616 + #endif 581 617 582 618 /* 583 619 * Initialise the rxperf server. ··· 649 603 goto error_keyring; 650 604 } 651 605 rxperf_sec_keyring = keyring; 652 - ret = rxperf_add_key(keyring); 606 + ret = rxperf_add_rxkad_key(keyring); 653 607 if (ret < 0) 654 608 goto error_key; 609 + #ifdef CONFIG_RXGK 610 + ret = rxperf_add_yfs_rxgk_key(keyring, KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96); 611 + if (ret < 0) 612 + goto error_key; 613 + ret = rxperf_add_yfs_rxgk_key(keyring, KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96); 614 + if (ret < 0) 615 + goto error_key; 616 + ret = rxperf_add_yfs_rxgk_key(keyring, KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128); 617 + if (ret < 0) 618 + goto error_key; 619 + ret = rxperf_add_yfs_rxgk_key(keyring, KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192); 620 + if (ret < 0) 621 + goto error_key; 622 + ret = rxperf_add_yfs_rxgk_key(keyring, KRB5_ENCTYPE_CAMELLIA128_CTS_CMAC); 623 + if (ret < 0) 624 + goto error_key; 625 + ret = rxperf_add_yfs_rxgk_key(keyring, KRB5_ENCTYPE_CAMELLIA256_CTS_CMAC); 626 + if (ret < 0) 627 + goto error_key; 628 + #endif 655 629 656 630 ret = rxperf_open_socket(); 657 631 if (ret < 0)
+3
net/rxrpc/security.c
··· 20 20 #ifdef CONFIG_RXKAD 21 21 [RXRPC_SECURITY_RXKAD] = &rxkad, 22 22 #endif 23 + #ifdef CONFIG_RXGK 24 + [RXRPC_SECURITY_YFS_RXGK] = &rxgk_yfs, 25 + #endif 23 26 }; 24 27 25 28 int __init rxrpc_init_security(void)
+17 -8
net/rxrpc/sendmsg.c
··· 607 607 static struct rxrpc_call * 608 608 rxrpc_new_client_call_for_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, 609 609 struct rxrpc_send_params *p) 610 - __releases(&rx->sk.sk_lock.slock) 610 + __releases(&rx->sk.sk_lock) 611 611 __acquires(&call->user_mutex) 612 612 { 613 613 struct rxrpc_conn_parameters cp; ··· 657 657 * - the socket may be either a client socket or a server socket 658 658 */ 659 659 int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) 660 - __releases(&rx->sk.sk_lock.slock) 661 660 { 662 661 struct rxrpc_call *call; 663 662 bool dropped_lock = false; ··· 758 759 if (rxrpc_call_is_complete(call)) { 759 760 /* it's too late for this call */ 760 761 ret = -ESHUTDOWN; 761 - } else if (p.command == RXRPC_CMD_SEND_ABORT) { 762 + goto out_put_unlock; 763 + } 764 + 765 + switch (p.command) { 766 + case RXRPC_CMD_SEND_ABORT: 762 767 rxrpc_propose_abort(call, p.abort_code, -ECONNABORTED, 763 768 rxrpc_abort_call_sendmsg); 764 769 ret = 0; 765 - } else if (p.command != RXRPC_CMD_SEND_DATA) { 766 - ret = -EINVAL; 767 - } else { 770 + break; 771 + case RXRPC_CMD_SEND_DATA: 768 772 ret = rxrpc_send_data(rx, call, msg, len, NULL, &dropped_lock); 773 + break; 774 + default: 775 + ret = -EINVAL; 776 + break; 769 777 } 770 778 771 779 out_put_unlock: ··· 800 794 * appropriate to sending data. No control data should be supplied in @msg, 801 795 * nor should an address be supplied. MSG_MORE should be flagged if there's 802 796 * more data to come, otherwise this data will end the transmission phase. 797 + * 798 + * Return: %0 if successful and a negative error code otherwise. 803 799 */ 804 800 int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, 805 801 struct msghdr *msg, size_t len, ··· 837 829 * @error: Local error value 838 830 * @why: Indication as to why. 839 831 * 840 - * Allow a kernel service to abort a call, if it's still in an abortable state 841 - * and return true if the call was aborted, false if it was already complete. 832 + * Allow a kernel service to abort a call if it's still in an abortable state. 833 + * 834 + * Return: %true if the call was aborted, %false if it was already complete. 842 835 */ 843 836 bool rxrpc_kernel_abort_call(struct socket *sock, struct rxrpc_call *call, 844 837 u32 abort_code, int error, enum rxrpc_abort_reason why)
+42
net/rxrpc/server_key.c
··· 152 152 * 153 153 * Set the server security keyring on an rxrpc socket. This is used to provide 154 154 * the encryption keys for a kernel service. 155 + * 156 + * Return: %0 if successful and a negative error code otherwise. 155 157 */ 156 158 int rxrpc_sock_set_security_keyring(struct sock *sk, struct key *keyring) 157 159 { ··· 171 169 return ret; 172 170 } 173 171 EXPORT_SYMBOL(rxrpc_sock_set_security_keyring); 172 + 173 + /** 174 + * rxrpc_sock_set_manage_response - Set the manage-response flag for a kernel service 175 + * @sk: The socket to set the keyring on 176 + * @set: True to set, false to clear the flag 177 + * 178 + * Set the flag on an rxrpc socket to say that the caller wants to manage the 179 + * RESPONSE packet and the user-defined data it may contain. Setting this 180 + * means that recvmsg() will return messages with RXRPC_CHALLENGED in the 181 + * control message buffer containing information about the challenge. 182 + * 183 + * The user should respond to the challenge by passing RXRPC_RESPOND or 184 + * RXRPC_RESPOND_ABORT control messages with sendmsg() to the same call. 185 + * Supplementary control messages, such as RXRPC_RESP_RXGK_APPDATA, may be 186 + * included to indicate the parts the user wants to supply. 187 + * 188 + * The server will be passed the response data with a RXRPC_RESPONDED control 189 + * message when it gets the first data from each call. 190 + * 191 + * Note that this is only honoured by security classes that need auxiliary data 192 + * (e.g. RxGK). Those that don't offer the facility (e.g. RxKAD) respond 193 + * without consulting userspace. 194 + * 195 + * Return: The previous setting. 196 + */ 197 + int rxrpc_sock_set_manage_response(struct sock *sk, bool set) 198 + { 199 + struct rxrpc_sock *rx = rxrpc_sk(sk); 200 + int ret; 201 + 202 + lock_sock(sk); 203 + ret = !!test_bit(RXRPC_SOCK_MANAGE_RESPONSE, &rx->flags); 204 + if (set) 205 + set_bit(RXRPC_SOCK_MANAGE_RESPONSE, &rx->flags); 206 + else 207 + clear_bit(RXRPC_SOCK_MANAGE_RESPONSE, &rx->flags); 208 + release_sock(sk); 209 + return ret; 210 + } 211 + EXPORT_SYMBOL(rxrpc_sock_set_manage_response);