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