.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* RxRPC security handling |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. |
---|
4 | 5 | * Written by David Howells (dhowells@redhat.com) |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or |
---|
7 | | - * modify it under the terms of the GNU General Public License |
---|
8 | | - * as published by the Free Software Foundation; either version |
---|
9 | | - * 2 of the License, or (at your option) any later version. |
---|
10 | 6 | */ |
---|
11 | 7 | |
---|
12 | 8 | #include <linux/module.h> |
---|
.. | .. |
---|
105 | 101 | } |
---|
106 | 102 | |
---|
107 | 103 | /* |
---|
108 | | - * initialise the security on a server connection |
---|
| 104 | + * Find the security key for a server connection. |
---|
109 | 105 | */ |
---|
110 | | -int rxrpc_init_server_conn_security(struct rxrpc_connection *conn) |
---|
| 106 | +bool rxrpc_look_up_server_security(struct rxrpc_local *local, struct rxrpc_sock *rx, |
---|
| 107 | + const struct rxrpc_security **_sec, |
---|
| 108 | + struct key **_key, |
---|
| 109 | + struct sk_buff *skb) |
---|
111 | 110 | { |
---|
112 | 111 | const struct rxrpc_security *sec; |
---|
113 | | - struct rxrpc_local *local = conn->params.local; |
---|
114 | | - struct rxrpc_sock *rx; |
---|
115 | | - struct key *key; |
---|
116 | | - key_ref_t kref; |
---|
| 112 | + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
---|
| 113 | + key_ref_t kref = NULL; |
---|
117 | 114 | char kdesc[5 + 1 + 3 + 1]; |
---|
118 | 115 | |
---|
119 | 116 | _enter(""); |
---|
120 | 117 | |
---|
121 | | - sprintf(kdesc, "%u:%u", conn->service_id, conn->security_ix); |
---|
| 118 | + sprintf(kdesc, "%u:%u", sp->hdr.serviceId, sp->hdr.securityIndex); |
---|
122 | 119 | |
---|
123 | | - sec = rxrpc_security_lookup(conn->security_ix); |
---|
| 120 | + sec = rxrpc_security_lookup(sp->hdr.securityIndex); |
---|
124 | 121 | if (!sec) { |
---|
125 | | - _leave(" = -ENOKEY [lookup]"); |
---|
126 | | - return -ENOKEY; |
---|
| 122 | + trace_rxrpc_abort(0, "SVS", |
---|
| 123 | + sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq, |
---|
| 124 | + RX_INVALID_OPERATION, EKEYREJECTED); |
---|
| 125 | + skb->mark = RXRPC_SKB_MARK_REJECT_ABORT; |
---|
| 126 | + skb->priority = RX_INVALID_OPERATION; |
---|
| 127 | + return false; |
---|
127 | 128 | } |
---|
128 | 129 | |
---|
129 | | - /* find the service */ |
---|
130 | | - read_lock(&local->services_lock); |
---|
131 | | - rx = rcu_dereference_protected(local->service, |
---|
132 | | - lockdep_is_held(&local->services_lock)); |
---|
133 | | - if (rx && (rx->srx.srx_service == conn->service_id || |
---|
134 | | - rx->second_service == conn->service_id)) |
---|
135 | | - goto found_service; |
---|
| 130 | + if (sp->hdr.securityIndex == RXRPC_SECURITY_NONE) |
---|
| 131 | + goto out; |
---|
136 | 132 | |
---|
137 | | - /* the service appears to have died */ |
---|
138 | | - read_unlock(&local->services_lock); |
---|
139 | | - _leave(" = -ENOENT"); |
---|
140 | | - return -ENOENT; |
---|
141 | | - |
---|
142 | | -found_service: |
---|
143 | 133 | if (!rx->securities) { |
---|
144 | | - read_unlock(&local->services_lock); |
---|
145 | | - _leave(" = -ENOKEY"); |
---|
146 | | - return -ENOKEY; |
---|
| 134 | + trace_rxrpc_abort(0, "SVR", |
---|
| 135 | + sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq, |
---|
| 136 | + RX_INVALID_OPERATION, EKEYREJECTED); |
---|
| 137 | + skb->mark = RXRPC_SKB_MARK_REJECT_ABORT; |
---|
| 138 | + skb->priority = RX_INVALID_OPERATION; |
---|
| 139 | + return false; |
---|
147 | 140 | } |
---|
148 | 141 | |
---|
149 | 142 | /* look through the service's keyring */ |
---|
150 | 143 | kref = keyring_search(make_key_ref(rx->securities, 1UL), |
---|
151 | | - &key_type_rxrpc_s, kdesc); |
---|
| 144 | + &key_type_rxrpc_s, kdesc, true); |
---|
152 | 145 | if (IS_ERR(kref)) { |
---|
153 | | - read_unlock(&local->services_lock); |
---|
154 | | - _leave(" = %ld [search]", PTR_ERR(kref)); |
---|
155 | | - return PTR_ERR(kref); |
---|
| 146 | + trace_rxrpc_abort(0, "SVK", |
---|
| 147 | + sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq, |
---|
| 148 | + sec->no_key_abort, EKEYREJECTED); |
---|
| 149 | + skb->mark = RXRPC_SKB_MARK_REJECT_ABORT; |
---|
| 150 | + skb->priority = sec->no_key_abort; |
---|
| 151 | + return false; |
---|
156 | 152 | } |
---|
157 | 153 | |
---|
158 | | - key = key_ref_to_ptr(kref); |
---|
159 | | - read_unlock(&local->services_lock); |
---|
160 | | - |
---|
161 | | - conn->server_key = key; |
---|
162 | | - conn->security = sec; |
---|
163 | | - |
---|
164 | | - _leave(" = 0"); |
---|
165 | | - return 0; |
---|
| 154 | +out: |
---|
| 155 | + *_sec = sec; |
---|
| 156 | + *_key = key_ref_to_ptr(kref); |
---|
| 157 | + return true; |
---|
166 | 158 | } |
---|