| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: BSD-3-Clause |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/net/sunrpc/gss_mech_switch.c |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * All rights reserved. |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * J. Bruce Fields <bfields@umich.edu> |
|---|
| 8 | | - * |
|---|
| 9 | | - * Redistribution and use in source and binary forms, with or without |
|---|
| 10 | | - * modification, are permitted provided that the following conditions |
|---|
| 11 | | - * are met: |
|---|
| 12 | | - * |
|---|
| 13 | | - * 1. Redistributions of source code must retain the above copyright |
|---|
| 14 | | - * notice, this list of conditions and the following disclaimer. |
|---|
| 15 | | - * 2. Redistributions in binary form must reproduce the above copyright |
|---|
| 16 | | - * notice, this list of conditions and the following disclaimer in the |
|---|
| 17 | | - * documentation and/or other materials provided with the distribution. |
|---|
| 18 | | - * 3. Neither the name of the University nor the names of its |
|---|
| 19 | | - * contributors may be used to endorse or promote products derived |
|---|
| 20 | | - * from this software without specific prior written permission. |
|---|
| 21 | | - * |
|---|
| 22 | | - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED |
|---|
| 23 | | - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|---|
| 24 | | - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|---|
| 25 | | - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|---|
| 26 | | - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|---|
| 27 | | - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|---|
| 28 | | - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
|---|
| 29 | | - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|---|
| 30 | | - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|---|
| 31 | | - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|---|
| 32 | | - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|---|
| 33 | | - * |
|---|
| 34 | 9 | */ |
|---|
| 35 | 10 | |
|---|
| 36 | 11 | #include <linux/types.h> |
|---|
| .. | .. |
|---|
| 45 | 20 | #include <linux/sunrpc/sched.h> |
|---|
| 46 | 21 | #include <linux/sunrpc/gss_api.h> |
|---|
| 47 | 22 | #include <linux/sunrpc/clnt.h> |
|---|
| 23 | +#include <trace/events/rpcgss.h> |
|---|
| 48 | 24 | |
|---|
| 49 | 25 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
|---|
| 50 | 26 | # define RPCDBG_FACILITY RPCDBG_AUTH |
|---|
| .. | .. |
|---|
| 123 | 99 | if (status) |
|---|
| 124 | 100 | return status; |
|---|
| 125 | 101 | spin_lock(®istered_mechs_lock); |
|---|
| 126 | | - list_add(&gm->gm_list, ®istered_mechs); |
|---|
| 102 | + list_add_rcu(&gm->gm_list, ®istered_mechs); |
|---|
| 127 | 103 | spin_unlock(®istered_mechs_lock); |
|---|
| 128 | 104 | dprintk("RPC: registered gss mechanism %s\n", gm->gm_name); |
|---|
| 129 | 105 | return 0; |
|---|
| .. | .. |
|---|
| 138 | 114 | void gss_mech_unregister(struct gss_api_mech *gm) |
|---|
| 139 | 115 | { |
|---|
| 140 | 116 | spin_lock(®istered_mechs_lock); |
|---|
| 141 | | - list_del(&gm->gm_list); |
|---|
| 117 | + list_del_rcu(&gm->gm_list); |
|---|
| 142 | 118 | spin_unlock(®istered_mechs_lock); |
|---|
| 143 | 119 | dprintk("RPC: unregistered gss mechanism %s\n", gm->gm_name); |
|---|
| 144 | 120 | gss_mech_free(gm); |
|---|
| .. | .. |
|---|
| 157 | 133 | { |
|---|
| 158 | 134 | struct gss_api_mech *pos, *gm = NULL; |
|---|
| 159 | 135 | |
|---|
| 160 | | - spin_lock(®istered_mechs_lock); |
|---|
| 161 | | - list_for_each_entry(pos, ®istered_mechs, gm_list) { |
|---|
| 136 | + rcu_read_lock(); |
|---|
| 137 | + list_for_each_entry_rcu(pos, ®istered_mechs, gm_list) { |
|---|
| 162 | 138 | if (0 == strcmp(name, pos->gm_name)) { |
|---|
| 163 | 139 | if (try_module_get(pos->gm_owner)) |
|---|
| 164 | 140 | gm = pos; |
|---|
| 165 | 141 | break; |
|---|
| 166 | 142 | } |
|---|
| 167 | 143 | } |
|---|
| 168 | | - spin_unlock(®istered_mechs_lock); |
|---|
| 144 | + rcu_read_unlock(); |
|---|
| 169 | 145 | return gm; |
|---|
| 170 | 146 | |
|---|
| 171 | 147 | } |
|---|
| .. | .. |
|---|
| 189 | 165 | |
|---|
| 190 | 166 | if (sprint_oid(obj->data, obj->len, buf, sizeof(buf)) < 0) |
|---|
| 191 | 167 | return NULL; |
|---|
| 192 | | - dprintk("RPC: %s(%s)\n", __func__, buf); |
|---|
| 193 | 168 | request_module("rpc-auth-gss-%s", buf); |
|---|
| 194 | 169 | |
|---|
| 195 | | - spin_lock(®istered_mechs_lock); |
|---|
| 196 | | - list_for_each_entry(pos, ®istered_mechs, gm_list) { |
|---|
| 170 | + rcu_read_lock(); |
|---|
| 171 | + list_for_each_entry_rcu(pos, ®istered_mechs, gm_list) { |
|---|
| 197 | 172 | if (obj->len == pos->gm_oid.len) { |
|---|
| 198 | 173 | if (0 == memcmp(obj->data, pos->gm_oid.data, obj->len)) { |
|---|
| 199 | 174 | if (try_module_get(pos->gm_owner)) |
|---|
| .. | .. |
|---|
| 202 | 177 | } |
|---|
| 203 | 178 | } |
|---|
| 204 | 179 | } |
|---|
| 205 | | - spin_unlock(®istered_mechs_lock); |
|---|
| 180 | + rcu_read_unlock(); |
|---|
| 181 | + if (!gm) |
|---|
| 182 | + trace_rpcgss_oid_to_mech(buf); |
|---|
| 206 | 183 | return gm; |
|---|
| 207 | 184 | } |
|---|
| 208 | 185 | |
|---|
| .. | .. |
|---|
| 222 | 199 | { |
|---|
| 223 | 200 | struct gss_api_mech *gm = NULL, *pos; |
|---|
| 224 | 201 | |
|---|
| 225 | | - spin_lock(®istered_mechs_lock); |
|---|
| 226 | | - list_for_each_entry(pos, ®istered_mechs, gm_list) { |
|---|
| 202 | + rcu_read_lock(); |
|---|
| 203 | + list_for_each_entry_rcu(pos, ®istered_mechs, gm_list) { |
|---|
| 227 | 204 | if (!mech_supports_pseudoflavor(pos, pseudoflavor)) |
|---|
| 228 | 205 | continue; |
|---|
| 229 | 206 | if (try_module_get(pos->gm_owner)) |
|---|
| 230 | 207 | gm = pos; |
|---|
| 231 | 208 | break; |
|---|
| 232 | 209 | } |
|---|
| 233 | | - spin_unlock(®istered_mechs_lock); |
|---|
| 210 | + rcu_read_unlock(); |
|---|
| 234 | 211 | return gm; |
|---|
| 235 | 212 | } |
|---|
| 236 | 213 | |
|---|
| .. | .. |
|---|
| 246 | 223 | gm = _gss_mech_get_by_pseudoflavor(pseudoflavor); |
|---|
| 247 | 224 | } |
|---|
| 248 | 225 | return gm; |
|---|
| 249 | | -} |
|---|
| 250 | | - |
|---|
| 251 | | -/** |
|---|
| 252 | | - * gss_mech_list_pseudoflavors - Discover registered GSS pseudoflavors |
|---|
| 253 | | - * @array: array to fill in |
|---|
| 254 | | - * @size: size of "array" |
|---|
| 255 | | - * |
|---|
| 256 | | - * Returns the number of array items filled in, or a negative errno. |
|---|
| 257 | | - * |
|---|
| 258 | | - * The returned array is not sorted by any policy. Callers should not |
|---|
| 259 | | - * rely on the order of the items in the returned array. |
|---|
| 260 | | - */ |
|---|
| 261 | | -int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr, int size) |
|---|
| 262 | | -{ |
|---|
| 263 | | - struct gss_api_mech *pos = NULL; |
|---|
| 264 | | - int j, i = 0; |
|---|
| 265 | | - |
|---|
| 266 | | - spin_lock(®istered_mechs_lock); |
|---|
| 267 | | - list_for_each_entry(pos, ®istered_mechs, gm_list) { |
|---|
| 268 | | - for (j = 0; j < pos->gm_pf_num; j++) { |
|---|
| 269 | | - if (i >= size) { |
|---|
| 270 | | - spin_unlock(®istered_mechs_lock); |
|---|
| 271 | | - return -ENOMEM; |
|---|
| 272 | | - } |
|---|
| 273 | | - array_ptr[i++] = pos->gm_pfs[j].pseudoflavor; |
|---|
| 274 | | - } |
|---|
| 275 | | - } |
|---|
| 276 | | - spin_unlock(®istered_mechs_lock); |
|---|
| 277 | | - return i; |
|---|
| 278 | 226 | } |
|---|
| 279 | 227 | |
|---|
| 280 | 228 | /** |
|---|
| .. | .. |
|---|
| 405 | 353 | gss_import_sec_context(const void *input_token, size_t bufsize, |
|---|
| 406 | 354 | struct gss_api_mech *mech, |
|---|
| 407 | 355 | struct gss_ctx **ctx_id, |
|---|
| 408 | | - time_t *endtime, |
|---|
| 356 | + time64_t *endtime, |
|---|
| 409 | 357 | gfp_t gfp_mask) |
|---|
| 410 | 358 | { |
|---|
| 411 | 359 | if (!(*ctx_id = kzalloc(sizeof(**ctx_id), gfp_mask))) |
|---|
| .. | .. |
|---|
| 469 | 417 | u32 |
|---|
| 470 | 418 | gss_unwrap(struct gss_ctx *ctx_id, |
|---|
| 471 | 419 | int offset, |
|---|
| 420 | + int len, |
|---|
| 472 | 421 | struct xdr_buf *buf) |
|---|
| 473 | 422 | { |
|---|
| 474 | 423 | return ctx_id->mech_type->gm_ops |
|---|
| 475 | | - ->gss_unwrap(ctx_id, offset, buf); |
|---|
| 424 | + ->gss_unwrap(ctx_id, offset, len, buf); |
|---|
| 476 | 425 | } |
|---|
| 477 | 426 | |
|---|
| 478 | 427 | |
|---|