1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * linux/fs/nfs/callback.c 4 * 5 * Copyright (C) 2004 Trond Myklebust 6 * 7 * NFSv4 callback handling 8 */ 9 10 #include <linux/completion.h> 11 #include <linux/ip.h> 12 #include <linux/module.h> 13 #include <linux/sched/signal.h> 14 #include <linux/sunrpc/svc.h> 15 #include <linux/sunrpc/svcsock.h> 16 #include <linux/nfs_fs.h> 17 #include <linux/errno.h> 18 #include <linux/mutex.h> 19 #include <linux/freezer.h> 20 #include <linux/sunrpc/svcauth_gss.h> 21 #include <linux/sunrpc/bc_xprt.h> 22 23 #include <net/inet_sock.h> 24 25 #include "nfs4_fs.h" 26 #include "callback.h" 27 #include "internal.h" 28 #include "netns.h" 29 30 #define NFSDBG_FACILITY NFSDBG_CALLBACK 31 32 struct nfs_callback_data { 33 unsigned int users; 34 struct svc_serv *serv; 35 }; 36 37 static struct nfs_callback_data nfs_callback_info[NFS4_MAX_MINOR_VERSION + 1]; 38 static DEFINE_MUTEX(nfs_callback_mutex); 39 static struct svc_program nfs4_callback_program; 40 41 static int nfs4_callback_up_net(struct svc_serv *serv, struct net *net) 42 { 43 const struct cred *cred = current_cred(); 44 int ret; 45 struct nfs_net *nn = net_generic(net, nfs_net_id); 46 47 ret = svc_xprt_create(serv, "tcp", net, PF_INET, 48 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS, 49 cred); 50 if (ret <= 0) 51 goto out_err; 52 nn->nfs_callback_tcpport = ret; 53 dprintk("NFS: Callback listener port = %u (af %u, net %x)\n", 54 nn->nfs_callback_tcpport, PF_INET, net->ns.inum); 55 56 ret = svc_xprt_create(serv, "tcp", net, PF_INET6, 57 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS, 58 cred); 59 if (ret > 0) { 60 nn->nfs_callback_tcpport6 = ret; 61 dprintk("NFS: Callback listener port = %u (af %u, net %x)\n", 62 nn->nfs_callback_tcpport6, PF_INET6, net->ns.inum); 63 } else if (ret != -EAFNOSUPPORT) 64 goto out_err; 65 return 0; 66 67 out_err: 68 return (ret) ? ret : -ENOMEM; 69 } 70 71 /* 72 * This is the NFSv4 callback kernel thread. 73 */ 74 static int 75 nfs4_callback_svc(void *vrqstp) 76 { 77 struct svc_rqst *rqstp = vrqstp; 78 79 svc_thread_init_status(rqstp, 0); 80 81 set_freezable(); 82 83 while (!svc_thread_should_stop(rqstp)) 84 svc_recv(rqstp); 85 86 svc_exit_thread(rqstp); 87 return 0; 88 } 89 90 #if defined(CONFIG_NFS_V4_1) 91 static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, 92 struct svc_serv *serv) 93 { 94 if (minorversion) 95 /* 96 * Save the svc_serv in the transport so that it can 97 * be referenced when the session backchannel is initialized 98 */ 99 xprt->bc_serv = serv; 100 } 101 #else 102 static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, 103 struct svc_serv *serv) 104 { 105 } 106 #endif /* CONFIG_NFS_V4_1 */ 107 108 static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, 109 struct svc_serv *serv) 110 { 111 int nrservs = nfs_callback_nr_threads; 112 int ret; 113 114 nfs_callback_bc_serv(minorversion, xprt, serv); 115 116 if (nrservs < NFS4_MIN_NR_CALLBACK_THREADS) 117 nrservs = NFS4_MIN_NR_CALLBACK_THREADS; 118 119 if (serv->sv_nrthreads == nrservs) 120 return 0; 121 122 ret = svc_set_num_threads(serv, NULL, nrservs); 123 if (ret) { 124 svc_set_num_threads(serv, NULL, 0); 125 return ret; 126 } 127 dprintk("nfs_callback_up: service started\n"); 128 return 0; 129 } 130 131 static void nfs_callback_down_net(u32 minorversion, struct svc_serv *serv, struct net *net) 132 { 133 struct nfs_net *nn = net_generic(net, nfs_net_id); 134 135 if (--nn->cb_users[minorversion]) 136 return; 137 138 dprintk("NFS: destroy per-net callback data; net=%x\n", net->ns.inum); 139 svc_xprt_destroy_all(serv, net); 140 } 141 142 static int nfs_callback_up_net(int minorversion, struct svc_serv *serv, 143 struct net *net, struct rpc_xprt *xprt) 144 { 145 struct nfs_net *nn = net_generic(net, nfs_net_id); 146 int ret; 147 148 if (nn->cb_users[minorversion]++) 149 return 0; 150 151 dprintk("NFS: create per-net callback data; net=%x\n", net->ns.inum); 152 153 ret = svc_bind(serv, net); 154 if (ret < 0) { 155 printk(KERN_WARNING "NFS: bind callback service failed\n"); 156 goto err_bind; 157 } 158 159 ret = 0; 160 if (!IS_ENABLED(CONFIG_NFS_V4_1) || minorversion == 0) 161 ret = nfs4_callback_up_net(serv, net); 162 else if (xprt->ops->bc_setup) 163 set_bc_enabled(serv); 164 else 165 ret = -EPROTONOSUPPORT; 166 167 if (ret < 0) { 168 printk(KERN_ERR "NFS: callback service start failed\n"); 169 goto err_socks; 170 } 171 return 0; 172 173 err_socks: 174 svc_rpcb_cleanup(serv, net); 175 err_bind: 176 nn->cb_users[minorversion]--; 177 dprintk("NFS: Couldn't create callback socket: err = %d; " 178 "net = %x\n", ret, net->ns.inum); 179 return ret; 180 } 181 182 static struct svc_serv *nfs_callback_create_svc(int minorversion) 183 { 184 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; 185 int (*threadfn)(void *data); 186 struct svc_serv *serv; 187 188 /* 189 * Check whether we're already up and running. 190 */ 191 if (cb_info->serv) 192 return cb_info->serv; 193 194 /* 195 * Sanity check: if there's no task, 196 * we should be the first user ... 197 */ 198 if (cb_info->users) 199 printk(KERN_WARNING "nfs_callback_create_svc: no kthread, %d users??\n", 200 cb_info->users); 201 202 threadfn = nfs4_callback_svc; 203 #if !defined(CONFIG_NFS_V4_1) 204 if (minorversion) 205 return ERR_PTR(-ENOTSUPP); 206 #endif 207 serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, 208 threadfn); 209 if (!serv) { 210 printk(KERN_ERR "nfs_callback_create_svc: create service failed\n"); 211 return ERR_PTR(-ENOMEM); 212 } 213 cb_info->serv = serv; 214 /* As there is only one thread we need to over-ride the 215 * default maximum of 80 connections 216 */ 217 serv->sv_maxconn = 1024; 218 dprintk("nfs_callback_create_svc: service created\n"); 219 return serv; 220 } 221 222 /* 223 * Bring up the callback thread if it is not already up. 224 */ 225 int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) 226 { 227 struct svc_serv *serv; 228 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; 229 int ret; 230 struct net *net = xprt->xprt_net; 231 232 mutex_lock(&nfs_callback_mutex); 233 234 serv = nfs_callback_create_svc(minorversion); 235 if (IS_ERR(serv)) { 236 ret = PTR_ERR(serv); 237 goto err_create; 238 } 239 240 ret = nfs_callback_up_net(minorversion, serv, net, xprt); 241 if (ret < 0) 242 goto err_net; 243 244 ret = nfs_callback_start_svc(minorversion, xprt, serv); 245 if (ret < 0) 246 goto err_start; 247 248 cb_info->users++; 249 err_net: 250 if (!cb_info->users) { 251 svc_set_num_threads(cb_info->serv, NULL, 0); 252 svc_destroy(&cb_info->serv); 253 } 254 err_create: 255 mutex_unlock(&nfs_callback_mutex); 256 return ret; 257 258 err_start: 259 nfs_callback_down_net(minorversion, serv, net); 260 dprintk("NFS: Couldn't create server thread; err = %d\n", ret); 261 goto err_net; 262 } 263 264 /* 265 * Kill the callback thread if it's no longer being used. 266 */ 267 void nfs_callback_down(int minorversion, struct net *net) 268 { 269 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; 270 struct svc_serv *serv; 271 272 mutex_lock(&nfs_callback_mutex); 273 serv = cb_info->serv; 274 nfs_callback_down_net(minorversion, serv, net); 275 cb_info->users--; 276 if (cb_info->users == 0) { 277 svc_set_num_threads(serv, NULL, 0); 278 dprintk("nfs_callback_down: service destroyed\n"); 279 svc_destroy(&cb_info->serv); 280 } 281 mutex_unlock(&nfs_callback_mutex); 282 } 283 284 /* Boolean check of RPC_AUTH_GSS principal */ 285 int 286 check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp) 287 { 288 char *p = rqstp->rq_cred.cr_principal; 289 290 if (rqstp->rq_authop->flavour != RPC_AUTH_GSS) 291 return 1; 292 293 /* No RPC_AUTH_GSS on NFSv4.1 back channel yet */ 294 if (clp->cl_minorversion != 0) 295 return 0; 296 /* 297 * It might just be a normal user principal, in which case 298 * userspace won't bother to tell us the name at all. 299 */ 300 if (p == NULL) 301 return 0; 302 303 /* 304 * Did we get the acceptor from userland during the SETCLIENID 305 * negotiation? 306 */ 307 if (clp->cl_acceptor) 308 return !strcmp(p, clp->cl_acceptor); 309 310 /* 311 * Otherwise try to verify it using the cl_hostname. Note that this 312 * doesn't work if a non-canonical hostname was used in the devname. 313 */ 314 315 /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */ 316 317 if (memcmp(p, "nfs@", 4) != 0) 318 return 0; 319 p += 4; 320 if (strcmp(p, clp->cl_hostname) != 0) 321 return 0; 322 return 1; 323 } 324 325 /* 326 * pg_authenticate method for nfsv4 callback threads. 327 * 328 * The authflavor has been negotiated, so an incorrect flavor is a server 329 * bug. Deny packets with incorrect authflavor. 330 * 331 * All other checking done after NFS decoding where the nfs_client can be 332 * found in nfs4_callback_compound 333 */ 334 static enum svc_auth_status nfs_callback_authenticate(struct svc_rqst *rqstp) 335 { 336 rqstp->rq_auth_stat = rpc_autherr_badcred; 337 338 switch (rqstp->rq_authop->flavour) { 339 case RPC_AUTH_NULL: 340 if (rqstp->rq_proc != CB_NULL) 341 return SVC_DENIED; 342 break; 343 case RPC_AUTH_GSS: 344 /* No RPC_AUTH_GSS support yet in NFSv4.1 */ 345 if (svc_is_backchannel(rqstp)) 346 return SVC_DENIED; 347 } 348 349 rqstp->rq_auth_stat = rpc_auth_ok; 350 return SVC_OK; 351 } 352 353 /* 354 * Define NFS4 callback program 355 */ 356 static const struct svc_version *nfs4_callback_version[] = { 357 [1] = &nfs4_callback_version1, 358 [4] = &nfs4_callback_version4, 359 }; 360 361 static struct svc_program nfs4_callback_program = { 362 .pg_prog = NFS4_CALLBACK, /* RPC service number */ 363 .pg_nvers = ARRAY_SIZE(nfs4_callback_version), /* Number of entries */ 364 .pg_vers = nfs4_callback_version, /* version table */ 365 .pg_name = "NFSv4 callback", /* service name */ 366 .pg_class = "nfs", /* authentication class */ 367 .pg_authenticate = nfs_callback_authenticate, 368 .pg_init_request = svc_generic_init_request, 369 .pg_rpcbind_set = svc_generic_rpcbind_set, 370 }; 371