Hide Forgot
+++ This bug was initially created as a clone of Bug #481422 +++ Description of problem: By default in Fedora 10, rpcbind runs with no options. In this mode, it denies set/unset requests unless the is_loopback function returns true. But is_loopback does more than its name would suggest: it requires that the call arrive from a loopback IP address and from a reserved port. This means that programs not running as root are unable to register services with rpcbind. But if we add the -i option to rpcbind, then it allows set/unset calls from remote hosts in addition to non-root local users. Version-Release number of selected component (if applicable): 0.1.7-1.fc10 How reproducible: Allow rpcbind to start normally without options, and then try to run a program as a non-root user that calls pmap_set. The call will fail. Steps to Reproduce: 1. Run rpcbind without any options. 2. As a non-root user, run a program that calls pmap_set 3. Actual results: pmap_set returns 0 for failure and fails to register the service. Expected results: pmap_set should succeed in registering the service. Additional info: The man page claims that the -i option is just to allow access from remote hosts, and that recompiling code should solve the problem. But in fact, recompiling the code does not solve the problem for non-root users, since the current glibc pmap_set call will still fail. At the very least, the man page should be corrected to indicate what -i actually does and that recompilation will not solve the problem for non-root users. A better solution would be to break the -i option into two finer-grained options, one to allow SET/UNSET from remote hosts, and another to allow SET/UNSET from non-reserved ports accessible to non-root users. --- Additional comment from triage@lists.fedoraproject.org on 2009-11-18 05:51:07 EST --- This message is a reminder that Fedora 10 is nearing its end of life. Approximately 30 (thirty) days from now Fedora will stop maintaining and issuing updates for Fedora 10. It is Fedora's policy to close all bug reports from releases that are no longer maintained. At that time this bug will be closed as WONTFIX if it remains open with a Fedora 'version' of '10'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, simply change the 'version' to a later Fedora version prior to Fedora 10's end of life. Bug Reporter: Thank you for reporting this issue and we are sorry that we may not be able to fix it before Fedora 10 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora please change the 'version' of this bug to the applicable version. If you are unable to change the version, please add a comment here and someone will do it for you. Although we aim to fix as many bugs as possible during every release's lifetime, sometimes those efforts are overtaken by events. Often a more recent Fedora release includes newer upstream software that fixes bugs or makes them obsolete. The process we are following is described here: http://fedoraproject.org/wiki/BugZappers/HouseKeeping --- Additional comment from ajschorr@alumni.princeton.edu on 2009-11-18 11:08:34 EST --- The source code in src/security.c is the same in version 0.2.0 in Fedora 12 as it was in version 0.1.7 in Fedora 10. So the bug is still there. --- Additional comment from steved@redhat.com on 2010-12-06 09:21:06 EST --- (In reply to comment #0) > Description of problem: > By default in Fedora 10, rpcbind runs with no options. In this mode, > it denies set/unset requests unless the is_loopback function returns > true. But is_loopback does more than its name would suggest: it > requires that the call arrive from a loopback IP address and from > a reserved port. This means that programs not running as root are > unable to register services with rpcbind. But if we add the -i option > to rpcbind, then it allows set/unset calls from remote hosts in > addition to non-root local users. > > > Version-Release number of selected component (if applicable): > 0.1.7-1.fc10 > > How reproducible: > Allow rpcbind to start normally without options, and then try to > run a program as a non-root user that calls pmap_set. The call > will fail. > > Steps to Reproduce: > 1. Run rpcbind without any options. > 2. As a non-root user, run a program that calls pmap_set > 3. > > Actual results: > pmap_set returns 0 for failure and fails to register the service. > > Expected results: > pmap_set should succeed in registering the service. > > Additional info: > The man page claims that the -i option is just to allow access > from remote hosts, and that recompiling code should solve the > problem. But in fact, recompiling the code does not solve the > problem for non-root users, since the current glibc pmap_set > call will still fail. At the very least, the man page should > be corrected to indicate what -i actually does and that > recompilation will not solve the problem for non-root users. > A better solution would be to break the -i option into two > finer-grained options, one to allow SET/UNSET from remote hosts, > and another to allow SET/UNSET from non-reserved ports accessible > to non-root users. The '-i' flag has nothing to do with root and non-root users. All that flag does is allow request from another network interface other than the loopback interface. Basically what the man page says.... Now if the glibc clnt_call() does not allow non-root calls, that's not a rpcbind problem... Open a bz against glibc... but I would suggested try using the cln_call() in libtirpc. --- Additional comment from ajschorr@alumni.princeton.edu on 2010-12-06 12:47:44 EST --- I respectfully disagree. If you look in rpcbind.c:main, you will see that the -i flag results in setting insecure = 1. And if you then grep for where the insecure flag is reference, you will see this in security.c:check_access: if (!insecure && !is_loopback(caller)) { <deny the request> } And if you look in the is_loopback function in the same file, you will see this: return ((sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) && (ntohs(sin->sin_port) < IPPORT_RESERVED)); In other words, if -i is not specified, then requests are accepted only from the local host and from a reserved port. Since reserved ports are available only to root, this means that non-root programs are unable to register services with rpcbind, even when run on the local host. The man page says that the purpose of the "-i" flag is to allow calls from any host. It does not mention anything about reserved ports. Turning on -i to enable local programs to register services is a security hole -- there is no need to open this up to remote programs. Did you read my problem report carefully? It's been almost 2 years now... Regards, Andy --- Additional comment from steved@redhat.com on 2010-12-06 13:15:27 EST --- (In reply to comment #4) > I respectfully disagree. If you look in rpcbind.c:main, you will see > that the -i flag results in setting insecure = 1. And if you then grep > for where the insecure flag is reference, you will see this in > security.c:check_access: > > if (!insecure && !is_loopback(caller)) { > <deny the request> > } > > And if you look in the is_loopback function in the same file, you will see > this: > > return ((sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) && > (ntohs(sin->sin_port) < IPPORT_RESERVED)); > > In other words, if -i is not specified, then requests are accepted only > from the local host and from a reserved port. Since reserved ports are > available only to root, this means that non-root programs are unable > to register services with rpcbind, even when run on the local host. Yes.. I do now see you point... > > The man page says that the purpose of the "-i" flag is to allow calls > from any host. It does not mention anything about reserved ports. True... > > Turning on -i to enable local programs to register services is a security > hole -- there is no need to open this up to remote programs. I agree... But it sounds its there for backward compatibility... > > Did you read my problem report carefully? Obviously not close enough.. ;-) So in your description you're suggesting having two options. One to allow local non-root set/unsets and the other to allow remote machines do sets/unsets... As you have already pointed out the latter is a huge security hole... So I'm thinking it would make sense to deprecate the -i flag. Then possibly introduce a new -I flag allowing non-root sets/unsets... Looking at other implementations, these options do not exist, which could be an argument for doing neither... Just curious, why do you need non-root sets/unsets? Thank you for your patiences.... --- Additional comment from steved@redhat.com on 2010-12-06 13:26:12 EST --- The easiest thing to do is simply update the man page to more accurate: diff --git a/man/rpcbind.8 b/man/rpcbind.8 index c5b8fb7..3686969 100644 --- a/man/rpcbind.8 +++ b/man/rpcbind.8 @@ -116,7 +116,8 @@ Normally accepts these requests only from the loopback interface for security reasons. This change is necessary for programs that were compiled with earlier versions of the rpc library and do not make those requests using the -loopback interface. +loopback interface. Note, the requests must come from a local process +since connection has to bound on a privileged port. .It Fl l Turn on libwrap connection logging. .It Fl s --- Additional comment from ajschorr@alumni.princeton.edu on 2010-12-06 13:56:30 EST --- If the goal is merely to correct the man page, I'd say this language is more accurate: In the absence of the -i option, calls are accepted only from privileged ports via the loopback interface. But as you agreed, -i is a big security hole for normal usage cases where simply allowing access to local, but non-superuser, processes is needed. I have many such programs on my system. We used the SunOS portmapper heavily back in the 90s to advertise local services. I suppose nobody else uses rpcbind any more, otherwise somebody else would have complained. If I were to supply a patch for the code to add a new -I flag, would it be considered? Or is it a waste of time? Regards, Andy --- Additional comment from steved@redhat.com on 2010-12-06 14:32:04 EST --- (In reply to comment #7) > If the goal is merely to correct the man page, I'd say this language is > more accurate: > > In the absence of the -i option, calls are accepted only from privileged > ports via the loopback interface. Sounds fine... > > But as you agreed, -i is a big security hole for normal usage cases where > simply > allowing access to local, but non-superuser, processes is needed. > > I have many such programs on my system. We used the SunOS portmapper heavily > back in the 90s to advertise local services. I suppose nobody else uses > rpcbind any more, otherwise somebody else would have complained. > > If I were to supply a patch for the code to add a new -I flag, would it be > considered? Or is it a waste of time? No guarantees... but there I know there has been some talk about this in the past... I think it would be a good discussion to have... If you are so incline.. Post the patches to linux-nfs@vger.kernel.org and lets start the discussion.... --- Additional comment from ajschorr@alumni.princeton.edu on 2010-12-09 15:43:29 EST --- Created attachment 467840 [details] Add new -c, -r, and -u options to allow fine-tuning of security holes. This patch adds -c, -r, and -u options to break down the functionality currently provided by the -i option. This allows the user to choose how much "insecurity" to introduce. --- Additional comment from ajschorr@alumni.princeton.edu on 2010-12-09 15:44:36 EST --- Created attachment 467841 [details] Patch the spec file to apply the new security patch To be used in conjunction with the security patch to build the new rpm.
Note for RPC users: This code for a non-super user application to register as a RPC service provider worked in Red Hat Enterprise Linux 5.4: SVCXPRT *transp = svctcp_create(RPC_ANYSOCK, 0, 0); svc_register(transp, prog, vers, callback, IPPROTO_TCP); but gives this error in RHEL 6.1 and Fedora 15: Cannot register service: RPC: Authentication error; why = Client credential too weak A program generated with rpcgen will also get this error. This problem was introduced when portmapper was replaced with rpcbind in Red Hat 6. The error message and the rpcbind man page sent me trying to change TCP wrapper configuration and use gss rpc. But only the rpcbind -i option works. Either Andy's change to the rpcbind man page should be made: In the absence of the -i option, calls are accepted only from privileged ports via the loopback interface. Or some form of Andy's change to rpcbind options should be made to allow non-super user applications to register an RPC service from the local host. This issue should be documented in the release notes. I can not use rpcbind -i because of poor security so need to recode my application to not use RPC.
Our environment has been impacted by this issue as well. We're a university lab, with at least one class that uses RPC programming as a student exercise. For the obvious security reasons, we'd like to be able to allow non-root set/unset for student code, while still restricting them to localhost. The earlier patch sounds like exactly what we need, though it appears never to have been accepted.
For whatever it's worth, there seems to be a simpler and undocumented patch for this in Fedora 16. It removes the port number check in security.c:is_loopback(). It's a shame that my patch hasn't been accepted, but this gets the job done for now. Regards, Andy
(In reply to comment #9) > For whatever it's worth, there seems to be a simpler and undocumented patch > for this in Fedora 16. It removes the port number check in > security.c:is_loopback(). > > It's a shame that my patch hasn't been accepted, but this gets the job done > for now. Is this the patch you are talking about? I think this upstream patch is what you are looking for commit 1d9fba5b631b517094c85a80f45f6f7ba1665e2a Author: Olaf Kirch <okir@suse.de> Date: Wed Mar 16 14:19:37 2011 -0400 Make is_loopback check more permissive This patch relaxes the is_loopback() check to its original meaning; i.e. verify that the caller is local. We no longer check whether the source port is privileged, for a number of reasons. 1) The existing check did not allow *any* non-root program to register a services via UDP or TCP transport. It did however allow *any* registration when using the AF_LOCAL transport. 2) Unregistration of services is only possible if the caller has the same "user name", i.e. "superuser" for root (when connecting through AF_LOCAL sockets, or when using pmap_set with a privileged port) numeric uid for non-root users when connecting through AF_LOCAL sockets "unknown" for all other users This seems safe enough to allow the removal of the privileged port check in is_localhost. Signed-off-by: Olaf Kirch <okir@suse.de> Signed-off-by: Steve Dickson <steved@redhat.com> diff --git a/src/security.c b/src/security.c index 07c8933..d272f74 100644 --- a/src/security.c +++ b/src/security.c @@ -138,8 +138,7 @@ is_loopback(struct netbuf *nbuf) "Checking caller's adress (port = %d)\n", ntohs(sin->sin_port)); #endif - return ((sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) && - (ntohs(sin->sin_port) < IPPORT_RESERVED)); + return (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)); #ifdef INET6 case AF_INET6: if (!oldstyle_local) @@ -151,10 +150,9 @@ is_loopback(struct netbuf *nbuf) "Checking caller's adress (port = %d)\n", ntohs(sin6->sin6_port)); #endif - return ((IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) || + return (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) || (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) && - sin6->sin6_addr.s6_addr32[3] == htonl(INADDR_LOOPBACK) - (ntohs(sin6->sin6_port) < IPV6PORT_RESERVED)); + sin6->sin6_addr.s6_addr32[3] == htonl(INADDR_LOOPBACK) #endif case AF_LOCAL: return 1;
*** Bug 717922 has been marked as a duplicate of this bug. ***
Reproduced with rpcbind-0.2.0-9.el6, non-root user couldn't register service [root@fstest rpcbind]# su gery -c "rpc_issue/test_server" Cannot register service: RPC: Authentication error; why = Client credential too weak unable to register (PROG1, PROG_VERS, udp). Verified with rpcbind-0.2.0-11.el6 [root@fstest rpcbind]# su gery -c "rpc_issue/test_server" server received: 5 # On another terminal [root@fstest rpc_issue]# su gery -c "./test_client localhost" client received: 10 Test program is from bug 717922 comment 0 Set VERIFIED
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. http://rhn.redhat.com/errata/RHBA-2013-0291.html