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 dprintk("nfs_callback_create_svc: service created\n"); 215 return serv; 216 } 217 218 /* 219 * Bring up the callback thread if it is not already up. 220 */ 221 int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) 222 { 223 struct svc_serv *serv; 224 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; 225 int ret; 226 struct net *net = xprt->xprt_net; 227 228 mutex_lock(&nfs_callback_mutex); 229 230 serv = nfs_callback_create_svc(minorversion); 231 if (IS_ERR(serv)) { 232 ret = PTR_ERR(serv); 233 goto err_create; 234 } 235 236 ret = nfs_callback_up_net(minorversion, serv, net, xprt); 237 if (ret < 0) 238 goto err_net; 239 240 ret = nfs_callback_start_svc(minorversion, xprt, serv); 241 if (ret < 0) 242 goto err_start; 243 244 cb_info->users++; 245 err_net: 246 if (!cb_info->users) { 247 svc_set_num_threads(cb_info->serv, NULL, 0); 248 svc_destroy(&cb_info->serv); 249 } 250 err_create: 251 mutex_unlock(&nfs_callback_mutex); 252 return ret; 253 254 err_start: 255 nfs_callback_down_net(minorversion, serv, net); 256 dprintk("NFS: Couldn't create server thread; err = %d\n", ret); 257 goto err_net; 258 } 259 260 /* 261 * Kill the callback thread if it's no longer being used. 262 */ 263 void nfs_callback_down(int minorversion, struct net *net) 264 { 265 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; 266 struct svc_serv *serv; 267 268 mutex_lock(&nfs_callback_mutex); 269 serv = cb_info->serv; 270 nfs_callback_down_net(minorversion, serv, net); 271 cb_info->users--; 272 if (cb_info->users == 0) { 273 svc_set_num_threads(serv, NULL, 0); 274 dprintk("nfs_callback_down: service destroyed\n"); 275 svc_destroy(&cb_info->serv); 276 } 277 mutex_unlock(&nfs_callback_mutex); 278 } 279 280 /* Boolean check of RPC_AUTH_GSS principal */ 281 int 282 check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp) 283 { 284 char *p = rqstp->rq_cred.cr_principal; 285 286 if (rqstp->rq_authop->flavour != RPC_AUTH_GSS) 287 return 1; 288 289 /* No RPC_AUTH_GSS on NFSv4.1 back channel yet */ 290 if (clp->cl_minorversion != 0) 291 return 0; 292 /* 293 * It might just be a normal user principal, in which case 294 * userspace won't bother to tell us the name at all. 295 */ 296 if (p == NULL) 297 return 0; 298 299 /* 300 * Did we get the acceptor from userland during the SETCLIENID 301 * negotiation? 302 */ 303 if (clp->cl_acceptor) 304 return !strcmp(p, clp->cl_acceptor); 305 306 /* 307 * Otherwise try to verify it using the cl_hostname. Note that this 308 * doesn't work if a non-canonical hostname was used in the devname. 309 */ 310 311 /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */ 312 313 if (memcmp(p, "nfs@", 4) != 0) 314 return 0; 315 p += 4; 316 if (strcmp(p, clp->cl_hostname) != 0) 317 return 0; 318 return 1; 319 } 320 321 /* 322 * pg_authenticate method for nfsv4 callback threads. 323 * 324 * The authflavor has been negotiated, so an incorrect flavor is a server 325 * bug. Deny packets with incorrect authflavor. 326 * 327 * All other checking done after NFS decoding where the nfs_client can be 328 * found in nfs4_callback_compound 329 */ 330 static enum svc_auth_status nfs_callback_authenticate(struct svc_rqst *rqstp) 331 { 332 rqstp->rq_auth_stat = rpc_autherr_badcred; 333 334 switch (rqstp->rq_authop->flavour) { 335 case RPC_AUTH_NULL: 336 if (rqstp->rq_proc != CB_NULL) 337 return SVC_DENIED; 338 break; 339 case RPC_AUTH_GSS: 340 /* No RPC_AUTH_GSS support yet in NFSv4.1 */ 341 if (svc_is_backchannel(rqstp)) 342 return SVC_DENIED; 343 } 344 345 rqstp->rq_auth_stat = rpc_auth_ok; 346 return SVC_OK; 347 } 348 349 /* 350 * Define NFS4 callback program 351 */ 352 static const struct svc_version *nfs4_callback_version[] = { 353 [1] = &nfs4_callback_version1, 354 [4] = &nfs4_callback_version4, 355 }; 356 357 static struct svc_program nfs4_callback_program = { 358 .pg_prog = NFS4_CALLBACK, /* RPC service number */ 359 .pg_nvers = ARRAY_SIZE(nfs4_callback_version), /* Number of entries */ 360 .pg_vers = nfs4_callback_version, /* version table */ 361 .pg_name = "NFSv4 callback", /* service name */ 362 .pg_class = "nfs", /* authentication class */ 363 .pg_authenticate = nfs_callback_authenticate, 364 .pg_init_request = svc_generic_init_request, 365 .pg_rpcbind_set = svc_generic_rpcbind_set, 366 }; 367