.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * In-kernel rpcbind client supporting versions 2, 3, and 4 of the rpcbind |
---|
3 | 4 | * protocol |
---|
.. | .. |
---|
30 | 31 | #include <linux/sunrpc/sched.h> |
---|
31 | 32 | #include <linux/sunrpc/xprtsock.h> |
---|
32 | 33 | |
---|
33 | | -#include "netns.h" |
---|
| 34 | +#include <trace/events/sunrpc.h> |
---|
34 | 35 | |
---|
35 | | -#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
---|
36 | | -# define RPCDBG_FACILITY RPCDBG_BIND |
---|
37 | | -#endif |
---|
| 36 | +#include "netns.h" |
---|
38 | 37 | |
---|
39 | 38 | #define RPCBIND_SOCK_PATHNAME "/var/run/rpcbind.sock" |
---|
40 | 39 | |
---|
.. | .. |
---|
215 | 214 | sn->rpcb_is_af_local = is_af_local ? 1 : 0; |
---|
216 | 215 | smp_wmb(); |
---|
217 | 216 | sn->rpcb_users = 1; |
---|
218 | | - dprintk("RPC: created new rpcb local clients (rpcb_local_clnt: " |
---|
219 | | - "%p, rpcb_local_clnt4: %p) for net %x%s\n", |
---|
220 | | - sn->rpcb_local_clnt, sn->rpcb_local_clnt4, |
---|
221 | | - net->ns.inum, (net == &init_net) ? " (init_net)" : ""); |
---|
222 | 217 | } |
---|
223 | 218 | |
---|
224 | 219 | /* |
---|
.. | .. |
---|
240 | 235 | .program = &rpcb_program, |
---|
241 | 236 | .version = RPCBVERS_2, |
---|
242 | 237 | .authflavor = RPC_AUTH_NULL, |
---|
| 238 | + .cred = current_cred(), |
---|
243 | 239 | /* |
---|
244 | 240 | * We turn off the idle timeout to prevent the kernel |
---|
245 | 241 | * from automatically disconnecting the socket. |
---|
.. | .. |
---|
259 | 255 | */ |
---|
260 | 256 | clnt = rpc_create(&args); |
---|
261 | 257 | if (IS_ERR(clnt)) { |
---|
262 | | - dprintk("RPC: failed to create AF_LOCAL rpcbind " |
---|
263 | | - "client (errno %ld).\n", PTR_ERR(clnt)); |
---|
264 | 258 | result = PTR_ERR(clnt); |
---|
265 | 259 | goto out; |
---|
266 | 260 | } |
---|
267 | 261 | |
---|
268 | 262 | clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4); |
---|
269 | | - if (IS_ERR(clnt4)) { |
---|
270 | | - dprintk("RPC: failed to bind second program to " |
---|
271 | | - "rpcbind v4 client (errno %ld).\n", |
---|
272 | | - PTR_ERR(clnt4)); |
---|
| 263 | + if (IS_ERR(clnt4)) |
---|
273 | 264 | clnt4 = NULL; |
---|
274 | | - } |
---|
275 | 265 | |
---|
276 | 266 | rpcb_set_local(net, clnt, clnt4, true); |
---|
277 | 267 | |
---|
.. | .. |
---|
299 | 289 | .program = &rpcb_program, |
---|
300 | 290 | .version = RPCBVERS_2, |
---|
301 | 291 | .authflavor = RPC_AUTH_UNIX, |
---|
| 292 | + .cred = current_cred(), |
---|
302 | 293 | .flags = RPC_CLNT_CREATE_NOPING, |
---|
303 | 294 | }; |
---|
304 | 295 | struct rpc_clnt *clnt, *clnt4; |
---|
.. | .. |
---|
306 | 297 | |
---|
307 | 298 | clnt = rpc_create(&args); |
---|
308 | 299 | if (IS_ERR(clnt)) { |
---|
309 | | - dprintk("RPC: failed to create local rpcbind " |
---|
310 | | - "client (errno %ld).\n", PTR_ERR(clnt)); |
---|
311 | 300 | result = PTR_ERR(clnt); |
---|
312 | 301 | goto out; |
---|
313 | 302 | } |
---|
.. | .. |
---|
318 | 307 | * v4 upcalls. |
---|
319 | 308 | */ |
---|
320 | 309 | clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4); |
---|
321 | | - if (IS_ERR(clnt4)) { |
---|
322 | | - dprintk("RPC: failed to bind second program to " |
---|
323 | | - "rpcbind v4 client (errno %ld).\n", |
---|
324 | | - PTR_ERR(clnt4)); |
---|
| 310 | + if (IS_ERR(clnt4)) |
---|
325 | 311 | clnt4 = NULL; |
---|
326 | | - } |
---|
327 | 312 | |
---|
328 | 313 | rpcb_set_local(net, clnt, clnt4, false); |
---|
329 | 314 | |
---|
.. | .. |
---|
358 | 343 | static struct rpc_clnt *rpcb_create(struct net *net, const char *nodename, |
---|
359 | 344 | const char *hostname, |
---|
360 | 345 | struct sockaddr *srvaddr, size_t salen, |
---|
361 | | - int proto, u32 version) |
---|
| 346 | + int proto, u32 version, |
---|
| 347 | + const struct cred *cred) |
---|
362 | 348 | { |
---|
363 | 349 | struct rpc_create_args args = { |
---|
364 | 350 | .net = net, |
---|
.. | .. |
---|
370 | 356 | .program = &rpcb_program, |
---|
371 | 357 | .version = version, |
---|
372 | 358 | .authflavor = RPC_AUTH_UNIX, |
---|
| 359 | + .cred = cred, |
---|
373 | 360 | .flags = (RPC_CLNT_CREATE_NOPING | |
---|
374 | 361 | RPC_CLNT_CREATE_NONPRIVPORT), |
---|
375 | 362 | }; |
---|
.. | .. |
---|
398 | 385 | msg->rpc_resp = &result; |
---|
399 | 386 | |
---|
400 | 387 | error = rpc_call_sync(clnt, msg, flags); |
---|
401 | | - if (error < 0) { |
---|
402 | | - dprintk("RPC: failed to contact local rpcbind " |
---|
403 | | - "server (errno %d).\n", -error); |
---|
| 388 | + if (error < 0) |
---|
404 | 389 | return error; |
---|
405 | | - } |
---|
406 | 390 | |
---|
407 | 391 | if (!result) |
---|
408 | 392 | return -EACCES; |
---|
.. | .. |
---|
456 | 440 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); |
---|
457 | 441 | bool is_set = false; |
---|
458 | 442 | |
---|
459 | | - dprintk("RPC: %sregistering (%u, %u, %d, %u) with local " |
---|
460 | | - "rpcbind\n", (port ? "" : "un"), |
---|
461 | | - prog, vers, prot, port); |
---|
| 443 | + trace_pmap_register(prog, vers, prot, port); |
---|
462 | 444 | |
---|
463 | 445 | msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET]; |
---|
464 | 446 | if (port != 0) { |
---|
.. | .. |
---|
483 | 465 | int result; |
---|
484 | 466 | |
---|
485 | 467 | map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL); |
---|
486 | | - |
---|
487 | | - dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " |
---|
488 | | - "local rpcbind\n", (port ? "" : "un"), |
---|
489 | | - map->r_prog, map->r_vers, |
---|
490 | | - map->r_addr, map->r_netid); |
---|
491 | 468 | |
---|
492 | 469 | msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET]; |
---|
493 | 470 | if (port != 0) { |
---|
.. | .. |
---|
515 | 492 | |
---|
516 | 493 | map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL); |
---|
517 | 494 | |
---|
518 | | - dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " |
---|
519 | | - "local rpcbind\n", (port ? "" : "un"), |
---|
520 | | - map->r_prog, map->r_vers, |
---|
521 | | - map->r_addr, map->r_netid); |
---|
522 | | - |
---|
523 | 495 | msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET]; |
---|
524 | 496 | if (port != 0) { |
---|
525 | 497 | msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; |
---|
.. | .. |
---|
536 | 508 | { |
---|
537 | 509 | struct rpcbind_args *map = msg->rpc_argp; |
---|
538 | 510 | |
---|
539 | | - dprintk("RPC: unregistering [%u, %u, '%s'] with " |
---|
540 | | - "local rpcbind\n", |
---|
541 | | - map->r_prog, map->r_vers, map->r_netid); |
---|
| 511 | + trace_rpcb_unregister(map->r_prog, map->r_vers, map->r_netid); |
---|
542 | 512 | |
---|
543 | 513 | map->r_addr = ""; |
---|
544 | 514 | msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET]; |
---|
.. | .. |
---|
609 | 579 | |
---|
610 | 580 | if (address == NULL) |
---|
611 | 581 | return rpcb_unregister_all_protofamilies(sn, &msg); |
---|
| 582 | + |
---|
| 583 | + trace_rpcb_register(map.r_prog, map.r_vers, map.r_addr, map.r_netid); |
---|
612 | 584 | |
---|
613 | 585 | switch (address->sa_family) { |
---|
614 | 586 | case AF_INET: |
---|
.. | .. |
---|
688 | 660 | rcu_read_unlock(); |
---|
689 | 661 | xprt = xprt_get(task->tk_xprt); |
---|
690 | 662 | |
---|
691 | | - dprintk("RPC: %5u %s(%s, %u, %u, %d)\n", |
---|
692 | | - task->tk_pid, __func__, |
---|
693 | | - xprt->servername, clnt->cl_prog, clnt->cl_vers, xprt->prot); |
---|
694 | | - |
---|
695 | 663 | /* Put self on the wait queue to ensure we get notified if |
---|
696 | 664 | * some other task is already attempting to bind the port */ |
---|
697 | | - rpc_sleep_on(&xprt->binding, task, NULL); |
---|
| 665 | + rpc_sleep_on_timeout(&xprt->binding, task, |
---|
| 666 | + NULL, jiffies + xprt->bind_timeout); |
---|
698 | 667 | |
---|
699 | 668 | if (xprt_test_and_set_binding(xprt)) { |
---|
700 | | - dprintk("RPC: %5u %s: waiting for another binder\n", |
---|
701 | | - task->tk_pid, __func__); |
---|
702 | 669 | xprt_put(xprt); |
---|
703 | 670 | return; |
---|
704 | 671 | } |
---|
.. | .. |
---|
706 | 673 | /* Someone else may have bound if we slept */ |
---|
707 | 674 | if (xprt_bound(xprt)) { |
---|
708 | 675 | status = 0; |
---|
709 | | - dprintk("RPC: %5u %s: already bound\n", |
---|
710 | | - task->tk_pid, __func__); |
---|
711 | 676 | goto bailout_nofree; |
---|
712 | 677 | } |
---|
713 | 678 | |
---|
.. | .. |
---|
726 | 691 | break; |
---|
727 | 692 | default: |
---|
728 | 693 | status = -EAFNOSUPPORT; |
---|
729 | | - dprintk("RPC: %5u %s: bad address family\n", |
---|
730 | | - task->tk_pid, __func__); |
---|
731 | 694 | goto bailout_nofree; |
---|
732 | 695 | } |
---|
733 | 696 | if (proc == NULL) { |
---|
734 | 697 | xprt->bind_index = 0; |
---|
735 | 698 | status = -EPFNOSUPPORT; |
---|
736 | | - dprintk("RPC: %5u %s: no more getport versions available\n", |
---|
737 | | - task->tk_pid, __func__); |
---|
738 | 699 | goto bailout_nofree; |
---|
739 | 700 | } |
---|
740 | 701 | |
---|
741 | | - dprintk("RPC: %5u %s: trying rpcbind version %u\n", |
---|
742 | | - task->tk_pid, __func__, bind_version); |
---|
| 702 | + trace_rpcb_getport(clnt, task, bind_version); |
---|
743 | 703 | |
---|
744 | 704 | rpcb_clnt = rpcb_create(xprt->xprt_net, |
---|
745 | 705 | clnt->cl_nodename, |
---|
746 | 706 | xprt->servername, sap, salen, |
---|
747 | | - xprt->prot, bind_version); |
---|
| 707 | + xprt->prot, bind_version, |
---|
| 708 | + clnt->cl_cred); |
---|
748 | 709 | if (IS_ERR(rpcb_clnt)) { |
---|
749 | 710 | status = PTR_ERR(rpcb_clnt); |
---|
750 | | - dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n", |
---|
751 | | - task->tk_pid, __func__, PTR_ERR(rpcb_clnt)); |
---|
752 | 711 | goto bailout_nofree; |
---|
753 | 712 | } |
---|
754 | 713 | |
---|
755 | | - map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC); |
---|
| 714 | + map = kzalloc(sizeof(struct rpcbind_args), GFP_NOFS); |
---|
756 | 715 | if (!map) { |
---|
757 | 716 | status = -ENOMEM; |
---|
758 | | - dprintk("RPC: %5u %s: no memory available\n", |
---|
759 | | - task->tk_pid, __func__); |
---|
760 | 717 | goto bailout_release_client; |
---|
761 | 718 | } |
---|
762 | 719 | map->r_prog = clnt->cl_prog; |
---|
.. | .. |
---|
770 | 727 | case RPCBVERS_4: |
---|
771 | 728 | case RPCBVERS_3: |
---|
772 | 729 | map->r_netid = xprt->address_strings[RPC_DISPLAY_NETID]; |
---|
773 | | - map->r_addr = rpc_sockaddr2uaddr(sap, GFP_ATOMIC); |
---|
| 730 | + map->r_addr = rpc_sockaddr2uaddr(sap, GFP_NOFS); |
---|
774 | 731 | if (!map->r_addr) { |
---|
775 | 732 | status = -ENOMEM; |
---|
776 | | - dprintk("RPC: %5u %s: no memory available\n", |
---|
777 | | - task->tk_pid, __func__); |
---|
778 | 733 | goto bailout_free_args; |
---|
779 | 734 | } |
---|
780 | 735 | map->r_owner = ""; |
---|
.. | .. |
---|
788 | 743 | |
---|
789 | 744 | child = rpcb_call_async(rpcb_clnt, map, proc); |
---|
790 | 745 | rpc_release_client(rpcb_clnt); |
---|
791 | | - if (IS_ERR(child)) { |
---|
792 | | - /* rpcb_map_release() has freed the arguments */ |
---|
793 | | - dprintk("RPC: %5u %s: rpc_run_task failed\n", |
---|
794 | | - task->tk_pid, __func__); |
---|
795 | | - return; |
---|
796 | | - } |
---|
797 | 746 | |
---|
798 | 747 | xprt->stat.bind_count++; |
---|
799 | 748 | rpc_put_task(child); |
---|
.. | .. |
---|
817 | 766 | { |
---|
818 | 767 | struct rpcbind_args *map = data; |
---|
819 | 768 | struct rpc_xprt *xprt = map->r_xprt; |
---|
820 | | - int status = child->tk_status; |
---|
| 769 | + |
---|
| 770 | + map->r_status = child->tk_status; |
---|
821 | 771 | |
---|
822 | 772 | /* Garbage reply: retry with a lesser rpcbind version */ |
---|
823 | | - if (status == -EIO) |
---|
824 | | - status = -EPROTONOSUPPORT; |
---|
| 773 | + if (map->r_status == -EIO) |
---|
| 774 | + map->r_status = -EPROTONOSUPPORT; |
---|
825 | 775 | |
---|
826 | 776 | /* rpcbind server doesn't support this rpcbind protocol version */ |
---|
827 | | - if (status == -EPROTONOSUPPORT) |
---|
| 777 | + if (map->r_status == -EPROTONOSUPPORT) |
---|
828 | 778 | xprt->bind_index++; |
---|
829 | 779 | |
---|
830 | | - if (status < 0) { |
---|
| 780 | + if (map->r_status < 0) { |
---|
831 | 781 | /* rpcbind server not available on remote host? */ |
---|
832 | | - xprt->ops->set_port(xprt, 0); |
---|
| 782 | + map->r_port = 0; |
---|
| 783 | + |
---|
833 | 784 | } else if (map->r_port == 0) { |
---|
834 | 785 | /* Requested RPC service wasn't registered on remote host */ |
---|
835 | | - xprt->ops->set_port(xprt, 0); |
---|
836 | | - status = -EACCES; |
---|
| 786 | + map->r_status = -EACCES; |
---|
837 | 787 | } else { |
---|
838 | 788 | /* Succeeded */ |
---|
839 | | - xprt->ops->set_port(xprt, map->r_port); |
---|
840 | | - xprt_set_bound(xprt); |
---|
841 | | - status = 0; |
---|
| 789 | + map->r_status = 0; |
---|
842 | 790 | } |
---|
843 | 791 | |
---|
844 | | - dprintk("RPC: %5u rpcb_getport_done(status %d, port %u)\n", |
---|
845 | | - child->tk_pid, status, map->r_port); |
---|
846 | | - |
---|
847 | | - map->r_status = status; |
---|
| 792 | + trace_rpcb_setport(child, map->r_status, map->r_port); |
---|
| 793 | + xprt->ops->set_port(xprt, map->r_port); |
---|
| 794 | + if (map->r_port) |
---|
| 795 | + xprt_set_bound(xprt); |
---|
848 | 796 | } |
---|
849 | 797 | |
---|
850 | 798 | /* |
---|
.. | .. |
---|
856 | 804 | { |
---|
857 | 805 | const struct rpcbind_args *rpcb = data; |
---|
858 | 806 | __be32 *p; |
---|
859 | | - |
---|
860 | | - dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n", |
---|
861 | | - req->rq_task->tk_pid, |
---|
862 | | - req->rq_task->tk_msg.rpc_proc->p_name, |
---|
863 | | - rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port); |
---|
864 | 807 | |
---|
865 | 808 | p = xdr_reserve_space(xdr, RPCB_mappingargs_sz << 2); |
---|
866 | 809 | *p++ = cpu_to_be32(rpcb->r_prog); |
---|
.. | .. |
---|
883 | 826 | return -EIO; |
---|
884 | 827 | |
---|
885 | 828 | port = be32_to_cpup(p); |
---|
886 | | - dprintk("RPC: %5u PMAP_%s result: %lu\n", req->rq_task->tk_pid, |
---|
887 | | - req->rq_task->tk_msg.rpc_proc->p_name, port); |
---|
888 | 829 | if (unlikely(port > USHRT_MAX)) |
---|
889 | 830 | return -EIO; |
---|
890 | 831 | |
---|
.. | .. |
---|
905 | 846 | *boolp = 0; |
---|
906 | 847 | if (*p != xdr_zero) |
---|
907 | 848 | *boolp = 1; |
---|
908 | | - |
---|
909 | | - dprintk("RPC: %5u RPCB_%s call %s\n", |
---|
910 | | - req->rq_task->tk_pid, |
---|
911 | | - req->rq_task->tk_msg.rpc_proc->p_name, |
---|
912 | | - (*boolp ? "succeeded" : "failed")); |
---|
913 | 849 | return 0; |
---|
914 | 850 | } |
---|
915 | 851 | |
---|
.. | .. |
---|
933 | 869 | { |
---|
934 | 870 | const struct rpcbind_args *rpcb = data; |
---|
935 | 871 | __be32 *p; |
---|
936 | | - |
---|
937 | | - dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n", |
---|
938 | | - req->rq_task->tk_pid, |
---|
939 | | - req->rq_task->tk_msg.rpc_proc->p_name, |
---|
940 | | - rpcb->r_prog, rpcb->r_vers, |
---|
941 | | - rpcb->r_netid, rpcb->r_addr); |
---|
942 | 872 | |
---|
943 | 873 | p = xdr_reserve_space(xdr, (RPCB_program_sz + RPCB_version_sz) << 2); |
---|
944 | 874 | *p++ = cpu_to_be32(rpcb->r_prog); |
---|
.. | .. |
---|
969 | 899 | * If the returned universal address is a null string, |
---|
970 | 900 | * the requested RPC service was not registered. |
---|
971 | 901 | */ |
---|
972 | | - if (len == 0) { |
---|
973 | | - dprintk("RPC: %5u RPCB reply: program not registered\n", |
---|
974 | | - req->rq_task->tk_pid); |
---|
| 902 | + if (len == 0) |
---|
975 | 903 | return 0; |
---|
976 | | - } |
---|
977 | 904 | |
---|
978 | 905 | if (unlikely(len > RPCBIND_MAXUADDRLEN)) |
---|
979 | 906 | goto out_fail; |
---|
.. | .. |
---|
981 | 908 | p = xdr_inline_decode(xdr, len); |
---|
982 | 909 | if (unlikely(p == NULL)) |
---|
983 | 910 | goto out_fail; |
---|
984 | | - dprintk("RPC: %5u RPCB_%s reply: %*pE\n", req->rq_task->tk_pid, |
---|
985 | | - req->rq_task->tk_msg.rpc_proc->p_name, len, (char *)p); |
---|
986 | 911 | |
---|
987 | 912 | if (rpc_uaddr2sockaddr(req->rq_xprt->xprt_net, (char *)p, len, |
---|
988 | 913 | sap, sizeof(address)) == 0) |
---|
.. | .. |
---|
992 | 917 | return 0; |
---|
993 | 918 | |
---|
994 | 919 | out_fail: |
---|
995 | | - dprintk("RPC: %5u malformed RPCB_%s reply\n", |
---|
996 | | - req->rq_task->tk_pid, |
---|
997 | | - req->rq_task->tk_msg.rpc_proc->p_name); |
---|
998 | 920 | return -EIO; |
---|
999 | 921 | } |
---|
1000 | 922 | |
---|