1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * NFS exporting and validation.
4 *
5 * We maintain a list of clients, each of which has a list of
6 * exports. To export an fs to a given client, you first have
7 * to create the client entry with NFSCTL_ADDCLIENT, which
8 * creates a client control block and adds it to the hash
9 * table. Then, you call NFSCTL_EXPORT for each fs.
10 *
11 *
12 * Copyright (C) 1995, 1996 Olaf Kirch, <okir@monad.swb.de>
13 */
14
15 #include <linux/slab.h>
16 #include <linux/namei.h>
17 #include <linux/module.h>
18 #include <linux/exportfs.h>
19 #include <linux/sunrpc/svc_xprt.h>
20 #include <net/genetlink.h>
21 #include <uapi/linux/nfsd_netlink.h>
22
23 #include "nfsd.h"
24 #include "nfsfh.h"
25 #include "netns.h"
26 #include "pnfs.h"
27 #include "filecache.h"
28 #include "trace.h"
29 #include "netlink.h"
30
31 #define NFSDDBG_FACILITY NFSDDBG_EXPORT
32
33 /*
34 * We have two caches.
35 * One maps client+vfsmnt+dentry to export options - the export map
36 * The other maps client+filehandle-fragment to export options. - the expkey map
37 *
38 * The export options are actually stored in the first map, and the
39 * second map contains a reference to the entry in the first map.
40 */
41
42 #define EXPKEY_HASHBITS 8
43 #define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS)
44 #define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)
45
expkey_put(struct kref * ref)46 static void expkey_put(struct kref *ref)
47 {
48 struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
49
50 if (test_bit(CACHE_VALID, &key->h.flags) &&
51 !test_bit(CACHE_NEGATIVE, &key->h.flags))
52 path_put(&key->ek_path);
53 auth_domain_put(key->ek_client);
54 kfree_rcu(key, ek_rcu);
55 }
56
expkey_upcall(struct cache_detail * cd,struct cache_head * h)57 static int expkey_upcall(struct cache_detail *cd, struct cache_head *h)
58 {
59 return sunrpc_cache_upcall(cd, h);
60 }
61
expkey_request(struct cache_detail * cd,struct cache_head * h,char ** bpp,int * blen)62 static void expkey_request(struct cache_detail *cd,
63 struct cache_head *h,
64 char **bpp, int *blen)
65 {
66 /* client fsidtype \xfsid */
67 struct svc_expkey *ek = container_of(h, struct svc_expkey, h);
68 char type[5];
69
70 qword_add(bpp, blen, ek->ek_client->name);
71 snprintf(type, 5, "%d", ek->ek_fsidtype);
72 qword_add(bpp, blen, type);
73 qword_addhex(bpp, blen, (char*)ek->ek_fsid, key_len(ek->ek_fsidtype));
74 (*bpp)[-1] = '\n';
75 }
76
77 static struct svc_expkey *svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
78 struct svc_expkey *old);
79 static struct svc_expkey *svc_expkey_lookup(struct cache_detail *cd, struct svc_expkey *);
80
expkey_parse(struct cache_detail * cd,char * mesg,int mlen)81 static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
82 {
83 /* client fsidtype fsid expiry [path] */
84 char *buf;
85 int len;
86 struct auth_domain *dom = NULL;
87 int err;
88 u8 fsidtype;
89 struct svc_expkey key;
90 struct svc_expkey *ek = NULL;
91
92 if (mesg[mlen - 1] != '\n')
93 return -EINVAL;
94 mesg[mlen-1] = 0;
95
96 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
97 err = -ENOMEM;
98 if (!buf)
99 goto out;
100
101 err = -EINVAL;
102 if (qword_get(&mesg, buf, PAGE_SIZE) <= 0)
103 goto out;
104
105 err = -ENOENT;
106 dom = auth_domain_find(buf);
107 if (!dom)
108 goto out;
109 dprintk("found domain %s\n", buf);
110
111 err = -EINVAL;
112 if (qword_get(&mesg, buf, PAGE_SIZE) <= 0)
113 goto out;
114 if (kstrtou8(buf, 10, &fsidtype))
115 goto out;
116 dprintk("found fsidtype %u\n", fsidtype);
117 if (key_len(fsidtype)==0) /* invalid type */
118 goto out;
119 if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0)
120 goto out;
121 dprintk("found fsid length %d\n", len);
122 if (len != key_len(fsidtype))
123 goto out;
124
125 /* OK, we seem to have a valid key */
126 key.h.flags = 0;
127 err = get_expiry(&mesg, &key.h.expiry_time);
128 if (err)
129 goto out;
130
131 key.ek_client = dom;
132 key.ek_fsidtype = fsidtype;
133 memcpy(key.ek_fsid, buf, len);
134
135 ek = svc_expkey_lookup(cd, &key);
136 err = -ENOMEM;
137 if (!ek)
138 goto out;
139
140 /* now we want a pathname, or empty meaning NEGATIVE */
141 err = -EINVAL;
142 len = qword_get(&mesg, buf, PAGE_SIZE);
143 if (len < 0)
144 goto out;
145 dprintk("Path seems to be <%s>\n", buf);
146 err = 0;
147 if (len == 0) {
148 set_bit(CACHE_NEGATIVE, &key.h.flags);
149 ek = svc_expkey_update(cd, &key, ek);
150 if (ek)
151 trace_nfsd_expkey_update(ek, NULL);
152 else
153 err = -ENOMEM;
154 } else {
155 err = kern_path(buf, 0, &key.ek_path);
156 if (err)
157 goto out;
158
159 dprintk("Found the path %s\n", buf);
160
161 ek = svc_expkey_update(cd, &key, ek);
162 if (ek)
163 trace_nfsd_expkey_update(ek, buf);
164 else
165 err = -ENOMEM;
166 path_put(&key.ek_path);
167 }
168 cache_flush();
169 out:
170 if (ek)
171 cache_put(&ek->h, cd);
172 if (dom)
173 auth_domain_put(dom);
174 kfree(buf);
175 return err;
176 }
177
expkey_show(struct seq_file * m,struct cache_detail * cd,struct cache_head * h)178 static int expkey_show(struct seq_file *m,
179 struct cache_detail *cd,
180 struct cache_head *h)
181 {
182 struct svc_expkey *ek ;
183 int i;
184
185 if (h ==NULL) {
186 seq_puts(m, "#domain fsidtype fsid [path]\n");
187 return 0;
188 }
189 ek = container_of(h, struct svc_expkey, h);
190 seq_printf(m, "%s %d 0x", ek->ek_client->name,
191 ek->ek_fsidtype);
192 for (i=0; i < key_len(ek->ek_fsidtype)/4; i++)
193 seq_printf(m, "%08x", ek->ek_fsid[i]);
194 if (test_bit(CACHE_VALID, &h->flags) &&
195 !test_bit(CACHE_NEGATIVE, &h->flags)) {
196 seq_printf(m, " ");
197 seq_path(m, &ek->ek_path, "\\ \t\n");
198 }
199 seq_printf(m, "\n");
200 return 0;
201 }
202
expkey_match(struct cache_head * a,struct cache_head * b)203 static inline int expkey_match (struct cache_head *a, struct cache_head *b)
204 {
205 struct svc_expkey *orig = container_of(a, struct svc_expkey, h);
206 struct svc_expkey *new = container_of(b, struct svc_expkey, h);
207
208 if (orig->ek_fsidtype != new->ek_fsidtype ||
209 orig->ek_client != new->ek_client ||
210 memcmp(orig->ek_fsid, new->ek_fsid, key_len(orig->ek_fsidtype)) != 0)
211 return 0;
212 return 1;
213 }
214
expkey_init(struct cache_head * cnew,struct cache_head * citem)215 static inline void expkey_init(struct cache_head *cnew,
216 struct cache_head *citem)
217 {
218 struct svc_expkey *new = container_of(cnew, struct svc_expkey, h);
219 struct svc_expkey *item = container_of(citem, struct svc_expkey, h);
220
221 kref_get(&item->ek_client->ref);
222 new->ek_client = item->ek_client;
223 new->ek_fsidtype = item->ek_fsidtype;
224
225 memcpy(new->ek_fsid, item->ek_fsid, sizeof(new->ek_fsid));
226 }
227
expkey_update(struct cache_head * cnew,struct cache_head * citem)228 static inline void expkey_update(struct cache_head *cnew,
229 struct cache_head *citem)
230 {
231 struct svc_expkey *new = container_of(cnew, struct svc_expkey, h);
232 struct svc_expkey *item = container_of(citem, struct svc_expkey, h);
233
234 new->ek_path = item->ek_path;
235 path_get(&item->ek_path);
236 }
237
expkey_alloc(void)238 static struct cache_head *expkey_alloc(void)
239 {
240 struct svc_expkey *i = kmalloc_obj(*i);
241 if (i)
242 return &i->h;
243 else
244 return NULL;
245 }
246
expkey_flush(void)247 static void expkey_flush(void)
248 {
249 /*
250 * Take the nfsd_mutex here to ensure that the file cache is not
251 * destroyed while we're in the middle of flushing.
252 */
253 mutex_lock(&nfsd_mutex);
254 nfsd_file_cache_purge(current->nsproxy->net_ns);
255 mutex_unlock(&nfsd_mutex);
256 }
257
expkey_notify(struct cache_detail * cd,struct cache_head * h)258 static int expkey_notify(struct cache_detail *cd, struct cache_head *h)
259 {
260 return nfsd_cache_notify(cd, h, NFSD_CACHE_TYPE_EXPKEY);
261 }
262
263 static const struct cache_detail svc_expkey_cache_template = {
264 .owner = THIS_MODULE,
265 .hash_size = EXPKEY_HASHMAX,
266 .name = "nfsd.fh",
267 .cache_put = expkey_put,
268 .cache_upcall = expkey_upcall,
269 .cache_notify = expkey_notify,
270 .cache_request = expkey_request,
271 .cache_parse = expkey_parse,
272 .cache_show = expkey_show,
273 .match = expkey_match,
274 .init = expkey_init,
275 .update = expkey_update,
276 .alloc = expkey_alloc,
277 .flush = expkey_flush,
278 };
279
280 static int
svc_expkey_hash(struct svc_expkey * item)281 svc_expkey_hash(struct svc_expkey *item)
282 {
283 int hash = item->ek_fsidtype;
284 char * cp = (char*)item->ek_fsid;
285 int len = key_len(item->ek_fsidtype);
286
287 hash ^= hash_mem(cp, len, EXPKEY_HASHBITS);
288 hash ^= hash_ptr(item->ek_client, EXPKEY_HASHBITS);
289 hash &= EXPKEY_HASHMASK;
290 return hash;
291 }
292
293 static struct svc_expkey *
svc_expkey_lookup(struct cache_detail * cd,struct svc_expkey * item)294 svc_expkey_lookup(struct cache_detail *cd, struct svc_expkey *item)
295 {
296 struct cache_head *ch;
297 int hash = svc_expkey_hash(item);
298
299 ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
300 if (ch)
301 return container_of(ch, struct svc_expkey, h);
302 else
303 return NULL;
304 }
305
306 static struct svc_expkey *
svc_expkey_update(struct cache_detail * cd,struct svc_expkey * new,struct svc_expkey * old)307 svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
308 struct svc_expkey *old)
309 {
310 struct cache_head *ch;
311 int hash = svc_expkey_hash(new);
312
313 ch = sunrpc_cache_update(cd, &new->h, &old->h, hash);
314 if (ch)
315 return container_of(ch, struct svc_expkey, h);
316 else
317 return NULL;
318 }
319
320 /**
321 * nfsd_nl_expkey_get_reqs_dumpit - dump pending expkey requests
322 * @skb: reply buffer
323 * @cb: netlink metadata and command arguments
324 *
325 * Walk the expkey cache's pending request list and create a netlink
326 * message with a nested entry for each cache_request, containing the
327 * seqno, client string, fsidtype and fsid.
328 *
329 * Uses cb->args[0] as a seqno cursor for dump continuation across
330 * multiple netlink messages.
331 *
332 * Returns the size of the reply or a negative errno.
333 */
nfsd_nl_expkey_get_reqs_dumpit(struct sk_buff * skb,struct netlink_callback * cb)334 int nfsd_nl_expkey_get_reqs_dumpit(struct sk_buff *skb,
335 struct netlink_callback *cb)
336 {
337 struct nfsd_net *nn;
338 struct cache_detail *cd;
339 struct cache_head **items;
340 u64 *seqnos;
341 int cnt, i, emitted;
342 void *hdr;
343 int ret;
344
345 nn = net_generic(sock_net(skb->sk), nfsd_net_id);
346
347 mutex_lock(&nfsd_mutex);
348
349 cd = nn->svc_expkey_cache;
350 if (!cd) {
351 ret = -ENODEV;
352 goto out_unlock;
353 }
354
355 cnt = sunrpc_cache_requests_count(cd);
356 if (!cnt) {
357 ret = 0;
358 goto out_unlock;
359 }
360
361 items = kzalloc_objs(*items, cnt);
362 seqnos = kcalloc(cnt, sizeof(*seqnos), GFP_KERNEL);
363 if (!items || !seqnos) {
364 ret = -ENOMEM;
365 goto out_alloc;
366 }
367
368 cnt = sunrpc_cache_requests_snapshot(cd, items, seqnos, cnt,
369 cb->args[0]);
370 if (!cnt) {
371 ret = 0;
372 goto out_alloc;
373 }
374
375 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
376 cb->nlh->nlmsg_seq, &nfsd_nl_family,
377 NLM_F_MULTI, NFSD_CMD_EXPKEY_GET_REQS);
378 if (!hdr) {
379 ret = -ENOBUFS;
380 goto out_put;
381 }
382
383 emitted = 0;
384 for (i = 0; i < cnt; i++) {
385 struct svc_expkey *ek;
386 struct nlattr *nest;
387
388 ek = container_of(items[i], struct svc_expkey, h);
389
390 nest = nla_nest_start(skb, NFSD_A_EXPKEY_REQS_REQUESTS);
391 if (!nest)
392 break;
393
394 if (nla_put_u64_64bit(skb, NFSD_A_EXPKEY_SEQNO,
395 seqnos[i], 0) ||
396 nla_put_string(skb, NFSD_A_EXPKEY_CLIENT,
397 ek->ek_client->name) ||
398 nla_put_u8(skb, NFSD_A_EXPKEY_FSIDTYPE,
399 ek->ek_fsidtype) ||
400 nla_put(skb, NFSD_A_EXPKEY_FSID,
401 key_len(ek->ek_fsidtype), ek->ek_fsid)) {
402 nla_nest_cancel(skb, nest);
403 break;
404 }
405
406 nla_nest_end(skb, nest);
407 cb->args[0] = seqnos[i];
408 emitted++;
409 }
410
411 if (!emitted) {
412 genlmsg_cancel(skb, hdr);
413 ret = -EMSGSIZE;
414 goto out_put;
415 }
416
417 genlmsg_end(skb, hdr);
418 ret = skb->len;
419 out_put:
420 for (i = 0; i < cnt; i++)
421 cache_put(items[i], cd);
422 out_alloc:
423 kfree(seqnos);
424 kfree(items);
425 out_unlock:
426 mutex_unlock(&nfsd_mutex);
427 return ret;
428 }
429
430 /**
431 * nfsd_nl_parse_one_expkey - parse one expkey entry from netlink
432 * @cd: cache_detail for the expkey cache
433 * @attr: nested attribute containing expkey fields
434 *
435 * Parses one expkey entry from a netlink message and updates the
436 * cache. Mirrors the logic in expkey_parse().
437 *
438 * Returns 0 on success or a negative errno.
439 */
nfsd_nl_parse_one_expkey(struct cache_detail * cd,struct nlattr * attr)440 static int nfsd_nl_parse_one_expkey(struct cache_detail *cd,
441 struct nlattr *attr)
442 {
443 struct nlattr *tb[NFSD_A_EXPKEY_PATH + 1];
444 struct auth_domain *dom = NULL;
445 struct svc_expkey key;
446 struct svc_expkey *ek = NULL;
447 struct timespec64 boot;
448 int err;
449 u8 fsidtype;
450 int fsid_len;
451
452 err = nla_parse_nested(tb, NFSD_A_EXPKEY_PATH, attr,
453 nfsd_expkey_nl_policy, NULL);
454 if (err)
455 return err;
456
457 /* client (required) */
458 if (!tb[NFSD_A_EXPKEY_CLIENT])
459 return -EINVAL;
460
461 dom = auth_domain_find(nla_data(tb[NFSD_A_EXPKEY_CLIENT]));
462 if (!dom)
463 return -ENOENT;
464
465 /* fsidtype (required) */
466 if (!tb[NFSD_A_EXPKEY_FSIDTYPE]) {
467 err = -EINVAL;
468 goto out_dom;
469 }
470 fsidtype = nla_get_u8(tb[NFSD_A_EXPKEY_FSIDTYPE]);
471 if (key_len(fsidtype) == 0) {
472 err = -EINVAL;
473 goto out_dom;
474 }
475
476 /* fsid (required) */
477 if (!tb[NFSD_A_EXPKEY_FSID]) {
478 err = -EINVAL;
479 goto out_dom;
480 }
481 fsid_len = nla_len(tb[NFSD_A_EXPKEY_FSID]);
482 if (fsid_len != key_len(fsidtype)) {
483 err = -EINVAL;
484 goto out_dom;
485 }
486
487 /* expiry (required, wallclock seconds) */
488 if (!tb[NFSD_A_EXPKEY_EXPIRY]) {
489 err = -EINVAL;
490 goto out_dom;
491 }
492
493 key.h.flags = 0;
494 getboottime64(&boot);
495 key.h.expiry_time = nla_get_u64(tb[NFSD_A_EXPKEY_EXPIRY]) -
496 boot.tv_sec;
497 key.ek_client = dom;
498 key.ek_fsidtype = fsidtype;
499 memcpy(key.ek_fsid, nla_data(tb[NFSD_A_EXPKEY_FSID]), fsid_len);
500
501 ek = svc_expkey_lookup(cd, &key);
502 if (!ek) {
503 err = -ENOMEM;
504 goto out_dom;
505 }
506
507 if (tb[NFSD_A_EXPKEY_NEGATIVE]) {
508 set_bit(CACHE_NEGATIVE, &key.h.flags);
509 ek = svc_expkey_update(cd, &key, ek);
510 if (ek)
511 trace_nfsd_expkey_update(ek, NULL);
512 else
513 err = -ENOMEM;
514 } else if (tb[NFSD_A_EXPKEY_PATH]) {
515 err = kern_path(nla_data(tb[NFSD_A_EXPKEY_PATH]), 0,
516 &key.ek_path);
517 if (err)
518 goto out_ek;
519 ek = svc_expkey_update(cd, &key, ek);
520 if (ek)
521 trace_nfsd_expkey_update(ek,
522 nla_data(tb[NFSD_A_EXPKEY_PATH]));
523 else
524 err = -ENOMEM;
525 path_put(&key.ek_path);
526 } else {
527 err = -EINVAL;
528 goto out_ek;
529 }
530
531 cache_flush();
532
533 out_ek:
534 if (ek)
535 cache_put(&ek->h, cd);
536 out_dom:
537 auth_domain_put(dom);
538 return err;
539 }
540
541 /**
542 * nfsd_nl_expkey_set_reqs_doit - respond to expkey requests
543 * @skb: reply buffer
544 * @info: netlink metadata and command arguments
545 *
546 * Parse one or more expkey cache responses from userspace and
547 * update the expkey cache accordingly.
548 *
549 * Returns 0 on success or a negative errno.
550 */
nfsd_nl_expkey_set_reqs_doit(struct sk_buff * skb,struct genl_info * info)551 int nfsd_nl_expkey_set_reqs_doit(struct sk_buff *skb,
552 struct genl_info *info)
553 {
554 struct nfsd_net *nn;
555 struct cache_detail *cd;
556 const struct nlattr *attr;
557 int rem, ret = 0;
558
559 nn = net_generic(genl_info_net(info), nfsd_net_id);
560
561 mutex_lock(&nfsd_mutex);
562
563 cd = nn->svc_expkey_cache;
564 if (!cd) {
565 ret = -ENODEV;
566 goto out_unlock;
567 }
568
569 nlmsg_for_each_attr_type(attr, NFSD_A_EXPKEY_REQS_REQUESTS,
570 info->nlhdr, GENL_HDRLEN, rem) {
571 ret = nfsd_nl_parse_one_expkey(cd, (struct nlattr *)attr);
572 if (ret)
573 break;
574 }
575
576 out_unlock:
577 mutex_unlock(&nfsd_mutex);
578 return ret;
579 }
580
581 #define EXPORT_HASHBITS 8
582 #define EXPORT_HASHMAX (1<< EXPORT_HASHBITS)
583
nfsd4_fslocs_free(struct nfsd4_fs_locations * fsloc)584 static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
585 {
586 struct nfsd4_fs_location *locations = fsloc->locations;
587 int i;
588
589 if (!locations)
590 return;
591
592 for (i = 0; i < fsloc->locations_count; i++) {
593 kfree(locations[i].path);
594 kfree(locations[i].hosts);
595 }
596
597 kfree(locations);
598 fsloc->locations = NULL;
599 }
600
export_stats_init(struct export_stats * stats)601 static int export_stats_init(struct export_stats *stats)
602 {
603 stats->start_time = ktime_get_seconds();
604 return percpu_counter_init_many(stats->counter, 0, GFP_KERNEL,
605 EXP_STATS_COUNTERS_NUM);
606 }
607
export_stats_reset(struct export_stats * stats)608 static void export_stats_reset(struct export_stats *stats)
609 {
610 if (stats) {
611 int i;
612
613 for (i = 0; i < EXP_STATS_COUNTERS_NUM; i++)
614 percpu_counter_set(&stats->counter[i], 0);
615 }
616 }
617
export_stats_destroy(struct export_stats * stats)618 static void export_stats_destroy(struct export_stats *stats)
619 {
620 if (stats)
621 percpu_counter_destroy_many(stats->counter,
622 EXP_STATS_COUNTERS_NUM);
623 }
624
svc_export_release(struct rcu_head * rcu_head)625 static void svc_export_release(struct rcu_head *rcu_head)
626 {
627 struct svc_export *exp = container_of(rcu_head, struct svc_export,
628 ex_rcu);
629
630 nfsd4_fslocs_free(&exp->ex_fslocs);
631 export_stats_destroy(exp->ex_stats);
632 kfree(exp->ex_stats);
633 kfree(exp->ex_uuid);
634 kfree(exp);
635 }
636
svc_export_put(struct kref * ref)637 static void svc_export_put(struct kref *ref)
638 {
639 struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
640
641 path_put(&exp->ex_path);
642 auth_domain_put(exp->ex_client);
643 call_rcu(&exp->ex_rcu, svc_export_release);
644 }
645
646 /**
647 * nfsd_nl_svc_export_get_reqs_dumpit - dump pending svc_export requests
648 * @skb: reply buffer
649 * @cb: netlink metadata and command arguments
650 *
651 * Walk the svc_export cache's pending request list and create a netlink
652 * message with a nested entry for each cache_request, containing the
653 * seqno, client string, and path.
654 *
655 * Uses cb->args[0] as a seqno cursor for dump continuation across
656 * multiple netlink messages.
657 *
658 * Returns the size of the reply or a negative errno.
659 */
nfsd_nl_svc_export_get_reqs_dumpit(struct sk_buff * skb,struct netlink_callback * cb)660 int nfsd_nl_svc_export_get_reqs_dumpit(struct sk_buff *skb,
661 struct netlink_callback *cb)
662 {
663 struct nfsd_net *nn;
664 struct cache_detail *cd;
665 struct cache_head **items;
666 u64 *seqnos;
667 int cnt, i, emitted;
668 char *pathbuf;
669 void *hdr;
670 int ret;
671
672 nn = net_generic(sock_net(skb->sk), nfsd_net_id);
673
674 mutex_lock(&nfsd_mutex);
675
676 cd = nn->svc_export_cache;
677 if (!cd) {
678 ret = -ENODEV;
679 goto out_unlock;
680 }
681
682 cnt = sunrpc_cache_requests_count(cd);
683 if (!cnt) {
684 ret = 0;
685 goto out_unlock;
686 }
687
688 items = kzalloc_objs(*items, cnt);
689 seqnos = kcalloc(cnt, sizeof(*seqnos), GFP_KERNEL);
690 pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
691 if (!items || !seqnos || !pathbuf) {
692 ret = -ENOMEM;
693 goto out_alloc;
694 }
695
696 cnt = sunrpc_cache_requests_snapshot(cd, items, seqnos, cnt,
697 cb->args[0]);
698 if (!cnt) {
699 ret = 0;
700 goto out_alloc;
701 }
702
703 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
704 cb->nlh->nlmsg_seq, &nfsd_nl_family,
705 NLM_F_MULTI, NFSD_CMD_SVC_EXPORT_GET_REQS);
706 if (!hdr) {
707 ret = -ENOBUFS;
708 goto out_put;
709 }
710
711 emitted = 0;
712 for (i = 0; i < cnt; i++) {
713 struct svc_export *exp;
714 struct nlattr *nest;
715 char *pth;
716
717 exp = container_of(items[i], struct svc_export, h);
718
719 pth = d_path(&exp->ex_path, pathbuf, PATH_MAX);
720 if (IS_ERR(pth))
721 continue;
722
723 nest = nla_nest_start(skb,
724 NFSD_A_SVC_EXPORT_REQS_REQUESTS);
725 if (!nest)
726 break;
727
728 if (nla_put_u64_64bit(skb, NFSD_A_SVC_EXPORT_SEQNO,
729 seqnos[i], 0) ||
730 nla_put_string(skb, NFSD_A_SVC_EXPORT_CLIENT,
731 exp->ex_client->name) ||
732 nla_put_string(skb, NFSD_A_SVC_EXPORT_PATH, pth)) {
733 nla_nest_cancel(skb, nest);
734 break;
735 }
736
737 nla_nest_end(skb, nest);
738 cb->args[0] = seqnos[i];
739 emitted++;
740 }
741
742 if (!emitted) {
743 genlmsg_cancel(skb, hdr);
744 ret = -EMSGSIZE;
745 goto out_put;
746 }
747
748 genlmsg_end(skb, hdr);
749 ret = skb->len;
750 out_put:
751 for (i = 0; i < cnt; i++)
752 cache_put(items[i], cd);
753 out_alloc:
754 kfree(pathbuf);
755 kfree(seqnos);
756 kfree(items);
757 out_unlock:
758 mutex_unlock(&nfsd_mutex);
759 return ret;
760 }
761
762 /**
763 * nfsd_nl_parse_fslocations - parse fslocations from netlink
764 * @attr: NFSD_A_SVC_EXPORT_FSLOCATIONS nested attribute
765 * @fsloc: fslocations struct to fill in
766 *
767 * Returns 0 on success or a negative errno.
768 */
nfsd_nl_parse_fslocations(struct nlattr * attr,struct nfsd4_fs_locations * fsloc)769 static int nfsd_nl_parse_fslocations(struct nlattr *attr,
770 struct nfsd4_fs_locations *fsloc)
771 {
772 struct nlattr *loc_attr;
773 int rem, count = 0;
774 int err;
775
776 if (fsloc->locations)
777 return -EINVAL;
778
779 /* Count locations first */
780 nla_for_each_nested_type(loc_attr, NFSD_A_FSLOCATIONS_LOCATION,
781 attr, rem)
782 count++;
783
784 if (count > MAX_FS_LOCATIONS)
785 return -EINVAL;
786 if (!count)
787 return 0;
788
789 fsloc->locations = kzalloc_objs(struct nfsd4_fs_location, count);
790 if (!fsloc->locations)
791 return -ENOMEM;
792
793 nla_for_each_nested_type(loc_attr, NFSD_A_FSLOCATIONS_LOCATION,
794 attr, rem) {
795 struct nlattr *tb[NFSD_A_FSLOCATION_PATH + 1];
796 struct nfsd4_fs_location *loc;
797
798 err = nla_parse_nested(tb, NFSD_A_FSLOCATION_PATH, loc_attr,
799 nfsd_fslocation_nl_policy, NULL);
800 if (err)
801 goto out_free;
802
803 if (!tb[NFSD_A_FSLOCATION_HOST] ||
804 !tb[NFSD_A_FSLOCATION_PATH]) {
805 err = -EINVAL;
806 goto out_free;
807 }
808
809 loc = &fsloc->locations[fsloc->locations_count++];
810 loc->hosts = kstrdup(nla_data(tb[NFSD_A_FSLOCATION_HOST]),
811 GFP_KERNEL);
812 loc->path = kstrdup(nla_data(tb[NFSD_A_FSLOCATION_PATH]),
813 GFP_KERNEL);
814 if (!loc->hosts || !loc->path) {
815 err = -ENOMEM;
816 goto out_free;
817 }
818 }
819
820 return 0;
821 out_free:
822 nfsd4_fslocs_free(fsloc);
823 return err;
824 }
825
826 static struct svc_export *svc_export_update(struct svc_export *new,
827 struct svc_export *old);
828 static struct svc_export *svc_export_lookup(struct svc_export *);
829 static int check_export(const struct path *path, int *flags,
830 unsigned char *uuid);
831
832 /**
833 * nfsd_nl_parse_one_export - parse one svc_export entry from a netlink message
834 * @cd: cache_detail for the svc_export cache
835 * @attr: nested attribute containing svc-export fields
836 *
837 * Parses one svc-export entry from a netlink message and updates the
838 * cache. Mirrors the logic in svc_export_parse().
839 *
840 * Returns 0 on success or a negative errno.
841 */
nfsd_nl_parse_one_export(struct cache_detail * cd,struct nlattr * attr)842 static int nfsd_nl_parse_one_export(struct cache_detail *cd,
843 struct nlattr *attr)
844 {
845 struct nlattr *tb[NFSD_A_SVC_EXPORT_FSID + 1];
846 struct auth_domain *dom = NULL;
847 struct svc_export exp = {}, *expp;
848 struct nlattr *secinfo_attr;
849 struct timespec64 boot;
850 int err, rem;
851
852 err = nla_parse_nested(tb, NFSD_A_SVC_EXPORT_FSID, attr,
853 nfsd_svc_export_nl_policy, NULL);
854 if (err)
855 return err;
856
857 /* client (required) */
858 if (!tb[NFSD_A_SVC_EXPORT_CLIENT])
859 return -EINVAL;
860
861 dom = auth_domain_find(nla_data(tb[NFSD_A_SVC_EXPORT_CLIENT]));
862 if (!dom)
863 return -ENOENT;
864
865 /* path (required) */
866 if (!tb[NFSD_A_SVC_EXPORT_PATH]) {
867 err = -EINVAL;
868 goto out_dom;
869 }
870
871 err = kern_path(nla_data(tb[NFSD_A_SVC_EXPORT_PATH]), 0,
872 &exp.ex_path);
873 if (err)
874 goto out_dom;
875
876 exp.ex_client = dom;
877 exp.cd = cd;
878 exp.ex_devid_map = NULL;
879 exp.ex_xprtsec_modes = NFSEXP_XPRTSEC_ALL;
880
881 /* expiry (required, wallclock seconds) */
882 if (!tb[NFSD_A_SVC_EXPORT_EXPIRY]) {
883 err = -EINVAL;
884 goto out_path;
885 }
886 getboottime64(&boot);
887 exp.h.expiry_time = nla_get_u64(tb[NFSD_A_SVC_EXPORT_EXPIRY]) -
888 boot.tv_sec;
889
890 if (tb[NFSD_A_SVC_EXPORT_NEGATIVE]) {
891 set_bit(CACHE_NEGATIVE, &exp.h.flags);
892 } else {
893 /* flags */
894 if (tb[NFSD_A_SVC_EXPORT_FLAGS])
895 exp.ex_flags = nla_get_u32(tb[NFSD_A_SVC_EXPORT_FLAGS]);
896
897 /* anon uid */
898 if (tb[NFSD_A_SVC_EXPORT_ANON_UID]) {
899 u32 uid = nla_get_u32(tb[NFSD_A_SVC_EXPORT_ANON_UID]);
900
901 exp.ex_anon_uid = make_kuid(current_user_ns(), uid);
902 }
903
904 /* anon gid */
905 if (tb[NFSD_A_SVC_EXPORT_ANON_GID]) {
906 u32 gid = nla_get_u32(tb[NFSD_A_SVC_EXPORT_ANON_GID]);
907
908 exp.ex_anon_gid = make_kgid(current_user_ns(), gid);
909 }
910
911 /* fsid */
912 if (tb[NFSD_A_SVC_EXPORT_FSID])
913 exp.ex_fsid = nla_get_s32(tb[NFSD_A_SVC_EXPORT_FSID]);
914
915 /* fslocations */
916 if (tb[NFSD_A_SVC_EXPORT_FSLOCATIONS]) {
917 struct nlattr *fsl = tb[NFSD_A_SVC_EXPORT_FSLOCATIONS];
918
919 err = nfsd_nl_parse_fslocations(fsl,
920 &exp.ex_fslocs);
921 if (err)
922 goto out_path;
923 }
924
925 /* uuid */
926 if (tb[NFSD_A_SVC_EXPORT_UUID]) {
927 if (nla_len(tb[NFSD_A_SVC_EXPORT_UUID]) !=
928 EX_UUID_LEN) {
929 err = -EINVAL;
930 goto out_fslocs;
931 }
932 exp.ex_uuid = kmemdup(nla_data(tb[NFSD_A_SVC_EXPORT_UUID]),
933 EX_UUID_LEN, GFP_KERNEL);
934 if (!exp.ex_uuid) {
935 err = -ENOMEM;
936 goto out_fslocs;
937 }
938 }
939
940 /* secinfo (multi-attr) */
941 nla_for_each_nested_type(secinfo_attr,
942 NFSD_A_SVC_EXPORT_SECINFO,
943 attr, rem) {
944 struct nlattr *ftb[NFSD_A_AUTH_FLAVOR_FLAGS + 1];
945 struct exp_flavor_info *f;
946
947 if (exp.ex_nflavors >= MAX_SECINFO_LIST) {
948 err = -EINVAL;
949 goto out_uuid;
950 }
951
952 err = nla_parse_nested(ftb,
953 NFSD_A_AUTH_FLAVOR_FLAGS,
954 secinfo_attr,
955 nfsd_auth_flavor_nl_policy,
956 NULL);
957 if (err)
958 goto out_uuid;
959
960 f = &exp.ex_flavors[exp.ex_nflavors++];
961
962 if (ftb[NFSD_A_AUTH_FLAVOR_PSEUDOFLAVOR])
963 f->pseudoflavor = nla_get_u32(ftb[NFSD_A_AUTH_FLAVOR_PSEUDOFLAVOR]);
964
965 if (ftb[NFSD_A_AUTH_FLAVOR_FLAGS])
966 f->flags = nla_get_u32(ftb[NFSD_A_AUTH_FLAVOR_FLAGS]);
967
968 /* Only some flags are allowed to differ between flavors: */
969 if (~NFSEXP_SECINFO_FLAGS & (f->flags ^ exp.ex_flags)) {
970 err = -EINVAL;
971 goto out_uuid;
972 }
973 }
974
975 /* xprtsec (multi-attr u32) */
976 if (tb[NFSD_A_SVC_EXPORT_XPRTSEC]) {
977 struct nlattr *xp_attr;
978
979 exp.ex_xprtsec_modes = 0;
980 nla_for_each_nested_type(xp_attr,
981 NFSD_A_SVC_EXPORT_XPRTSEC,
982 attr, rem) {
983 u32 mode = nla_get_u32(xp_attr);
984
985 if (mode > NFSEXP_XPRTSEC_MTLS) {
986 err = -EINVAL;
987 goto out_uuid;
988 }
989 exp.ex_xprtsec_modes |= mode;
990 }
991 }
992
993 err = check_export(&exp.ex_path, &exp.ex_flags,
994 exp.ex_uuid);
995 if (err)
996 goto out_uuid;
997
998 if (exp.h.expiry_time < seconds_since_boot())
999 goto out_uuid;
1000
1001 err = -EINVAL;
1002 if (!uid_valid(exp.ex_anon_uid))
1003 goto out_uuid;
1004 if (!gid_valid(exp.ex_anon_gid))
1005 goto out_uuid;
1006 err = 0;
1007
1008 if (exp.ex_flags & NFSEXP_PNFS)
1009 nfsd4_setup_layout_type(&exp);
1010 }
1011
1012 expp = svc_export_lookup(&exp);
1013 if (!expp) {
1014 err = -ENOMEM;
1015 goto out_uuid;
1016 }
1017 expp = svc_export_update(&exp, expp);
1018 if (expp) {
1019 trace_nfsd_export_update(expp);
1020 cache_flush();
1021 exp_put(expp);
1022 } else {
1023 err = -ENOMEM;
1024 }
1025
1026 out_uuid:
1027 kfree(exp.ex_uuid);
1028 out_fslocs:
1029 nfsd4_fslocs_free(&exp.ex_fslocs);
1030 out_path:
1031 path_put(&exp.ex_path);
1032 out_dom:
1033 auth_domain_put(dom);
1034 return err;
1035 }
1036
1037 /**
1038 * nfsd_nl_svc_export_set_reqs_doit - respond to svc_export requests
1039 * @skb: reply buffer
1040 * @info: netlink metadata and command arguments
1041 *
1042 * Parse one or more svc_export cache responses from userspace and
1043 * update the export cache accordingly.
1044 *
1045 * Returns 0 on success or a negative errno.
1046 */
nfsd_nl_svc_export_set_reqs_doit(struct sk_buff * skb,struct genl_info * info)1047 int nfsd_nl_svc_export_set_reqs_doit(struct sk_buff *skb,
1048 struct genl_info *info)
1049 {
1050 struct nfsd_net *nn;
1051 struct cache_detail *cd;
1052 const struct nlattr *attr;
1053 int rem, ret = 0;
1054
1055 nn = net_generic(genl_info_net(info), nfsd_net_id);
1056
1057 mutex_lock(&nfsd_mutex);
1058
1059 cd = nn->svc_export_cache;
1060 if (!cd) {
1061 ret = -ENODEV;
1062 goto out_unlock;
1063 }
1064
1065 nlmsg_for_each_attr_type(attr, NFSD_A_SVC_EXPORT_REQS_REQUESTS,
1066 info->nlhdr, GENL_HDRLEN, rem) {
1067 ret = nfsd_nl_parse_one_export(cd, (struct nlattr *)attr);
1068 if (ret)
1069 break;
1070 }
1071
1072 out_unlock:
1073 mutex_unlock(&nfsd_mutex);
1074 return ret;
1075 }
1076
svc_export_upcall(struct cache_detail * cd,struct cache_head * h)1077 static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
1078 {
1079 return sunrpc_cache_upcall(cd, h);
1080 }
1081
svc_export_notify(struct cache_detail * cd,struct cache_head * h)1082 static int svc_export_notify(struct cache_detail *cd, struct cache_head *h)
1083 {
1084 return nfsd_cache_notify(cd, h, NFSD_CACHE_TYPE_SVC_EXPORT);
1085 }
1086
svc_export_request(struct cache_detail * cd,struct cache_head * h,char ** bpp,int * blen)1087 static void svc_export_request(struct cache_detail *cd,
1088 struct cache_head *h,
1089 char **bpp, int *blen)
1090 {
1091 /* client path */
1092 struct svc_export *exp = container_of(h, struct svc_export, h);
1093 char *pth;
1094
1095 qword_add(bpp, blen, exp->ex_client->name);
1096 pth = d_path(&exp->ex_path, *bpp, *blen);
1097 if (IS_ERR(pth)) {
1098 /* is this correct? */
1099 (*bpp)[0] = '\n';
1100 return;
1101 }
1102 qword_add(bpp, blen, pth);
1103 (*bpp)[-1] = '\n';
1104 }
1105
check_export(const struct path * path,int * flags,unsigned char * uuid)1106 static int check_export(const struct path *path, int *flags, unsigned char *uuid)
1107 {
1108 struct inode *inode = d_inode(path->dentry);
1109
1110 /*
1111 * We currently export only dirs, regular files, and (for v4
1112 * pseudoroot) symlinks.
1113 */
1114 if (!S_ISDIR(inode->i_mode) &&
1115 !S_ISLNK(inode->i_mode) &&
1116 !S_ISREG(inode->i_mode))
1117 return -ENOTDIR;
1118
1119 /*
1120 * Mountd should never pass down a writeable V4ROOT export, but,
1121 * just to make sure:
1122 */
1123 if (*flags & NFSEXP_V4ROOT)
1124 *flags |= NFSEXP_READONLY;
1125
1126 /* There are two requirements on a filesystem to be exportable.
1127 * 1: We must be able to identify the filesystem from a number.
1128 * either a device number (so FS_REQUIRES_DEV needed)
1129 * or an FSID number (so NFSEXP_FSID or ->uuid is needed).
1130 * 2: We must be able to find an inode from a filehandle.
1131 * This means that s_export_op must be set and comply with
1132 * the requirements for remote filesystem export.
1133 * 3: We must not currently be on an idmapped mount.
1134 */
1135 if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) &&
1136 !(*flags & NFSEXP_FSID) &&
1137 uuid == NULL) {
1138 dprintk("exp_export: export of non-dev fs without fsid\n");
1139 return -EINVAL;
1140 }
1141
1142 if (!exportfs_may_export(inode->i_sb->s_export_op)) {
1143 dprintk("exp_export: export of invalid fs type (%s).\n",
1144 inode->i_sb->s_type->name);
1145 return -EINVAL;
1146 }
1147
1148 if (is_idmapped_mnt(path->mnt)) {
1149 dprintk("exp_export: export of idmapped mounts not yet supported.\n");
1150 return -EINVAL;
1151 }
1152
1153 if (inode->i_sb->s_export_op->flags & EXPORT_OP_NOSUBTREECHK &&
1154 !(*flags & NFSEXP_NOSUBTREECHECK)) {
1155 dprintk("%s: %s does not support subtree checking!\n",
1156 __func__, inode->i_sb->s_type->name);
1157 return -EINVAL;
1158 }
1159 return 0;
1160 }
1161
1162 #ifdef CONFIG_NFSD_V4
1163
1164 static int
fsloc_parse(char ** mesg,char * buf,struct nfsd4_fs_locations * fsloc)1165 fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc)
1166 {
1167 int len;
1168 int migrated, i, err;
1169
1170 /* more than one fsloc */
1171 if (fsloc->locations)
1172 return -EINVAL;
1173
1174 /* listsize */
1175 err = get_uint(mesg, &fsloc->locations_count);
1176 if (err)
1177 return err;
1178 if (fsloc->locations_count > MAX_FS_LOCATIONS)
1179 return -EINVAL;
1180 if (fsloc->locations_count == 0)
1181 return 0;
1182
1183 fsloc->locations = kzalloc_objs(struct nfsd4_fs_location,
1184 fsloc->locations_count);
1185 if (!fsloc->locations)
1186 return -ENOMEM;
1187 for (i=0; i < fsloc->locations_count; i++) {
1188 /* colon separated host list */
1189 err = -EINVAL;
1190 len = qword_get(mesg, buf, PAGE_SIZE);
1191 if (len <= 0)
1192 goto out_free_all;
1193 err = -ENOMEM;
1194 fsloc->locations[i].hosts = kstrdup(buf, GFP_KERNEL);
1195 if (!fsloc->locations[i].hosts)
1196 goto out_free_all;
1197 err = -EINVAL;
1198 /* slash separated path component list */
1199 len = qword_get(mesg, buf, PAGE_SIZE);
1200 if (len <= 0)
1201 goto out_free_all;
1202 err = -ENOMEM;
1203 fsloc->locations[i].path = kstrdup(buf, GFP_KERNEL);
1204 if (!fsloc->locations[i].path)
1205 goto out_free_all;
1206 }
1207 /* migrated */
1208 err = get_int(mesg, &migrated);
1209 if (err)
1210 goto out_free_all;
1211 err = -EINVAL;
1212 if (migrated < 0 || migrated > 1)
1213 goto out_free_all;
1214 fsloc->migrated = migrated;
1215 return 0;
1216 out_free_all:
1217 nfsd4_fslocs_free(fsloc);
1218 return err;
1219 }
1220
secinfo_parse(char ** mesg,char * buf,struct svc_export * exp)1221 static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp)
1222 {
1223 struct exp_flavor_info *f;
1224 u32 listsize;
1225 int err;
1226
1227 /* more than one secinfo */
1228 if (exp->ex_nflavors)
1229 return -EINVAL;
1230
1231 err = get_uint(mesg, &listsize);
1232 if (err)
1233 return err;
1234 if (listsize > MAX_SECINFO_LIST)
1235 return -EINVAL;
1236
1237 for (f = exp->ex_flavors; f < exp->ex_flavors + listsize; f++) {
1238 err = get_uint(mesg, &f->pseudoflavor);
1239 if (err)
1240 return err;
1241 /*
1242 * XXX: It would be nice to also check whether this
1243 * pseudoflavor is supported, so we can discover the
1244 * problem at export time instead of when a client fails
1245 * to authenticate.
1246 */
1247 err = get_uint(mesg, &f->flags);
1248 if (err)
1249 return err;
1250 /* Only some flags are allowed to differ between flavors: */
1251 if (~NFSEXP_SECINFO_FLAGS & (f->flags ^ exp->ex_flags))
1252 return -EINVAL;
1253 }
1254 exp->ex_nflavors = listsize;
1255 return 0;
1256 }
1257
1258 #else /* CONFIG_NFSD_V4 */
1259 static inline int
fsloc_parse(char ** mesg,char * buf,struct nfsd4_fs_locations * fsloc)1260 fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc){return 0;}
1261 static inline int
secinfo_parse(char ** mesg,char * buf,struct svc_export * exp)1262 secinfo_parse(char **mesg, char *buf, struct svc_export *exp) { return 0; }
1263 #endif
1264
xprtsec_parse(char ** mesg,char * buf,struct svc_export * exp)1265 static int xprtsec_parse(char **mesg, char *buf, struct svc_export *exp)
1266 {
1267 unsigned int i, mode, listsize;
1268 int err;
1269
1270 err = get_uint(mesg, &listsize);
1271 if (err)
1272 return err;
1273 if (listsize > NFSEXP_XPRTSEC_NUM)
1274 return -EINVAL;
1275
1276 exp->ex_xprtsec_modes = 0;
1277 for (i = 0; i < listsize; i++) {
1278 err = get_uint(mesg, &mode);
1279 if (err)
1280 return err;
1281 if (mode > NFSEXP_XPRTSEC_MTLS)
1282 return -EINVAL;
1283 exp->ex_xprtsec_modes |= mode;
1284 }
1285 return 0;
1286 }
1287
1288 static inline int
nfsd_uuid_parse(char ** mesg,char * buf,unsigned char ** puuid)1289 nfsd_uuid_parse(char **mesg, char *buf, unsigned char **puuid)
1290 {
1291 int len;
1292
1293 /* more than one uuid */
1294 if (*puuid)
1295 return -EINVAL;
1296
1297 /* expect a 16 byte uuid encoded as \xXXXX... */
1298 len = qword_get(mesg, buf, PAGE_SIZE);
1299 if (len != EX_UUID_LEN)
1300 return -EINVAL;
1301
1302 *puuid = kmemdup(buf, EX_UUID_LEN, GFP_KERNEL);
1303 if (*puuid == NULL)
1304 return -ENOMEM;
1305
1306 return 0;
1307 }
1308
svc_export_parse(struct cache_detail * cd,char * mesg,int mlen)1309 static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
1310 {
1311 /* client path expiry [flags anonuid anongid fsid] */
1312 char *buf;
1313 int err;
1314 struct auth_domain *dom = NULL;
1315 struct svc_export exp = {}, *expp;
1316 int an_int;
1317
1318 if (mesg[mlen-1] != '\n')
1319 return -EINVAL;
1320 mesg[mlen-1] = 0;
1321
1322 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1323 if (!buf)
1324 return -ENOMEM;
1325
1326 /* client */
1327 err = -EINVAL;
1328 if (qword_get(&mesg, buf, PAGE_SIZE) <= 0)
1329 goto out;
1330
1331 err = -ENOENT;
1332 dom = auth_domain_find(buf);
1333 if (!dom)
1334 goto out;
1335
1336 /* path */
1337 err = -EINVAL;
1338 if (qword_get(&mesg, buf, PAGE_SIZE) <= 0)
1339 goto out1;
1340
1341 err = kern_path(buf, 0, &exp.ex_path);
1342 if (err)
1343 goto out1;
1344
1345 exp.ex_client = dom;
1346 exp.cd = cd;
1347 exp.ex_devid_map = NULL;
1348 exp.ex_xprtsec_modes = NFSEXP_XPRTSEC_ALL;
1349
1350 /* expiry */
1351 err = get_expiry(&mesg, &exp.h.expiry_time);
1352 if (err)
1353 goto out3;
1354
1355 /* flags */
1356 err = get_int(&mesg, &an_int);
1357 if (err == -ENOENT) {
1358 err = 0;
1359 set_bit(CACHE_NEGATIVE, &exp.h.flags);
1360 } else {
1361 if (err || an_int < 0)
1362 goto out3;
1363 exp.ex_flags= an_int;
1364
1365 /* anon uid */
1366 err = get_int(&mesg, &an_int);
1367 if (err)
1368 goto out3;
1369 exp.ex_anon_uid= make_kuid(current_user_ns(), an_int);
1370
1371 /* anon gid */
1372 err = get_int(&mesg, &an_int);
1373 if (err)
1374 goto out3;
1375 exp.ex_anon_gid= make_kgid(current_user_ns(), an_int);
1376
1377 /* fsid */
1378 err = get_int(&mesg, &an_int);
1379 if (err)
1380 goto out3;
1381 exp.ex_fsid = an_int;
1382
1383 while (qword_get(&mesg, buf, PAGE_SIZE) > 0) {
1384 if (strcmp(buf, "fsloc") == 0)
1385 err = fsloc_parse(&mesg, buf, &exp.ex_fslocs);
1386 else if (strcmp(buf, "uuid") == 0)
1387 err = nfsd_uuid_parse(&mesg, buf, &exp.ex_uuid);
1388 else if (strcmp(buf, "secinfo") == 0)
1389 err = secinfo_parse(&mesg, buf, &exp);
1390 else if (strcmp(buf, "xprtsec") == 0)
1391 err = xprtsec_parse(&mesg, buf, &exp);
1392 else
1393 /* quietly ignore unknown words and anything
1394 * following. Newer user-space can try to set
1395 * new values, then see what the result was.
1396 */
1397 break;
1398 if (err)
1399 goto out4;
1400 }
1401
1402 err = check_export(&exp.ex_path, &exp.ex_flags, exp.ex_uuid);
1403 if (err)
1404 goto out4;
1405
1406 /*
1407 * No point caching this if it would immediately expire.
1408 * Also, this protects exportfs's dummy export from the
1409 * anon_uid/anon_gid checks:
1410 */
1411 if (exp.h.expiry_time < seconds_since_boot())
1412 goto out4;
1413 /*
1414 * For some reason exportfs has been passing down an
1415 * invalid (-1) uid & gid on the "dummy" export which it
1416 * uses to test export support. To make sure exportfs
1417 * sees errors from check_export we therefore need to
1418 * delay these checks till after check_export:
1419 */
1420 err = -EINVAL;
1421 if (!uid_valid(exp.ex_anon_uid))
1422 goto out4;
1423 if (!gid_valid(exp.ex_anon_gid))
1424 goto out4;
1425 err = 0;
1426
1427 if (exp.ex_flags & NFSEXP_PNFS)
1428 nfsd4_setup_layout_type(&exp);
1429 }
1430
1431 expp = svc_export_lookup(&exp);
1432 if (!expp) {
1433 err = -ENOMEM;
1434 goto out4;
1435 }
1436 expp = svc_export_update(&exp, expp);
1437 if (expp) {
1438 trace_nfsd_export_update(expp);
1439 cache_flush();
1440 exp_put(expp);
1441 } else
1442 err = -ENOMEM;
1443 out4:
1444 nfsd4_fslocs_free(&exp.ex_fslocs);
1445 kfree(exp.ex_uuid);
1446 out3:
1447 path_put(&exp.ex_path);
1448 out1:
1449 auth_domain_put(dom);
1450 out:
1451 kfree(buf);
1452 return err;
1453 }
1454
1455 static void exp_flags(struct seq_file *m, int flag, int fsid,
1456 kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fslocs);
1457 static void show_secinfo(struct seq_file *m, struct svc_export *exp);
1458
is_export_stats_file(struct seq_file * m)1459 static int is_export_stats_file(struct seq_file *m)
1460 {
1461 /*
1462 * The export_stats file uses the same ops as the exports file.
1463 * We use the file's name to determine the reported info per export.
1464 * There is no rename in nsfdfs, so d_name.name is stable.
1465 */
1466 return !strcmp(m->file->f_path.dentry->d_name.name, "export_stats");
1467 }
1468
svc_export_show(struct seq_file * m,struct cache_detail * cd,struct cache_head * h)1469 static int svc_export_show(struct seq_file *m,
1470 struct cache_detail *cd,
1471 struct cache_head *h)
1472 {
1473 struct svc_export *exp;
1474 bool export_stats = is_export_stats_file(m);
1475
1476 if (h == NULL) {
1477 if (export_stats)
1478 seq_puts(m, "#path domain start-time\n#\tstats\n");
1479 else
1480 seq_puts(m, "#path domain(flags)\n");
1481 return 0;
1482 }
1483 exp = container_of(h, struct svc_export, h);
1484 seq_path(m, &exp->ex_path, " \t\n\\");
1485 seq_putc(m, '\t');
1486 seq_escape(m, exp->ex_client->name, " \t\n\\");
1487 if (export_stats) {
1488 struct percpu_counter *counter = exp->ex_stats->counter;
1489
1490 seq_printf(m, "\t%lld\n", exp->ex_stats->start_time);
1491 seq_printf(m, "\tfh_stale: %lld\n",
1492 percpu_counter_sum_positive(&counter[EXP_STATS_FH_STALE]));
1493 seq_printf(m, "\tio_read: %lld\n",
1494 percpu_counter_sum_positive(&counter[EXP_STATS_IO_READ]));
1495 seq_printf(m, "\tio_write: %lld\n",
1496 percpu_counter_sum_positive(&counter[EXP_STATS_IO_WRITE]));
1497 seq_putc(m, '\n');
1498 return 0;
1499 }
1500 seq_putc(m, '(');
1501 if (test_bit(CACHE_VALID, &h->flags) &&
1502 !test_bit(CACHE_NEGATIVE, &h->flags)) {
1503 exp_flags(m, exp->ex_flags, exp->ex_fsid,
1504 exp->ex_anon_uid, exp->ex_anon_gid, &exp->ex_fslocs);
1505 if (exp->ex_uuid) {
1506 int i;
1507 seq_puts(m, ",uuid=");
1508 for (i = 0; i < EX_UUID_LEN; i++) {
1509 if ((i&3) == 0 && i)
1510 seq_putc(m, ':');
1511 seq_printf(m, "%02x", exp->ex_uuid[i]);
1512 }
1513 }
1514 show_secinfo(m, exp);
1515 }
1516 seq_puts(m, ")\n");
1517 return 0;
1518 }
svc_export_match(struct cache_head * a,struct cache_head * b)1519 static int svc_export_match(struct cache_head *a, struct cache_head *b)
1520 {
1521 struct svc_export *orig = container_of(a, struct svc_export, h);
1522 struct svc_export *new = container_of(b, struct svc_export, h);
1523 return orig->ex_client == new->ex_client &&
1524 path_equal(&orig->ex_path, &new->ex_path);
1525 }
1526
svc_export_init(struct cache_head * cnew,struct cache_head * citem)1527 static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
1528 {
1529 struct svc_export *new = container_of(cnew, struct svc_export, h);
1530 struct svc_export *item = container_of(citem, struct svc_export, h);
1531
1532 kref_get(&item->ex_client->ref);
1533 new->ex_client = item->ex_client;
1534 new->ex_path = item->ex_path;
1535 path_get(&item->ex_path);
1536 new->ex_fslocs.locations = NULL;
1537 new->ex_fslocs.locations_count = 0;
1538 new->ex_fslocs.migrated = 0;
1539 new->ex_layout_types = 0;
1540 new->ex_uuid = NULL;
1541 new->cd = item->cd;
1542 export_stats_reset(new->ex_stats);
1543 }
1544
export_update(struct cache_head * cnew,struct cache_head * citem)1545 static void export_update(struct cache_head *cnew, struct cache_head *citem)
1546 {
1547 struct svc_export *new = container_of(cnew, struct svc_export, h);
1548 struct svc_export *item = container_of(citem, struct svc_export, h);
1549 int i;
1550
1551 new->ex_flags = item->ex_flags;
1552 new->ex_anon_uid = item->ex_anon_uid;
1553 new->ex_anon_gid = item->ex_anon_gid;
1554 new->ex_fsid = item->ex_fsid;
1555 new->ex_devid_map = item->ex_devid_map;
1556 item->ex_devid_map = NULL;
1557 new->ex_uuid = item->ex_uuid;
1558 item->ex_uuid = NULL;
1559 new->ex_fslocs.locations = item->ex_fslocs.locations;
1560 item->ex_fslocs.locations = NULL;
1561 new->ex_fslocs.locations_count = item->ex_fslocs.locations_count;
1562 item->ex_fslocs.locations_count = 0;
1563 new->ex_fslocs.migrated = item->ex_fslocs.migrated;
1564 item->ex_fslocs.migrated = 0;
1565 new->ex_layout_types = item->ex_layout_types;
1566 new->ex_nflavors = item->ex_nflavors;
1567 for (i = 0; i < MAX_SECINFO_LIST; i++) {
1568 new->ex_flavors[i] = item->ex_flavors[i];
1569 }
1570 new->ex_xprtsec_modes = item->ex_xprtsec_modes;
1571 }
1572
svc_export_alloc(void)1573 static struct cache_head *svc_export_alloc(void)
1574 {
1575 struct svc_export *i = kmalloc_obj(*i);
1576 if (!i)
1577 return NULL;
1578
1579 i->ex_stats = kmalloc_obj(*(i->ex_stats));
1580 if (!i->ex_stats) {
1581 kfree(i);
1582 return NULL;
1583 }
1584
1585 if (export_stats_init(i->ex_stats)) {
1586 kfree(i->ex_stats);
1587 kfree(i);
1588 return NULL;
1589 }
1590
1591 return &i->h;
1592 }
1593
1594 static const struct cache_detail svc_export_cache_template = {
1595 .owner = THIS_MODULE,
1596 .hash_size = EXPORT_HASHMAX,
1597 .name = "nfsd.export",
1598 .cache_put = svc_export_put,
1599 .cache_upcall = svc_export_upcall,
1600 .cache_notify = svc_export_notify,
1601 .cache_request = svc_export_request,
1602 .cache_parse = svc_export_parse,
1603 .cache_show = svc_export_show,
1604 .match = svc_export_match,
1605 .init = svc_export_init,
1606 .update = export_update,
1607 .alloc = svc_export_alloc,
1608 };
1609
1610 static int
svc_export_hash(struct svc_export * exp)1611 svc_export_hash(struct svc_export *exp)
1612 {
1613 int hash;
1614
1615 hash = hash_ptr(exp->ex_client, EXPORT_HASHBITS);
1616 hash ^= hash_ptr(exp->ex_path.dentry, EXPORT_HASHBITS);
1617 hash ^= hash_ptr(exp->ex_path.mnt, EXPORT_HASHBITS);
1618 return hash;
1619 }
1620
1621 static struct svc_export *
svc_export_lookup(struct svc_export * exp)1622 svc_export_lookup(struct svc_export *exp)
1623 {
1624 struct cache_head *ch;
1625 int hash = svc_export_hash(exp);
1626
1627 ch = sunrpc_cache_lookup_rcu(exp->cd, &exp->h, hash);
1628 if (ch)
1629 return container_of(ch, struct svc_export, h);
1630 else
1631 return NULL;
1632 }
1633
1634 static struct svc_export *
svc_export_update(struct svc_export * new,struct svc_export * old)1635 svc_export_update(struct svc_export *new, struct svc_export *old)
1636 {
1637 struct cache_head *ch;
1638 int hash = svc_export_hash(old);
1639
1640 ch = sunrpc_cache_update(old->cd, &new->h, &old->h, hash);
1641 if (ch)
1642 return container_of(ch, struct svc_export, h);
1643 else
1644 return NULL;
1645 }
1646
1647
1648 static struct svc_expkey *
exp_find_key(struct cache_detail * cd,struct auth_domain * clp,int fsid_type,u32 * fsidv,struct cache_req * reqp)1649 exp_find_key(struct cache_detail *cd, struct auth_domain *clp, int fsid_type,
1650 u32 *fsidv, struct cache_req *reqp)
1651 {
1652 struct svc_expkey key, *ek;
1653 int err;
1654
1655 if (!clp)
1656 return ERR_PTR(-ENOENT);
1657
1658 key.ek_client = clp;
1659 key.ek_fsidtype = fsid_type;
1660 memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
1661
1662 ek = svc_expkey_lookup(cd, &key);
1663 if (ek == NULL)
1664 return ERR_PTR(-ENOMEM);
1665 err = cache_check(cd, &ek->h, reqp);
1666 if (err) {
1667 trace_nfsd_exp_find_key(&key, err);
1668 return ERR_PTR(err);
1669 }
1670 return ek;
1671 }
1672
1673 static struct svc_export *
exp_get_by_name(struct cache_detail * cd,struct auth_domain * clp,const struct path * path,struct cache_req * reqp)1674 exp_get_by_name(struct cache_detail *cd, struct auth_domain *clp,
1675 const struct path *path, struct cache_req *reqp)
1676 {
1677 struct svc_export *exp, key;
1678 int err;
1679
1680 if (!clp)
1681 return ERR_PTR(-ENOENT);
1682
1683 key.ex_client = clp;
1684 key.ex_path = *path;
1685 key.cd = cd;
1686
1687 exp = svc_export_lookup(&key);
1688 if (exp == NULL)
1689 return ERR_PTR(-ENOMEM);
1690 err = cache_check(cd, &exp->h, reqp);
1691 if (err) {
1692 trace_nfsd_exp_get_by_name(&key, err);
1693 return ERR_PTR(err);
1694 }
1695 return exp;
1696 }
1697
1698 /*
1699 * Find the export entry for a given dentry.
1700 */
1701 static struct svc_export *
exp_parent(struct cache_detail * cd,struct auth_domain * clp,struct path * path)1702 exp_parent(struct cache_detail *cd, struct auth_domain *clp, struct path *path)
1703 {
1704 struct dentry *saved = dget(path->dentry);
1705 struct svc_export *exp = exp_get_by_name(cd, clp, path, NULL);
1706
1707 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
1708 struct dentry *parent = dget_parent(path->dentry);
1709 dput(path->dentry);
1710 path->dentry = parent;
1711 exp = exp_get_by_name(cd, clp, path, NULL);
1712 }
1713 dput(path->dentry);
1714 path->dentry = saved;
1715 return exp;
1716 }
1717
1718
1719
1720 /*
1721 * Obtain the root fh on behalf of a client.
1722 * This could be done in user space, but I feel that it adds some safety
1723 * since its harder to fool a kernel module than a user space program.
1724 */
1725 int
exp_rootfh(struct net * net,struct auth_domain * clp,char * name,struct knfsd_fh * f,int maxsize)1726 exp_rootfh(struct net *net, struct auth_domain *clp, char *name,
1727 struct knfsd_fh *f, int maxsize)
1728 {
1729 struct svc_export *exp;
1730 struct path path;
1731 struct inode *inode __maybe_unused;
1732 struct svc_fh fh;
1733 int err;
1734 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1735 struct cache_detail *cd = nn->svc_export_cache;
1736
1737 err = -EPERM;
1738 /* NB: we probably ought to check that it's NUL-terminated */
1739 if (kern_path(name, 0, &path)) {
1740 printk("nfsd: exp_rootfh path not found %s", name);
1741 return err;
1742 }
1743 inode = d_inode(path.dentry);
1744
1745 dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%llu)\n",
1746 name, path.dentry, clp->name,
1747 inode->i_sb->s_id, inode->i_ino);
1748 exp = exp_parent(cd, clp, &path);
1749 if (IS_ERR(exp)) {
1750 err = PTR_ERR(exp);
1751 goto out;
1752 }
1753
1754 /*
1755 * fh must be initialized before calling fh_compose
1756 */
1757 fh_init(&fh, maxsize);
1758 if (fh_compose(&fh, exp, path.dentry, NULL))
1759 err = -EINVAL;
1760 else
1761 err = 0;
1762 memcpy(f, &fh.fh_handle, sizeof(struct knfsd_fh));
1763 fh_put(&fh);
1764 exp_put(exp);
1765 out:
1766 path_put(&path);
1767 return err;
1768 }
1769
exp_find(struct cache_detail * cd,struct auth_domain * clp,int fsid_type,u32 * fsidv,struct cache_req * reqp)1770 static struct svc_export *exp_find(struct cache_detail *cd,
1771 struct auth_domain *clp, int fsid_type,
1772 u32 *fsidv, struct cache_req *reqp)
1773 {
1774 struct svc_export *exp;
1775 struct nfsd_net *nn = net_generic(cd->net, nfsd_net_id);
1776 struct svc_expkey *ek = exp_find_key(nn->svc_expkey_cache, clp, fsid_type, fsidv, reqp);
1777 if (IS_ERR(ek))
1778 return ERR_CAST(ek);
1779
1780 exp = exp_get_by_name(cd, clp, &ek->ek_path, reqp);
1781 cache_put(&ek->h, nn->svc_expkey_cache);
1782
1783 if (IS_ERR(exp))
1784 return ERR_CAST(exp);
1785 return exp;
1786 }
1787
1788 /**
1789 * check_xprtsec_policy - check if access to export is allowed by the
1790 * xprtsec policy
1791 * @exp: svc_export that is being accessed.
1792 * @rqstp: svc_rqst attempting to access @exp.
1793 *
1794 * Helper function for check_nfsd_access(). Note that callers should be
1795 * using check_nfsd_access() instead of calling this function directly. The
1796 * one exception is __fh_verify() since it has logic that may result in one
1797 * or both of the helpers being skipped.
1798 *
1799 * Return values:
1800 * %nfs_ok if access is granted, or
1801 * %nfserr_wrongsec if access is denied
1802 */
check_xprtsec_policy(struct svc_export * exp,struct svc_rqst * rqstp)1803 __be32 check_xprtsec_policy(struct svc_export *exp, struct svc_rqst *rqstp)
1804 {
1805 struct svc_xprt *xprt = rqstp->rq_xprt;
1806
1807 if (exp->ex_xprtsec_modes & NFSEXP_XPRTSEC_NONE) {
1808 if (!test_bit(XPT_TLS_SESSION, &xprt->xpt_flags))
1809 return nfs_ok;
1810 }
1811 if (exp->ex_xprtsec_modes & NFSEXP_XPRTSEC_TLS) {
1812 if (test_bit(XPT_TLS_SESSION, &xprt->xpt_flags) &&
1813 !test_bit(XPT_PEER_AUTH, &xprt->xpt_flags))
1814 return nfs_ok;
1815 }
1816 if (exp->ex_xprtsec_modes & NFSEXP_XPRTSEC_MTLS) {
1817 if (test_bit(XPT_TLS_SESSION, &xprt->xpt_flags) &&
1818 test_bit(XPT_PEER_AUTH, &xprt->xpt_flags))
1819 return nfs_ok;
1820 }
1821 return nfserr_wrongsec;
1822 }
1823
1824 /**
1825 * check_security_flavor - check if access to export is allowed by the
1826 * security flavor
1827 * @exp: svc_export that is being accessed.
1828 * @rqstp: svc_rqst attempting to access @exp.
1829 * @may_bypass_gss: reduce strictness of authorization check
1830 *
1831 * Helper function for check_nfsd_access(). Note that callers should be
1832 * using check_nfsd_access() instead of calling this function directly. The
1833 * one exception is __fh_verify() since it has logic that may result in one
1834 * or both of the helpers being skipped.
1835 *
1836 * Return values:
1837 * %nfs_ok if access is granted, or
1838 * %nfserr_wrongsec if access is denied
1839 */
check_security_flavor(struct svc_export * exp,struct svc_rqst * rqstp,bool may_bypass_gss)1840 __be32 check_security_flavor(struct svc_export *exp, struct svc_rqst *rqstp,
1841 bool may_bypass_gss)
1842 {
1843 struct exp_flavor_info *f, *end = exp->ex_flavors + exp->ex_nflavors;
1844
1845 /* legacy gss-only clients are always OK: */
1846 if (exp->ex_client == rqstp->rq_gssclient)
1847 return nfs_ok;
1848 /* ip-address based client; check sec= export option: */
1849 for (f = exp->ex_flavors; f < end; f++) {
1850 if (f->pseudoflavor == rqstp->rq_cred.cr_flavor)
1851 return nfs_ok;
1852 }
1853 /* defaults in absence of sec= options: */
1854 if (exp->ex_nflavors == 0) {
1855 if (rqstp->rq_cred.cr_flavor == RPC_AUTH_NULL ||
1856 rqstp->rq_cred.cr_flavor == RPC_AUTH_UNIX)
1857 return nfs_ok;
1858 }
1859
1860 /* If the compound op contains a spo_must_allowed op,
1861 * it will be sent with integrity/protection which
1862 * will have to be expressly allowed on mounts that
1863 * don't support it
1864 */
1865
1866 if (nfsd4_spo_must_allow(rqstp))
1867 return nfs_ok;
1868
1869 /* Some calls may be processed without authentication
1870 * on GSS exports. For example NFS2/3 calls on root
1871 * directory, see section 2.3.2 of rfc 2623.
1872 * For "may_bypass_gss" check that export has really
1873 * enabled some flavor with authentication (GSS or any
1874 * other) and also check that the used auth flavor is
1875 * without authentication (none or sys).
1876 */
1877 if (may_bypass_gss && (
1878 rqstp->rq_cred.cr_flavor == RPC_AUTH_NULL ||
1879 rqstp->rq_cred.cr_flavor == RPC_AUTH_UNIX)) {
1880 for (f = exp->ex_flavors; f < end; f++) {
1881 if (f->pseudoflavor >= RPC_AUTH_DES)
1882 return 0;
1883 }
1884 }
1885
1886 return nfserr_wrongsec;
1887 }
1888
1889 /**
1890 * check_nfsd_access - check if access to export is allowed.
1891 * @exp: svc_export that is being accessed.
1892 * @rqstp: svc_rqst attempting to access @exp.
1893 * @may_bypass_gss: reduce strictness of authorization check
1894 *
1895 * Return values:
1896 * %nfs_ok if access is granted, or
1897 * %nfserr_wrongsec if access is denied
1898 */
check_nfsd_access(struct svc_export * exp,struct svc_rqst * rqstp,bool may_bypass_gss)1899 __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp,
1900 bool may_bypass_gss)
1901 {
1902 __be32 status;
1903
1904 status = check_xprtsec_policy(exp, rqstp);
1905 if (status != nfs_ok)
1906 return status;
1907 return check_security_flavor(exp, rqstp, may_bypass_gss);
1908 }
1909
1910 /*
1911 * Uses rq_client and rq_gssclient to find an export; uses rq_client (an
1912 * auth_unix client) if it's available and has secinfo information;
1913 * otherwise, will try to use rq_gssclient.
1914 *
1915 * Called from functions that handle requests; functions that do work on
1916 * behalf of mountd are passed a single client name to use, and should
1917 * use exp_get_by_name() or exp_find().
1918 */
1919 struct svc_export *
rqst_exp_get_by_name(struct svc_rqst * rqstp,const struct path * path)1920 rqst_exp_get_by_name(struct svc_rqst *rqstp, const struct path *path)
1921 {
1922 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
1923 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
1924 struct cache_detail *cd = nn->svc_export_cache;
1925
1926 if (rqstp->rq_client == NULL)
1927 goto gss;
1928
1929 /* First try the auth_unix client: */
1930 exp = exp_get_by_name(cd, rqstp->rq_client, path, &rqstp->rq_chandle);
1931 if (PTR_ERR(exp) == -ENOENT)
1932 goto gss;
1933 if (IS_ERR(exp))
1934 return exp;
1935 /* If it has secinfo, assume there are no gss/... clients */
1936 if (exp->ex_nflavors > 0)
1937 return exp;
1938 gss:
1939 /* Otherwise, try falling back on gss client */
1940 if (rqstp->rq_gssclient == NULL)
1941 return exp;
1942 gssexp = exp_get_by_name(cd, rqstp->rq_gssclient, path, &rqstp->rq_chandle);
1943 if (PTR_ERR(gssexp) == -ENOENT)
1944 return exp;
1945 if (!IS_ERR(exp))
1946 exp_put(exp);
1947 return gssexp;
1948 }
1949
1950 /**
1951 * rqst_exp_find - Find an svc_export in the context of a rqst or similar
1952 * @reqp: The handle to be used to suspend the request if a cache-upcall is needed
1953 * If NULL, missing in-cache information will result in failure.
1954 * @net: The network namespace in which the request exists
1955 * @cl: default auth_domain to use for looking up the export
1956 * @gsscl: an alternate auth_domain defined using deprecated gss/krb5 format.
1957 * @fsid_type: The type of fsid to look for
1958 * @fsidv: The actual fsid to look up in the context of either client.
1959 *
1960 * Perform a lookup for @cl/@fsidv in the given @net for an export. If
1961 * none found and @gsscl specified, repeat the lookup.
1962 *
1963 * Returns an export, or an error pointer.
1964 */
1965 struct svc_export *
rqst_exp_find(struct cache_req * reqp,struct net * net,struct auth_domain * cl,struct auth_domain * gsscl,int fsid_type,u32 * fsidv)1966 rqst_exp_find(struct cache_req *reqp, struct net *net,
1967 struct auth_domain *cl, struct auth_domain *gsscl,
1968 int fsid_type, u32 *fsidv)
1969 {
1970 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1971 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
1972 struct cache_detail *cd = nn->svc_export_cache;
1973
1974 if (!cl)
1975 goto gss;
1976
1977 /* First try the auth_unix client: */
1978 exp = exp_find(cd, cl, fsid_type, fsidv, reqp);
1979 if (PTR_ERR(exp) == -ENOENT)
1980 goto gss;
1981 if (IS_ERR(exp))
1982 return exp;
1983 /* If it has secinfo, assume there are no gss/... clients */
1984 if (exp->ex_nflavors > 0)
1985 return exp;
1986 gss:
1987 /* Otherwise, try falling back on gss client */
1988 if (!gsscl)
1989 return exp;
1990 gssexp = exp_find(cd, gsscl, fsid_type, fsidv, reqp);
1991 if (PTR_ERR(gssexp) == -ENOENT)
1992 return exp;
1993 if (!IS_ERR(exp))
1994 exp_put(exp);
1995 return gssexp;
1996 }
1997
1998 struct svc_export *
rqst_exp_parent(struct svc_rqst * rqstp,struct path * path)1999 rqst_exp_parent(struct svc_rqst *rqstp, struct path *path)
2000 {
2001 struct dentry *saved = dget(path->dentry);
2002 struct svc_export *exp = rqst_exp_get_by_name(rqstp, path);
2003
2004 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
2005 struct dentry *parent = dget_parent(path->dentry);
2006 dput(path->dentry);
2007 path->dentry = parent;
2008 exp = rqst_exp_get_by_name(rqstp, path);
2009 }
2010 dput(path->dentry);
2011 path->dentry = saved;
2012 return exp;
2013 }
2014
rqst_find_fsidzero_export(struct svc_rqst * rqstp)2015 struct svc_export *rqst_find_fsidzero_export(struct svc_rqst *rqstp)
2016 {
2017 u32 fsidv[2];
2018
2019 mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL);
2020
2021 return rqst_exp_find(&rqstp->rq_chandle, SVC_NET(rqstp),
2022 rqstp->rq_client, rqstp->rq_gssclient,
2023 FSID_NUM, fsidv);
2024 }
2025
2026 /*
2027 * Called when we need the filehandle for the root of the pseudofs,
2028 * for a given NFSv4 client. The root is defined to be the
2029 * export point with fsid==0
2030 */
2031 __be32
exp_pseudoroot(struct svc_rqst * rqstp,struct svc_fh * fhp)2032 exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp)
2033 {
2034 struct svc_export *exp;
2035 __be32 rv;
2036
2037 exp = rqst_find_fsidzero_export(rqstp);
2038 if (IS_ERR(exp))
2039 return nfserrno(PTR_ERR(exp));
2040 rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL);
2041 exp_put(exp);
2042 return rv;
2043 }
2044
2045 static struct flags {
2046 int flag;
2047 char *name[2];
2048 } expflags[] = {
2049 { NFSEXP_READONLY, {"ro", "rw"}},
2050 { NFSEXP_INSECURE_PORT, {"insecure", ""}},
2051 { NFSEXP_ROOTSQUASH, {"root_squash", "no_root_squash"}},
2052 { NFSEXP_ALLSQUASH, {"all_squash", ""}},
2053 { NFSEXP_ASYNC, {"async", "sync"}},
2054 { NFSEXP_GATHERED_WRITES, {"wdelay", "no_wdelay"}},
2055 { NFSEXP_NOREADDIRPLUS, {"nordirplus", ""}},
2056 { NFSEXP_SECURITY_LABEL, {"security_label", ""}},
2057 { NFSEXP_SIGN_FH, {"sign_fh", ""}},
2058 { NFSEXP_NOHIDE, {"nohide", ""}},
2059 { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},
2060 { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},
2061 { NFSEXP_CROSSMOUNT, {"crossmnt", ""}},
2062 { NFSEXP_V4ROOT, {"v4root", ""}},
2063 { NFSEXP_PNFS, {"pnfs", ""}},
2064 { 0, {"", ""}}
2065 };
2066
show_expflags(struct seq_file * m,int flags,int mask)2067 static void show_expflags(struct seq_file *m, int flags, int mask)
2068 {
2069 struct flags *flg;
2070 int state, first = 0;
2071
2072 for (flg = expflags; flg->flag; flg++) {
2073 if (flg->flag & ~mask)
2074 continue;
2075 state = (flg->flag & flags) ? 0 : 1;
2076 if (*flg->name[state])
2077 seq_printf(m, "%s%s", first++?",":"", flg->name[state]);
2078 }
2079 }
2080
show_secinfo_flags(struct seq_file * m,int flags)2081 static void show_secinfo_flags(struct seq_file *m, int flags)
2082 {
2083 seq_printf(m, ",");
2084 show_expflags(m, flags, NFSEXP_SECINFO_FLAGS);
2085 }
2086
secinfo_flags_equal(int f,int g)2087 static bool secinfo_flags_equal(int f, int g)
2088 {
2089 f &= NFSEXP_SECINFO_FLAGS;
2090 g &= NFSEXP_SECINFO_FLAGS;
2091 return f == g;
2092 }
2093
show_secinfo_run(struct seq_file * m,struct exp_flavor_info ** fp,struct exp_flavor_info * end)2094 static int show_secinfo_run(struct seq_file *m, struct exp_flavor_info **fp, struct exp_flavor_info *end)
2095 {
2096 int flags;
2097
2098 flags = (*fp)->flags;
2099 seq_printf(m, ",sec=%d", (*fp)->pseudoflavor);
2100 (*fp)++;
2101 while (*fp != end && secinfo_flags_equal(flags, (*fp)->flags)) {
2102 seq_printf(m, ":%d", (*fp)->pseudoflavor);
2103 (*fp)++;
2104 }
2105 return flags;
2106 }
2107
show_secinfo(struct seq_file * m,struct svc_export * exp)2108 static void show_secinfo(struct seq_file *m, struct svc_export *exp)
2109 {
2110 struct exp_flavor_info *f;
2111 struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors;
2112 int flags;
2113
2114 if (exp->ex_nflavors == 0)
2115 return;
2116 f = exp->ex_flavors;
2117 flags = show_secinfo_run(m, &f, end);
2118 if (!secinfo_flags_equal(flags, exp->ex_flags))
2119 show_secinfo_flags(m, flags);
2120 while (f != end) {
2121 flags = show_secinfo_run(m, &f, end);
2122 show_secinfo_flags(m, flags);
2123 }
2124 }
2125
exp_flags(struct seq_file * m,int flag,int fsid,kuid_t anonu,kgid_t anong,struct nfsd4_fs_locations * fsloc)2126 static void exp_flags(struct seq_file *m, int flag, int fsid,
2127 kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fsloc)
2128 {
2129 struct user_namespace *userns = m->file->f_cred->user_ns;
2130
2131 show_expflags(m, flag, NFSEXP_ALLFLAGS);
2132 if (flag & NFSEXP_FSID)
2133 seq_printf(m, ",fsid=%d", fsid);
2134 if (!uid_eq(anonu, make_kuid(userns, (uid_t)-2)) &&
2135 !uid_eq(anonu, make_kuid(userns, 0x10000-2)))
2136 seq_printf(m, ",anonuid=%u", from_kuid_munged(userns, anonu));
2137 if (!gid_eq(anong, make_kgid(userns, (gid_t)-2)) &&
2138 !gid_eq(anong, make_kgid(userns, 0x10000-2)))
2139 seq_printf(m, ",anongid=%u", from_kgid_munged(userns, anong));
2140 if (fsloc && fsloc->locations_count > 0) {
2141 char *loctype = (fsloc->migrated) ? "refer" : "replicas";
2142 int i;
2143
2144 seq_printf(m, ",%s=", loctype);
2145 seq_escape(m, fsloc->locations[0].path, ",;@ \t\n\\");
2146 seq_putc(m, '@');
2147 seq_escape(m, fsloc->locations[0].hosts, ",;@ \t\n\\");
2148 for (i = 1; i < fsloc->locations_count; i++) {
2149 seq_putc(m, ';');
2150 seq_escape(m, fsloc->locations[i].path, ",;@ \t\n\\");
2151 seq_putc(m, '@');
2152 seq_escape(m, fsloc->locations[i].hosts, ",;@ \t\n\\");
2153 }
2154 }
2155 }
2156
e_show(struct seq_file * m,void * p)2157 static int e_show(struct seq_file *m, void *p)
2158 {
2159 struct cache_head *cp = p;
2160 struct svc_export *exp = container_of(cp, struct svc_export, h);
2161 struct cache_detail *cd = m->private;
2162 bool export_stats = is_export_stats_file(m);
2163
2164 if (p == SEQ_START_TOKEN) {
2165 seq_puts(m, "# Version 1.1\n");
2166 if (export_stats)
2167 seq_puts(m, "# Path Client Start-time\n#\tStats\n");
2168 else
2169 seq_puts(m, "# Path Client(Flags) # IPs\n");
2170 return 0;
2171 }
2172
2173 if (cache_check_rcu(cd, &exp->h, NULL))
2174 return 0;
2175
2176 return svc_export_show(m, cd, cp);
2177 }
2178
2179 const struct seq_operations nfs_exports_op = {
2180 .start = cache_seq_start_rcu,
2181 .next = cache_seq_next_rcu,
2182 .stop = cache_seq_stop_rcu,
2183 .show = e_show,
2184 };
2185
2186 /*
2187 * Initialize the exports module.
2188 */
2189 int
nfsd_export_init(struct net * net)2190 nfsd_export_init(struct net *net)
2191 {
2192 int rv;
2193 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
2194
2195 dprintk("nfsd: initializing export module (net: %x).\n", net->ns.inum);
2196
2197 nn->svc_export_cache = cache_create_net(&svc_export_cache_template, net);
2198 if (IS_ERR(nn->svc_export_cache))
2199 return PTR_ERR(nn->svc_export_cache);
2200 rv = cache_register_net(nn->svc_export_cache, net);
2201 if (rv)
2202 goto destroy_export_cache;
2203
2204 nn->svc_expkey_cache = cache_create_net(&svc_expkey_cache_template, net);
2205 if (IS_ERR(nn->svc_expkey_cache)) {
2206 rv = PTR_ERR(nn->svc_expkey_cache);
2207 goto unregister_export_cache;
2208 }
2209 rv = cache_register_net(nn->svc_expkey_cache, net);
2210 if (rv)
2211 goto destroy_expkey_cache;
2212 return 0;
2213
2214 destroy_expkey_cache:
2215 cache_destroy_net(nn->svc_expkey_cache, net);
2216 unregister_export_cache:
2217 cache_unregister_net(nn->svc_export_cache, net);
2218 destroy_export_cache:
2219 cache_destroy_net(nn->svc_export_cache, net);
2220 return rv;
2221 }
2222
2223 /*
2224 * Flush exports table - called when last nfsd thread is killed
2225 */
2226 void
nfsd_export_flush(struct net * net)2227 nfsd_export_flush(struct net *net)
2228 {
2229 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
2230
2231 cache_purge(nn->svc_expkey_cache);
2232 cache_purge(nn->svc_export_cache);
2233 }
2234
2235 /*
2236 * Shutdown the exports module.
2237 */
2238 void
nfsd_export_shutdown(struct net * net)2239 nfsd_export_shutdown(struct net *net)
2240 {
2241 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
2242
2243 dprintk("nfsd: shutting down export module (net: %x).\n", net->ns.inum);
2244
2245 cache_unregister_net(nn->svc_expkey_cache, net);
2246 cache_unregister_net(nn->svc_export_cache, net);
2247 cache_destroy_net(nn->svc_expkey_cache, net);
2248 cache_destroy_net(nn->svc_export_cache, net);
2249 svcauth_unix_purge(net);
2250
2251 dprintk("nfsd: export shutdown complete (net: %x).\n", net->ns.inum);
2252 }
2253