2018-02-05 16:36:49

by Steve Dickson

[permalink] [raw]
Subject: [PATCH 0/1] Remote calls don't need to use privilege ports

Over the weekend I did some experimenting with
the remote call code in rpcbind. The code does
functionally work but is very antiquated when
it comes to the latest NFS versions.

Since only UDP sockets are used to do remote calls
using the documented interfaces pmap_rmtcall() and callrpc()
calls to NFS will fail (actual times out) since UDP is no
longer supported.

The undocumented interface rpc_call() can be used to
call into NFS since the protocol can specified, which
also means the PMAPPROC_CALLIT protocol is not used.

It turns out privilege port are not needed to make
remote calls, at least with my testing. I'm thinking
the only reason privilege ports were being uses was
a side effect of create_rmtcall_fd() calling
svc_tli_create() with an unbound socket.

So the following patch simply binds the socket
before calling svc_tli_create() which means a
non-privilege port will be reserved for remote
calls.

I'm thinking this is the simplest way to
not pollute the privilege port space.

Steve Dickson (1):
rmtcalls: Don't use privileged ports for remote calls.

src/rpcb_svc_com.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)

--
2.14.3



2018-02-05 16:36:49

by Steve Dickson

[permalink] [raw]
Subject: [PATCH 1/1] rmtcalls: Don't use privileged ports for remote calls.

Sockets use for remote calls are preallocated which
mean the a port will be tied up for as long as
rpcbind runs. Make sure that port is not a privileged
port by binding the socket before calling svc_tli_create()

Signed-off-by: Steve Dickson <[email protected]>
---
src/rpcb_svc_com.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/rpcb_svc_com.c b/src/rpcb_svc_com.c
index 9c1c3af..b9aeaaf 100644
--- a/src/rpcb_svc_com.c
+++ b/src/rpcb_svc_com.c
@@ -501,9 +501,12 @@ static struct rmtcallfd_list *rmttail;
int
create_rmtcall_fd(struct netconfig *nconf)
{
- int fd;
+ int fd, cc;
struct rmtcallfd_list *rmt;
SVCXPRT *xprt;
+ struct __rpc_sockinfo si;
+ struct sockaddr_storage ss;
+ struct t_bind bindaddr;

if ((fd = __rpc_nconf2fd(nconf)) == -1) {
if (debugging)
@@ -512,6 +515,20 @@ create_rmtcall_fd(struct netconfig *nconf)
nconf->nc_device, errno);
return (-1);
}
+
+ if (!__rpc_nconf2sockinfo(nconf, &si)) {
+ xlog(LOG_ERR, "create_rmtcall_fd: cannot get information for %s",
+ nconf->nc_netid);
+ return (-1);
+ }
+ memset(&ss, 0, sizeof ss);
+ ss.ss_family = si.si_af;
+ cc = bind(fd, (struct sockaddr *)(void *)&ss,
+ (socklen_t)si.si_alen);
+ if (cc < 0) {
+ xlog(LOG_ERR, "create_rmtcall_fd: could not bind to anonymous port");
+ return (-1);
+ }
xprt = svc_tli_create(fd, 0, (struct t_bind *) 0, 0, 0);
if (xprt == NULL) {
if (debugging)
--
2.14.3


2018-02-05 17:02:33

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports

Heya Steve-

> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> wrote:
>=20
> Over the weekend I did some experimenting with
> the remote call code in rpcbind. The code does=20
> functionally work but is very antiquated when
> it comes to the latest NFS versions.=20
>=20
> Since only UDP sockets are used to do remote calls
> using the documented interfaces pmap_rmtcall() and callrpc()
> calls to NFS will fail (actual times out) since UDP is no=20
> longer supported.=20
>=20
> The undocumented interface rpc_call() can be used to=20
> call into NFS since the protocol can specified, which=20
> also means the PMAPPROC_CALLIT protocol is not used.
>=20
> It turns out privilege port are not needed to make
> remote calls, at least with my testing.

It's not quite clear what you are claiming here, but
I'm guessing that what you demonstrated is that the
CALLIT _listener_ does not have to be privileged?

I claim that is true for all RPC listeners.


> I'm thinking=20
> the only reason privilege ports were being uses was=20
> a side effect of create_rmtcall_fd() calling=20
> svc_tli_create() with an unbound socket.

Privileged listener ports are being created because
svc_tli_create is using bindresvport when the passed
in socket is not already bound.

svc_tli_create should use bind instead, and it needs
to choose a port higher than 49151.

=
https://www.iana.org/assignments/service-names-port-numbers/service-names-=
port-numbers.xhtml


> So the following patch simply binds the socket
> before calling svc_tli_create() which means a
> non-privilege port will be reserved for remote
> calls.=20
>=20
> I'm thinking this is the simplest way to
> not pollute the privilege port space.=20

This is going in the right direction, but the problem
needs to be addressed in svc_tli_create, not in each
application that calls svc_tli_create.

This is the same issue that Guillem Jover was trying to
address by making bindresvport skip well-known ports.

In other words: this code in src/svc_generic.c is wrong:

218 /*
219 * If the fd is unbound, try to bind it.
220 */
221 if (madefd || !__rpc_sockisbound(fd)) {
222 if (bindaddr =3D=3D NULL) {
223 if (bindresvport(fd, NULL) < 0) {
^^^^^^^^^^^^

224 memset(&ss, 0, sizeof ss);
225 ss.ss_family =3D si.si_af;
226 if (bind(fd, (struct sockaddr =
*)(void *)&ss,
227 (socklen_t)si.si_alen) < 0) {
228 warnx(
229 "svc_tli_create: could not bind to anonymous =
port");
230 goto freedata;
231 }
232 }
233 listen(fd, SOMAXCONN);
234 } else {
235 if (bind(fd,
236 (struct sockaddr *)bindaddr->addr.buf,
237 (socklen_t)si.si_alen) < 0) {
238 warnx(
239 "svc_tli_create: could not bind to requested =
address");
240 goto freedata;
241 }
242 listen(fd, (int)bindaddr->qlen);
243 }
244=20
245 }


> Steve Dickson (1):
> rmtcalls: Don't use privileged ports for remote calls.
>=20
> src/rpcb_svc_com.c | 19 ++++++++++++++++++-
> 1 file changed, 18 insertions(+), 1 deletion(-)


--
Chuck Lever




2018-02-05 17:09:47

by Tom Talpey

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports

On 2/5/2018 12:02 PM, Chuck Lever wrote:
> Heya Steve-
>
>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> wrote:
>>
>> Over the weekend I did some experimenting with
>> the remote call code in rpcbind. The code does
>> functionally work but is very antiquated when
>> it comes to the latest NFS versions.
>>
>> Since only UDP sockets are used to do remote calls
>> using the documented interfaces pmap_rmtcall() and callrpc()
>> calls to NFS will fail (actual times out) since UDP is no
>> longer supported.
>>
>> The undocumented interface rpc_call() can be used to
>> call into NFS since the protocol can specified, which
>> also means the PMAPPROC_CALLIT protocol is not used.
>>
>> It turns out privilege port are not needed to make
>> remote calls, at least with my testing.
>
> It's not quite clear what you are claiming here, but
> I'm guessing that what you demonstrated is that the
> CALLIT _listener_ does not have to be privileged?
>
> I claim that is true for all RPC listeners.


Why in the world is the remote-call interface even still supported?
It is and was a mammoth security hole allowing machine impersonation,
and to my knowledge no actual services or applications depends on
it. Why not bury it under some compatibility option, default=off??

Tom.


>
>> I'm thinking
>> the only reason privilege ports were being uses was
>> a side effect of create_rmtcall_fd() calling
>> svc_tli_create() with an unbound socket.
>
> Privileged listener ports are being created because
> svc_tli_create is using bindresvport when the passed
> in socket is not already bound.
>
> svc_tli_create should use bind instead, and it needs
> to choose a port higher than 49151.
>
> https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
>
>
>> So the following patch simply binds the socket
>> before calling svc_tli_create() which means a
>> non-privilege port will be reserved for remote
>> calls.
>>
>> I'm thinking this is the simplest way to
>> not pollute the privilege port space.
>
> This is going in the right direction, but the problem
> needs to be addressed in svc_tli_create, not in each
> application that calls svc_tli_create.
>
> This is the same issue that Guillem Jover was trying to
> address by making bindresvport skip well-known ports.
>
> In other words: this code in src/svc_generic.c is wrong:
>
> 218 /*
> 219 * If the fd is unbound, try to bind it.
> 220 */
> 221 if (madefd || !__rpc_sockisbound(fd)) {
> 222 if (bindaddr == NULL) {
> 223 if (bindresvport(fd, NULL) < 0) {
> ^^^^^^^^^^^^
>
> 224 memset(&ss, 0, sizeof ss);
> 225 ss.ss_family = si.si_af;
> 226 if (bind(fd, (struct sockaddr *)(void *)&ss,
> 227 (socklen_t)si.si_alen) < 0) {
> 228 warnx(
> 229 "svc_tli_create: could not bind to anonymous port");
> 230 goto freedata;
> 231 }
> 232 }
> 233 listen(fd, SOMAXCONN);
> 234 } else {
> 235 if (bind(fd,
> 236 (struct sockaddr *)bindaddr->addr.buf,
> 237 (socklen_t)si.si_alen) < 0) {
> 238 warnx(
> 239 "svc_tli_create: could not bind to requested address");
> 240 goto freedata;
> 241 }
> 242 listen(fd, (int)bindaddr->qlen);
> 243 }
> 244
> 245 }
>
>
>> Steve Dickson (1):
>> rmtcalls: Don't use privileged ports for remote calls.
>>
>> src/rpcb_svc_com.c | 19 ++++++++++++++++++-
>> 1 file changed, 18 insertions(+), 1 deletion(-)
>
>
> --
> Chuck Lever
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>

2018-02-05 17:11:36

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports



> On Feb 5, 2018, at 12:09 PM, Tom Talpey <[email protected]> wrote:
>=20
> On 2/5/2018 12:02 PM, Chuck Lever wrote:
>> Heya Steve-
>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> =
wrote:
>>>=20
>>> Over the weekend I did some experimenting with
>>> the remote call code in rpcbind. The code does
>>> functionally work but is very antiquated when
>>> it comes to the latest NFS versions.
>>>=20
>>> Since only UDP sockets are used to do remote calls
>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>> calls to NFS will fail (actual times out) since UDP is no
>>> longer supported.
>>>=20
>>> The undocumented interface rpc_call() can be used to
>>> call into NFS since the protocol can specified, which
>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>=20
>>> It turns out privilege port are not needed to make
>>> remote calls, at least with my testing.
>> It's not quite clear what you are claiming here, but
>> I'm guessing that what you demonstrated is that the
>> CALLIT _listener_ does not have to be privileged?
>> I claim that is true for all RPC listeners.
>=20
>=20
> Why in the world is the remote-call interface even still supported?
> It is and was a mammoth security hole allowing machine impersonation,
> and to my knowledge no actual services or applications depends on
> it. Why not bury it under some compatibility option, default=3Doff??

I agree, and that has been proposed (just last week in this thread).


> Tom.
>=20
>=20
>>> I'm thinking
>>> the only reason privilege ports were being uses was
>>> a side effect of create_rmtcall_fd() calling
>>> svc_tli_create() with an unbound socket.
>> Privileged listener ports are being created because
>> svc_tli_create is using bindresvport when the passed
>> in socket is not already bound.
>> svc_tli_create should use bind instead, and it needs
>> to choose a port higher than 49151.
>> =
https://www.iana.org/assignments/service-names-port-numbers/service-names-=
port-numbers.xhtml
>>> So the following patch simply binds the socket
>>> before calling svc_tli_create() which means a
>>> non-privilege port will be reserved for remote
>>> calls.
>>>=20
>>> I'm thinking this is the simplest way to
>>> not pollute the privilege port space.
>> This is going in the right direction, but the problem
>> needs to be addressed in svc_tli_create, not in each
>> application that calls svc_tli_create.
>> This is the same issue that Guillem Jover was trying to
>> address by making bindresvport skip well-known ports.
>> In other words: this code in src/svc_generic.c is wrong:
>> 218 /*
>> 219 * If the fd is unbound, try to bind it.
>> 220 */
>> 221 if (madefd || !__rpc_sockisbound(fd)) {
>> 222 if (bindaddr =3D=3D NULL) {
>> 223 if (bindresvport(fd, NULL) < 0) {
>> ^^^^^^^^^^^^
>> 224 memset(&ss, 0, sizeof ss);
>> 225 ss.ss_family =3D si.si_af;
>> 226 if (bind(fd, (struct sockaddr =
*)(void *)&ss,
>> 227 (socklen_t)si.si_alen) < 0) {
>> 228 warnx(
>> 229 "svc_tli_create: could not bind to =
anonymous port");
>> 230 goto freedata;
>> 231 }
>> 232 }
>> 233 listen(fd, SOMAXCONN);
>> 234 } else {
>> 235 if (bind(fd,
>> 236 (struct sockaddr =
*)bindaddr->addr.buf,
>> 237 (socklen_t)si.si_alen) < 0) {
>> 238 warnx(
>> 239 "svc_tli_create: could not bind to requested =
address");
>> 240 goto freedata;
>> 241 }
>> 242 listen(fd, (int)bindaddr->qlen);
>> 243 }
>> 244
>> 245 }
>>> Steve Dickson (1):
>>> rmtcalls: Don't use privileged ports for remote calls.
>>>=20
>>> src/rpcb_svc_com.c | 19 ++++++++++++++++++-
>>> 1 file changed, 18 insertions(+), 1 deletion(-)
>> --
>> Chuck Lever
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" =
in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html

--
Chuck Lever




2018-02-05 19:21:21

by Steve Dickson

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports



On 02/05/2018 12:02 PM, Chuck Lever wrote:
> Heya Steve-
>
>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> wrote:
>>
>> Over the weekend I did some experimenting with
>> the remote call code in rpcbind. The code does
>> functionally work but is very antiquated when
>> it comes to the latest NFS versions.
>>
>> Since only UDP sockets are used to do remote calls
>> using the documented interfaces pmap_rmtcall() and callrpc()
>> calls to NFS will fail (actual times out) since UDP is no
>> longer supported.
>>
>> The undocumented interface rpc_call() can be used to
>> call into NFS since the protocol can specified, which
>> also means the PMAPPROC_CALLIT protocol is not used.
>>
>> It turns out privilege port are not needed to make
>> remote calls, at least with my testing.
>
> It's not quite clear what you are claiming here, but
> I'm guessing that what you demonstrated is that the
> CALLIT _listener_ does not have to be privileged?
Right...
>
> I claim that is true for all RPC listeners.
It could be true..

>
>
>> I'm thinking
>> the only reason privilege ports were being uses was
>> a side effect of create_rmtcall_fd() calling
>> svc_tli_create() with an unbound socket.
>
> Privileged listener ports are being created because
> svc_tli_create is using bindresvport when the passed
> in socket is not already bound.
Right... So handing svc_tli_create a bound socket will
cause the bindresvport not to happen.

>
> svc_tli_create should use bind instead, and it needs
> to choose a port higher than 49151.Actual it does when a t_bind structure is passed in.
But more to the point, I thought about changing
svc_tli_create but that would effect all the callers
of the routine which I didn't think was a good idea
for code that is basically not used.

Also, now that libtirpc is the only Linux RPC implementation
(the RPC code has been removed from glibc) I'm a bit
sensitive to changing functionality unless its a
clear bug or security issue.

>
> https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
Hmm... I have been conveniently ignoring Thorsten's blacklist patch.
Maybe we should take another look at that.

>
>
>> So the following patch simply binds the socket
>> before calling svc_tli_create() which means a
>> non-privilege port will be reserved for remote
>> calls.
>>
>> I'm thinking this is the simplest way to
>> not pollute the privilege port space.
>
> This is going in the right direction, but the problem
> needs to be addressed in svc_tli_create, not in each
> application that calls svc_tli_create.
>
> This is the same issue that Guillem Jover was trying to
> address by making bindresvport skip well-known ports.
>
> In other words: this code in src/svc_generic.c is wrong:
It could be... but the API allows for the bindresvport (or any bind)
to not happen... So changing how it is called I think is
appropriate... Plus its been working this way for a long to so
I'm very resistant to change functionality basically for no reason.

But I do think we should look into bindresvport using a black list
since it is already established in SuSE

steved.

>
> 218 /*
> 219 * If the fd is unbound, try to bind it.
> 220 */
> 221 if (madefd || !__rpc_sockisbound(fd)) {
> 222 if (bindaddr == NULL) {
> 223 if (bindresvport(fd, NULL) < 0) {
> ^^^^^^^^^^^^
>
> 224 memset(&ss, 0, sizeof ss);
> 225 ss.ss_family = si.si_af;
> 226 if (bind(fd, (struct sockaddr *)(void *)&ss,
> 227 (socklen_t)si.si_alen) < 0) {
> 228 warnx(
> 229 "svc_tli_create: could not bind to anonymous port");
> 230 goto freedata;
> 231 }
> 232 }
> 233 listen(fd, SOMAXCONN);
> 234 } else {
> 235 if (bind(fd,
> 236 (struct sockaddr *)bindaddr->addr.buf,
> 237 (socklen_t)si.si_alen) < 0) {
> 238 warnx(
> 239 "svc_tli_create: could not bind to requested address");
> 240 goto freedata;
> 241 }
> 242 listen(fd, (int)bindaddr->qlen);
> 243 }
> 244
> 245 }
>
>
>> Steve Dickson (1):
>> rmtcalls: Don't use privileged ports for remote calls.
>>
>> src/rpcb_svc_com.c | 19 ++++++++++++++++++-
>> 1 file changed, 18 insertions(+), 1 deletion(-)
>
>
> --
> Chuck Lever
>
>
>

2018-02-05 19:46:33

by Steve Dickson

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports



On 02/05/2018 12:09 PM, Tom Talpey wrote:
> On 2/5/2018 12:02 PM, Chuck Lever wrote:
>> Heya Steve-
>>
>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> wrote:
>>>
>>> Over the weekend I did some experimenting with
>>> the remote call code in rpcbind. The code does
>>> functionally work but is very antiquated when
>>> it comes to the latest NFS versions.
>>>
>>> Since only UDP sockets are used to do remote calls
>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>> calls to NFS will fail (actual times out) since UDP is no
>>> longer supported.
>>>
>>> The undocumented interface rpc_call() can be used to
>>> call into NFS since the protocol can specified, which
>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>
>>> It turns out privilege port are not needed to make
>>> remote calls, at least with my testing.
>>
>> It's not quite clear what you are claiming here, but
>> I'm guessing that what you demonstrated is that the
>> CALLIT _listener_ does not have to be privileged?
>>
>> I claim that is true for all RPC listeners.
>
>
> Why in the world is the remote-call interface even still supported?
> It is and was a mammoth security hole allowing machine impersonation,
> and to my knowledge no actual services or applications depends on
> it. Why not bury it under some compatibility option, default=off??
I did not realize it was a security hole since the info returned
can be gotten in other ways... But I do see Netapp has disabled
the procedure.

steved.


2018-02-05 19:50:18

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports

Hi Steve-

> On Feb 5, 2018, at 2:21 PM, Steve Dickson <[email protected]> wrote:
>=20
>=20
>=20
> On 02/05/2018 12:02 PM, Chuck Lever wrote:
>> Heya Steve-
>>=20
>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> =
wrote:
>>>=20
>>> Over the weekend I did some experimenting with
>>> the remote call code in rpcbind. The code does=20
>>> functionally work but is very antiquated when
>>> it comes to the latest NFS versions.=20
>>>=20
>>> Since only UDP sockets are used to do remote calls
>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>> calls to NFS will fail (actual times out) since UDP is no=20
>>> longer supported.=20
>>>=20
>>> The undocumented interface rpc_call() can be used to=20
>>> call into NFS since the protocol can specified, which=20
>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>=20
>>> It turns out privilege port are not needed to make
>>> remote calls, at least with my testing.
>>=20
>> It's not quite clear what you are claiming here, but
>> I'm guessing that what you demonstrated is that the
>> CALLIT _listener_ does not have to be privileged?
> Right...=20
>>=20
>> I claim that is true for all RPC listeners.
> It could be true..

"privileged port" always means a source port, never a
listener. There is no extra privilege given to a listener
port that is below 1024.

svc_tli_create is simply wrong to use bindresvport.


>>> I'm thinking=20
>>> the only reason privilege ports were being uses was=20
>>> a side effect of create_rmtcall_fd() calling=20
>>> svc_tli_create() with an unbound socket.
>>=20
>> Privileged listener ports are being created because
>> svc_tli_create is using bindresvport when the passed
>> in socket is not already bound.
> Right... So handing svc_tli_create a bound socket will
> cause the bindresvport not to happen.

True, and your patch corrects the behavior of rpcbind.

But I argue that is a workaround: svc_tli_create is
still doing the wrong thing for any other RPC server
that does not hand in a pre-bound socket. Fix it there
and all RPC servers that use libtirpc are fixed.


>> svc_tli_create should use bind instead, and it needs
>> to choose a port higher than 49151.Actual it does when a t_bind =
structure is passed in.=20
> But more to the point, I thought about changing=20
> svc_tli_create but that would effect all the callers
> of the routine which I didn't think was a good idea=20
> for code that is basically not used.

I'm not sure what you mean by "code that is basically
not used."

svc_tli_create is the bottom of the RPC stack. It is the
libtirpc API that is used every time an RPC server starts
a listener. mountd and statd call svc_tli_create
directly for example, from support/nfs/svc_create.c.

Thus this is the right place to fix it for all RPC server
applications.


> Also, now that libtirpc is the only Linux RPC implementation
> (the RPC code has been removed from glibc) I'm a bit
> sensitive to changing functionality unless its a=20
> clear bug or security issue.=20

This is a clear bug.

- The library should not be allowed to choose ports that
interfere with well-known services.

- The library should choose service ports based on well-
established standards, such as the IANA service names to
port numbers standard.


>> =
https://www.iana.org/assignments/service-names-port-numbers/service-names-=
port-numbers.xhtml
> Hmm... I have been conveniently ignoring Thorsten's blacklist patch.
> Maybe we should take another look at that.
>=20
>>=20
>>=20
>>> So the following patch simply binds the socket
>>> before calling svc_tli_create() which means a
>>> non-privilege port will be reserved for remote
>>> calls.=20
>>>=20
>>> I'm thinking this is the simplest way to
>>> not pollute the privilege port space.=20
>>=20
>> This is going in the right direction, but the problem
>> needs to be addressed in svc_tli_create, not in each
>> application that calls svc_tli_create.
>>=20
>> This is the same issue that Guillem Jover was trying to
>> address by making bindresvport skip well-known ports.
>>=20
>> In other words: this code in src/svc_generic.c is wrong:
> It could be... but the API allows for the bindresvport (or any bind)=20=

> to not happen... So changing how it is called I think is=20
> appropriate... Plus its been working this way for a long to so=20
> I'm very resistant to change functionality basically for no reason.=20
>=20
> But I do think we should look into bindresvport using a black list
> since it is already established in SuSE

IMO a bindresvport blacklist is absolutely the wrong approach.
We have standards organizations that have explained exactly how
this needs to work, and we want it to work without installing
extra files or giving admins more knobs that they really don't
need.

This is exactly the problem with distros applying patches
without upstream review. SuSE fixed this and let their fix sit
for years without any public bug report or review. IMO SuSE
should be prepared to take this hit, it should not constrain
upstream to choose a non-optimal long-term solution. I don't
see any compelling reason in this particular case that we need
to be constrained.

Fixing svc_tli_create to use ports higher than 49151 should be
completely compatible with any reasonable blacklist, and it
MUST be compatible with /etc/services, which is based on the
IANA publication (no well-known fixed ports above 49151).


> steved.
>=20
>>=20
>> 218 /*
>> 219 * If the fd is unbound, try to bind it.
>> 220 */
>> 221 if (madefd || !__rpc_sockisbound(fd)) {
>> 222 if (bindaddr =3D=3D NULL) {
>> 223 if (bindresvport(fd, NULL) < 0) {
>> ^^^^^^^^^^^^
>>=20
>> 224 memset(&ss, 0, sizeof ss);
>> 225 ss.ss_family =3D si.si_af;
>> 226 if (bind(fd, (struct sockaddr =
*)(void *)&ss,
>> 227 (socklen_t)si.si_alen) < 0) {
>> 228 warnx(
>> 229 "svc_tli_create: could not bind to =
anonymous port");
>> 230 goto freedata;
>> 231 }
>> 232 }
>> 233 listen(fd, SOMAXCONN);
>> 234 } else {
>> 235 if (bind(fd,
>> 236 (struct sockaddr =
*)bindaddr->addr.buf,
>> 237 (socklen_t)si.si_alen) < 0) {
>> 238 warnx(
>> 239 "svc_tli_create: could not bind to requested =
address");
>> 240 goto freedata;
>> 241 }
>> 242 listen(fd, (int)bindaddr->qlen);
>> 243 }
>> 244=20
>> 245 }
>>=20
>>=20
>>> Steve Dickson (1):
>>> rmtcalls: Don't use privileged ports for remote calls.
>>>=20
>>> src/rpcb_svc_com.c | 19 ++++++++++++++++++-
>>> 1 file changed, 18 insertions(+), 1 deletion(-)
>>=20
>>=20
>> --
>> Chuck Lever

--
Chuck Lever




2018-02-06 16:37:08

by Steve Dickson

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports



On 02/05/2018 02:47 PM, Chuck Lever wrote:
> Hi Steve-
>
>> On Feb 5, 2018, at 2:21 PM, Steve Dickson <[email protected]> wrote:
>>
>>
>>
>> On 02/05/2018 12:02 PM, Chuck Lever wrote:
>>> Heya Steve-
>>>
>>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> wrote:
>>>>
>>>> Over the weekend I did some experimenting with
>>>> the remote call code in rpcbind. The code does
>>>> functionally work but is very antiquated when
>>>> it comes to the latest NFS versions.
>>>>
>>>> Since only UDP sockets are used to do remote calls
>>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>>> calls to NFS will fail (actual times out) since UDP is no
>>>> longer supported.
>>>>
>>>> The undocumented interface rpc_call() can be used to
>>>> call into NFS since the protocol can specified, which
>>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>>
>>>> It turns out privilege port are not needed to make
>>>> remote calls, at least with my testing.
>>>
>>> It's not quite clear what you are claiming here, but
>>> I'm guessing that what you demonstrated is that the
>>> CALLIT _listener_ does not have to be privileged?
>> Right...
>>>
>>> I claim that is true for all RPC listeners.
>> It could be true..
>
> "privileged port" always means a source port, never a
> listener. There is no extra privilege given to a listener
> port that is below 1024.
>
> svc_tli_create is simply wrong to use bindresvport.
>
>
>>>> I'm thinking
>>>> the only reason privilege ports were being uses was
>>>> a side effect of create_rmtcall_fd() calling
>>>> svc_tli_create() with an unbound socket.
>>>
>>> Privileged listener ports are being created because
>>> svc_tli_create is using bindresvport when the passed
>>> in socket is not already bound.
>> Right... So handing svc_tli_create a bound socket will
>> cause the bindresvport not to happen.
>
> True, and your patch corrects the behavior of rpcbind.
>
> But I argue that is a workaround: svc_tli_create is
> still doing the wrong thing for any other RPC server
> that does not hand in a pre-bound socket. Fix it there
> and all RPC servers that use libtirpc are fixed.
>
>
>>> svc_tli_create should use bind instead, and it needs
>>> to choose a port higher than 49151.Actual it does when a t_bind structure is passed in.
>> But more to the point, I thought about changing
>> svc_tli_create but that would effect all the callers
>> of the routine which I didn't think was a good idea
>> for code that is basically not used.
>
> I'm not sure what you mean by "code that is basically
> not used."
>
> svc_tli_create is the bottom of the RPC stack. It is the
> libtirpc API that is used every time an RPC server starts
> a listener. mountd and statd call svc_tli_create
> directly for example, from support/nfs/svc_create.c.
>
> Thus this is the right place to fix it for all RPC server
> applications.
Actually I believe those application get their ports from /etc/rpc
via the getrpcbyname() and then hands svc_tli_create a
bound socket which the reason bindresvport is not done.

Side Note: /etc/rpc will be staying in glibc since it is
"backed by the NSS framework"


>
>
>> Also, now that libtirpc is the only Linux RPC implementation
>> (the RPC code has been removed from glibc) I'm a bit
>> sensitive to changing functionality unless its a
>> clear bug or security issue.
>
> This is a clear bug.
Lets do this... Please open up a upstream bz that justifies
why the bindresvport was removed from svc_tli_create().

If we break some legacy app I would like something to
point to explaining why the change was made

>
> - The library should not be allowed to choose ports that
> interfere with well-known services.
>
> - The library should choose service ports based on well-
> established standards, such as the IANA service names to
> port numbers standard.
>
>
>>> https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
>> Hmm... I have been conveniently ignoring Thorsten's blacklist patch.
>> Maybe we should take another look at that.
>>
>>>
>>>
>>>> So the following patch simply binds the socket
>>>> before calling svc_tli_create() which means a
>>>> non-privilege port will be reserved for remote
>>>> calls.
>>>>
>>>> I'm thinking this is the simplest way to
>>>> not pollute the privilege port space.
>>>
>>> This is going in the right direction, but the problem
>>> needs to be addressed in svc_tli_create, not in each
>>> application that calls svc_tli_create.
>>>
>>> This is the same issue that Guillem Jover was trying to
>>> address by making bindresvport skip well-known ports.
>>>
>>> In other words: this code in src/svc_generic.c is wrong:
>> It could be... but the API allows for the bindresvport (or any bind)
>> to not happen... So changing how it is called I think is
>> appropriate... Plus its been working this way for a long to so
>> I'm very resistant to change functionality basically for no reason.
>>
>> But I do think we should look into bindresvport using a black list
>> since it is already established in SuSE
>
> IMO a bindresvport blacklist is absolutely the wrong approach.
> We have standards organizations that have explained exactly how
> this needs to work, and we want it to work without installing
> extra files or giving admins more knobs that they really don't
> need.
>
> This is exactly the problem with distros applying patches
> without upstream review. SuSE fixed this and let their fix sit
> for years without any public bug report or review. IMO SuSE
> should be prepared to take this hit, it should not constrain
> upstream to choose a non-optimal long-term solution. I don't
> see any compelling reason in this particular case that we need
> to be constrained.
>
> Fixing svc_tli_create to use ports higher than 49151 should be
> completely compatible with any reasonable blacklist, and it
> MUST be compatible with /etc/services, which is based on the
> IANA publication (no well-known fixed ports above 49151).
>
Let me look into this...

steved.

2018-02-06 17:35:06

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports



> On Feb 6, 2018, at 11:37 AM, Steve Dickson <[email protected]> wrote:
>=20
>=20
>=20
> On 02/05/2018 02:47 PM, Chuck Lever wrote:
>> Hi Steve-
>>=20
>>> On Feb 5, 2018, at 2:21 PM, Steve Dickson <[email protected]> wrote:
>>>=20
>>>=20
>>>=20
>>> On 02/05/2018 12:02 PM, Chuck Lever wrote:
>>>> Heya Steve-
>>>>=20
>>>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> =
wrote:
>>>>>=20
>>>>> Over the weekend I did some experimenting with
>>>>> the remote call code in rpcbind. The code does=20
>>>>> functionally work but is very antiquated when
>>>>> it comes to the latest NFS versions.=20
>>>>>=20
>>>>> Since only UDP sockets are used to do remote calls
>>>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>>>> calls to NFS will fail (actual times out) since UDP is no=20
>>>>> longer supported.=20
>>>>>=20
>>>>> The undocumented interface rpc_call() can be used to=20
>>>>> call into NFS since the protocol can specified, which=20
>>>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>>>=20
>>>>> It turns out privilege port are not needed to make
>>>>> remote calls, at least with my testing.
>>>>=20
>>>> It's not quite clear what you are claiming here, but
>>>> I'm guessing that what you demonstrated is that the
>>>> CALLIT _listener_ does not have to be privileged?
>>> Right...=20
>>>>=20
>>>> I claim that is true for all RPC listeners.
>>> It could be true..
>>=20
>> "privileged port" always means a source port, never a
>> listener. There is no extra privilege given to a listener
>> port that is below 1024.
>>=20
>> svc_tli_create is simply wrong to use bindresvport.
>>=20
>>=20
>>>>> I'm thinking=20
>>>>> the only reason privilege ports were being uses was=20
>>>>> a side effect of create_rmtcall_fd() calling=20
>>>>> svc_tli_create() with an unbound socket.
>>>>=20
>>>> Privileged listener ports are being created because
>>>> svc_tli_create is using bindresvport when the passed
>>>> in socket is not already bound.
>>> Right... So handing svc_tli_create a bound socket will
>>> cause the bindresvport not to happen.
>>=20
>> True, and your patch corrects the behavior of rpcbind.
>>=20
>> But I argue that is a workaround: svc_tli_create is
>> still doing the wrong thing for any other RPC server
>> that does not hand in a pre-bound socket. Fix it there
>> and all RPC servers that use libtirpc are fixed.
>>=20
>>=20
>>>> svc_tli_create should use bind instead, and it needs
>>>> to choose a port higher than 49151.Actual it does when a t_bind =
structure is passed in.=20
>>> But more to the point, I thought about changing=20
>>> svc_tli_create but that would effect all the callers
>>> of the routine which I didn't think was a good idea=20
>>> for code that is basically not used.
>>=20
>> I'm not sure what you mean by "code that is basically
>> not used."
>>=20
>> svc_tli_create is the bottom of the RPC stack. It is the
>> libtirpc API that is used every time an RPC server starts
>> a listener. mountd and statd call svc_tli_create
>> directly for example, from support/nfs/svc_create.c.
>>=20
>> Thus this is the right place to fix it for all RPC server
>> applications.
> Actually I believe those application get their ports from /etc/rpc=20
> via the getrpcbyname() and then hands svc_tli_create a
> bound socket which the reason bindresvport is not done.

/etc/rpc lists RPC program numbers, not ports.

mountd can and should use a dynamic port assignment, IMO.
It doesn't have to use 20048.


> Side Note: /etc/rpc will be staying in glibc since it is
> "backed by the NSS framework"
>=20
>=20
>>=20
>>=20
>>> Also, now that libtirpc is the only Linux RPC implementation
>>> (the RPC code has been removed from glibc) I'm a bit
>>> sensitive to changing functionality unless its a=20
>>> clear bug or security issue.=20
>>=20
>> This is a clear bug.
> Lets do this... Please open up a upstream bz that justifies
> why the bindresvport was removed from svc_tli_create().
>=20
> If we break some legacy app I would like something to
> point to explaining why the change was made

That's fair. Also, my name will be on the bug and on the
justification, so you can blame me when it goes all snafooey.

:-)


>> - The library should not be allowed to choose ports that
>> interfere with well-known services.
>>=20
>> - The library should choose service ports based on well-
>> established standards, such as the IANA service names to
>> port numbers standard.
>>=20
>>=20
>>>> =
https://www.iana.org/assignments/service-names-port-numbers/service-names-=
port-numbers.xhtml
>>> Hmm... I have been conveniently ignoring Thorsten's blacklist patch.
>>> Maybe we should take another look at that.
>>>=20
>>>>=20
>>>>=20
>>>>> So the following patch simply binds the socket
>>>>> before calling svc_tli_create() which means a
>>>>> non-privilege port will be reserved for remote
>>>>> calls.=20
>>>>>=20
>>>>> I'm thinking this is the simplest way to
>>>>> not pollute the privilege port space.=20
>>>>=20
>>>> This is going in the right direction, but the problem
>>>> needs to be addressed in svc_tli_create, not in each
>>>> application that calls svc_tli_create.
>>>>=20
>>>> This is the same issue that Guillem Jover was trying to
>>>> address by making bindresvport skip well-known ports.
>>>>=20
>>>> In other words: this code in src/svc_generic.c is wrong:
>>> It could be... but the API allows for the bindresvport (or any bind)=20=

>>> to not happen... So changing how it is called I think is=20
>>> appropriate... Plus its been working this way for a long to so=20
>>> I'm very resistant to change functionality basically for no reason.=20=

>>>=20
>>> But I do think we should look into bindresvport using a black list
>>> since it is already established in SuSE
>>=20
>> IMO a bindresvport blacklist is absolutely the wrong approach.
>> We have standards organizations that have explained exactly how
>> this needs to work, and we want it to work without installing
>> extra files or giving admins more knobs that they really don't
>> need.
>>=20
>> This is exactly the problem with distros applying patches
>> without upstream review. SuSE fixed this and let their fix sit
>> for years without any public bug report or review. IMO SuSE
>> should be prepared to take this hit, it should not constrain
>> upstream to choose a non-optimal long-term solution. I don't
>> see any compelling reason in this particular case that we need
>> to be constrained.
>>=20
>> Fixing svc_tli_create to use ports higher than 49151 should be
>> completely compatible with any reasonable blacklist, and it
>> MUST be compatible with /etc/services, which is based on the
>> IANA publication (no well-known fixed ports above 49151).
>>=20
> Let me look into this...=20
>=20
> steved.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" =
in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

--
Chuck Lever




2018-02-06 18:29:33

by Tom Talpey

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports

On 2/6/2018 12:34 PM, Chuck Lever wrote:
> mountd can and should use a dynamic port assignment, IMO.
> It doesn't have to use 20048.

Speaking of 20048, does anyone know why Nico made this assignment?
Apart from making it well-known for firewalls, what system(s)
actually required it? I don't recall it ever being discussed.
Using it is certainly not required, since portmap resolves it.

https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt

++ mountd 20048 tcp NFS mount protocol
[Nicolas_Williams] [Nicolas_Williams]
2010-08-09
++ mountd 20048 udp NFS mount protocol
[Nicolas_Williams] [Nicolas_Williams]
2010-08-09

Tom.

2018-02-06 18:47:04

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports



> On Feb 6, 2018, at 1:22 PM, Tom Talpey <[email protected]> wrote:
>=20
> On 2/6/2018 12:34 PM, Chuck Lever wrote:
>> mountd can and should use a dynamic port assignment, IMO.
>> It doesn't have to use 20048.
>=20
> Speaking of 20048, does anyone know why Nico made this assignment?
> Apart from making it well-known for firewalls, what system(s)
> actually required it? I don't recall it ever being discussed.
> Using it is certainly not required, since portmap resolves it.
>=20
> =
https://www.iana.org/assignments/service-names-port-numbers/service-names-=
port-numbers.txt
>=20
> ++ mountd 20048 tcp NFS mount protocol =
[Nicolas_Williams] [Nicolas_Williams] =
2010-08-09
> ++ mountd 20048 udp NFS mount protocol =
[Nicolas_Williams] [Nicolas_Williams] =
2010-08-09

Actually my first active interaction with the nfsv4 WG was at the
IETF meeting in Montreal in late July of 2010. So I can't say that
I have any memory of why this was done. It might be a question that
can be answered by someone on [email protected].


--
Chuck Lever




2018-02-06 19:00:16

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports



> On Feb 6, 2018, at 11:37 AM, Steve Dickson <[email protected]> wrote:
>=20
>=20
>=20
> On 02/05/2018 02:47 PM, Chuck Lever wrote:
>> Hi Steve-
>>=20
>>> On Feb 5, 2018, at 2:21 PM, Steve Dickson <[email protected]> wrote:
>>>=20
>>>=20
>>>=20
>>> On 02/05/2018 12:02 PM, Chuck Lever wrote:
>>>> Heya Steve-
>>>>=20
>>>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> =
wrote:
>>>>>=20
>>>>> Over the weekend I did some experimenting with
>>>>> the remote call code in rpcbind. The code does=20
>>>>> functionally work but is very antiquated when
>>>>> it comes to the latest NFS versions.=20
>>>>>=20
>>>>> Since only UDP sockets are used to do remote calls
>>>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>>>> calls to NFS will fail (actual times out) since UDP is no=20
>>>>> longer supported.=20
>>>>>=20
>>>>> The undocumented interface rpc_call() can be used to=20
>>>>> call into NFS since the protocol can specified, which=20
>>>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>>>=20
>>>>> It turns out privilege port are not needed to make
>>>>> remote calls, at least with my testing.
>>>>=20
>>>> It's not quite clear what you are claiming here, but
>>>> I'm guessing that what you demonstrated is that the
>>>> CALLIT _listener_ does not have to be privileged?
>>> Right...=20
>>>>=20
>>>> I claim that is true for all RPC listeners.
>>> It could be true..
>>=20
>> "privileged port" always means a source port, never a
>> listener. There is no extra privilege given to a listener
>> port that is below 1024.
>>=20
>> svc_tli_create is simply wrong to use bindresvport.
>>=20
>>=20
>>>>> I'm thinking=20
>>>>> the only reason privilege ports were being uses was=20
>>>>> a side effect of create_rmtcall_fd() calling=20
>>>>> svc_tli_create() with an unbound socket.
>>>>=20
>>>> Privileged listener ports are being created because
>>>> svc_tli_create is using bindresvport when the passed
>>>> in socket is not already bound.
>>> Right... So handing svc_tli_create a bound socket will
>>> cause the bindresvport not to happen.
>>=20
>> True, and your patch corrects the behavior of rpcbind.
>>=20
>> But I argue that is a workaround: svc_tli_create is
>> still doing the wrong thing for any other RPC server
>> that does not hand in a pre-bound socket. Fix it there
>> and all RPC servers that use libtirpc are fixed.
>>=20
>>=20
>>>> svc_tli_create should use bind instead, and it needs
>>>> to choose a port higher than 49151.Actual it does when a t_bind =
structure is passed in.=20
>>> But more to the point, I thought about changing=20
>>> svc_tli_create but that would effect all the callers
>>> of the routine which I didn't think was a good idea=20
>>> for code that is basically not used.
>>=20
>> I'm not sure what you mean by "code that is basically
>> not used."
>>=20
>> svc_tli_create is the bottom of the RPC stack. It is the
>> libtirpc API that is used every time an RPC server starts
>> a listener. mountd and statd call svc_tli_create
>> directly for example, from support/nfs/svc_create.c.
>>=20
>> Thus this is the right place to fix it for all RPC server
>> applications.
> Actually I believe those application get their ports from /etc/rpc=20
> via the getrpcbyname() and then hands svc_tli_create a
> bound socket which the reason bindresvport is not done.
>=20
> Side Note: /etc/rpc will be staying in glibc since it is
> "backed by the NSS framework"
>=20
>=20
>>=20
>>=20
>>> Also, now that libtirpc is the only Linux RPC implementation
>>> (the RPC code has been removed from glibc) I'm a bit
>>> sensitive to changing functionality unless its a=20
>>> clear bug or security issue.=20
>>=20
>> This is a clear bug.
> Lets do this... Please open up a upstream bz that justifies
> why the bindresvport was removed from svc_tli_create().
>=20
> If we break some legacy app I would like something to
> point to explaining why the change was made

I've opened a bug:

https://bugzilla.linux-nfs.org/show_bug.cgi?id=3D320


>> - The library should not be allowed to choose ports that
>> interfere with well-known services.
>>=20
>> - The library should choose service ports based on well-
>> established standards, such as the IANA service names to
>> port numbers standard.
>>=20
>>=20
>>>> =
https://www.iana.org/assignments/service-names-port-numbers/service-names-=
port-numbers.xhtml
>>> Hmm... I have been conveniently ignoring Thorsten's blacklist patch.
>>> Maybe we should take another look at that.
>>>=20
>>>>=20
>>>>=20
>>>>> So the following patch simply binds the socket
>>>>> before calling svc_tli_create() which means a
>>>>> non-privilege port will be reserved for remote
>>>>> calls.=20
>>>>>=20
>>>>> I'm thinking this is the simplest way to
>>>>> not pollute the privilege port space.=20
>>>>=20
>>>> This is going in the right direction, but the problem
>>>> needs to be addressed in svc_tli_create, not in each
>>>> application that calls svc_tli_create.
>>>>=20
>>>> This is the same issue that Guillem Jover was trying to
>>>> address by making bindresvport skip well-known ports.
>>>>=20
>>>> In other words: this code in src/svc_generic.c is wrong:
>>> It could be... but the API allows for the bindresvport (or any bind)=20=

>>> to not happen... So changing how it is called I think is=20
>>> appropriate... Plus its been working this way for a long to so=20
>>> I'm very resistant to change functionality basically for no reason.=20=

>>>=20
>>> But I do think we should look into bindresvport using a black list
>>> since it is already established in SuSE
>>=20
>> IMO a bindresvport blacklist is absolutely the wrong approach.
>> We have standards organizations that have explained exactly how
>> this needs to work, and we want it to work without installing
>> extra files or giving admins more knobs that they really don't
>> need.
>>=20
>> This is exactly the problem with distros applying patches
>> without upstream review. SuSE fixed this and let their fix sit
>> for years without any public bug report or review. IMO SuSE
>> should be prepared to take this hit, it should not constrain
>> upstream to choose a non-optimal long-term solution. I don't
>> see any compelling reason in this particular case that we need
>> to be constrained.
>>=20
>> Fixing svc_tli_create to use ports higher than 49151 should be
>> completely compatible with any reasonable blacklist, and it
>> MUST be compatible with /etc/services, which is based on the
>> IANA publication (no well-known fixed ports above 49151).
>>=20
> Let me look into this...=20
>=20
> steved.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" =
in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

--
Chuck Lever




2018-02-07 00:22:32

by Tom Talpey

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports

On 2/6/2018 1:36 PM, Chuck Lever wrote:
>
>
>> On Feb 6, 2018, at 1:22 PM, Tom Talpey <[email protected]> wrote:
>>
>> On 2/6/2018 12:34 PM, Chuck Lever wrote:
>>> mountd can and should use a dynamic port assignment, IMO.
>>> It doesn't have to use 20048.
>>
>> Speaking of 20048, does anyone know why Nico made this assignment?
>> Apart from making it well-known for firewalls, what system(s)
>> actually required it? I don't recall it ever being discussed.
>> Using it is certainly not required, since portmap resolves it.
>>
>> https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt
>>
>> ++ mountd 20048 tcp NFS mount protocol [Nicolas_Williams] [Nicolas_Williams] 2010-08-09
>> ++ mountd 20048 udp NFS mount protocol [Nicolas_Williams] [Nicolas_Williams] 2010-08-09
>
> Actually my first active interaction with the nfsv4 WG was at the
> IETF meeting in Montreal in late July of 2010. So I can't say that
> I have any memory of why this was done. It might be a question that
> can be answered by someone on [email protected].

Sure, or Nico directly. What I was wondering is why nfs-utils seems
to have implemented it? Surely there was a reason?

Tom.

2018-02-07 04:36:10

by NeilBrown

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports

On Mon, Feb 05 2018, Tom Talpey wrote:

> On 2/5/2018 12:02 PM, Chuck Lever wrote:
>> Heya Steve-
>>
>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> wrote:
>>>
>>> Over the weekend I did some experimenting with
>>> the remote call code in rpcbind. The code does
>>> functionally work but is very antiquated when
>>> it comes to the latest NFS versions.
>>>
>>> Since only UDP sockets are used to do remote calls
>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>> calls to NFS will fail (actual times out) since UDP is no
>>> longer supported.
>>>
>>> The undocumented interface rpc_call() can be used to
>>> call into NFS since the protocol can specified, which
>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>
>>> It turns out privilege port are not needed to make
>>> remote calls, at least with my testing.
>>
>> It's not quite clear what you are claiming here, but
>> I'm guessing that what you demonstrated is that the
>> CALLIT _listener_ does not have to be privileged?

rpcbind listens for CALLIT on port 111.
Listening on some other port wouldn't ever get the messges...


>>
>> I claim that is true for all RPC listeners.
>
>
> Why in the world is the remote-call interface even still supported?
> It is and was a mammoth security hole allowing machine impersonation,
> and to my knowledge no actual services or applications depends on
> it. Why not bury it under some compatibility option, default=off??

Is "ybind --broadcast" still used?
Even it is it, the port that rpcbind uses to forward the request doesn't
need to be privileged.

NeilBrown


>
> Tom.
>
>
>>
>>> I'm thinking
>>> the only reason privilege ports were being uses was
>>> a side effect of create_rmtcall_fd() calling
>>> svc_tli_create() with an unbound socket.
>>
>> Privileged listener ports are being created because
>> svc_tli_create is using bindresvport when the passed
>> in socket is not already bound.
>>
>> svc_tli_create should use bind instead, and it needs
>> to choose a port higher than 49151.
>>
>> https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
>>
>>
>>> So the following patch simply binds the socket
>>> before calling svc_tli_create() which means a
>>> non-privilege port will be reserved for remote
>>> calls.
>>>
>>> I'm thinking this is the simplest way to
>>> not pollute the privilege port space.
>>
>> This is going in the right direction, but the problem
>> needs to be addressed in svc_tli_create, not in each
>> application that calls svc_tli_create.
>>
>> This is the same issue that Guillem Jover was trying to
>> address by making bindresvport skip well-known ports.
>>
>> In other words: this code in src/svc_generic.c is wrong:
>>
>> 218 /*
>> 219 * If the fd is unbound, try to bind it.
>> 220 */
>> 221 if (madefd || !__rpc_sockisbound(fd)) {
>> 222 if (bindaddr == NULL) {
>> 223 if (bindresvport(fd, NULL) < 0) {
>> ^^^^^^^^^^^^
>>
>> 224 memset(&ss, 0, sizeof ss);
>> 225 ss.ss_family = si.si_af;
>> 226 if (bind(fd, (struct sockaddr *)(void *)&ss,
>> 227 (socklen_t)si.si_alen) < 0) {
>> 228 warnx(
>> 229 "svc_tli_create: could not bind to anonymous port");
>> 230 goto freedata;
>> 231 }
>> 232 }
>> 233 listen(fd, SOMAXCONN);
>> 234 } else {
>> 235 if (bind(fd,
>> 236 (struct sockaddr *)bindaddr->addr.buf,
>> 237 (socklen_t)si.si_alen) < 0) {
>> 238 warnx(
>> 239 "svc_tli_create: could not bind to requested address");
>> 240 goto freedata;
>> 241 }
>> 242 listen(fd, (int)bindaddr->qlen);
>> 243 }
>> 244
>> 245 }
>>
>>
>>> Steve Dickson (1):
>>> rmtcalls: Don't use privileged ports for remote calls.
>>>
>>> src/rpcb_svc_com.c | 19 ++++++++++++++++++-
>>> 1 file changed, 18 insertions(+), 1 deletion(-)
>>
>>
>> --
>> Chuck Lever
>>
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html


Attachments:
signature.asc (832.00 B)

2018-02-07 16:14:29

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports



> On Feb 6, 2018, at 11:35 PM, NeilBrown <[email protected]> wrote:
>=20
> On Mon, Feb 05 2018, Tom Talpey wrote:
>=20
>> On 2/5/2018 12:02 PM, Chuck Lever wrote:
>>> Heya Steve-
>>>=20
>>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> =
wrote:
>>>>=20
>>>> Over the weekend I did some experimenting with
>>>> the remote call code in rpcbind. The code does
>>>> functionally work but is very antiquated when
>>>> it comes to the latest NFS versions.
>>>>=20
>>>> Since only UDP sockets are used to do remote calls
>>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>>> calls to NFS will fail (actual times out) since UDP is no
>>>> longer supported.
>>>>=20
>>>> The undocumented interface rpc_call() can be used to
>>>> call into NFS since the protocol can specified, which
>>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>>=20
>>>> It turns out privilege port are not needed to make
>>>> remote calls, at least with my testing.
>>>=20
>>> It's not quite clear what you are claiming here, but
>>> I'm guessing that what you demonstrated is that the
>>> CALLIT _listener_ does not have to be privileged?
>=20
> rpcbind listens for CALLIT on port 111.

Right, my bad. CALLIT is an RPC procedure, not an RPC
program.


> Listening on some other port wouldn't ever get the messges...

Then we still do not understand why rpcbind is opening
and registering a second listener port. I can't think of
any reason it should do this other than that there is a
bug.


>>>=20
>>> I claim that is true for all RPC listeners.
>>=20
>>=20
>> Why in the world is the remote-call interface even still supported?
>> It is and was a mammoth security hole allowing machine impersonation,
>> and to my knowledge no actual services or applications depends on
>> it. Why not bury it under some compatibility option, default=3Doff??
>=20
> Is "ybind --broadcast" still used?
> Even it is it, the port that rpcbind uses to forward the request =
doesn't
> need to be privileged.
>=20
> NeilBrown
>=20
>=20
>>=20
>> Tom.
>>=20
>>=20
>>>=20
>>>> I'm thinking
>>>> the only reason privilege ports were being uses was
>>>> a side effect of create_rmtcall_fd() calling
>>>> svc_tli_create() with an unbound socket.
>>>=20
>>> Privileged listener ports are being created because
>>> svc_tli_create is using bindresvport when the passed
>>> in socket is not already bound.
>>>=20
>>> svc_tli_create should use bind instead, and it needs
>>> to choose a port higher than 49151.
>>>=20
>>> =
https://www.iana.org/assignments/service-names-port-numbers/service-names-=
port-numbers.xhtml
>>>=20
>>>=20
>>>> So the following patch simply binds the socket
>>>> before calling svc_tli_create() which means a
>>>> non-privilege port will be reserved for remote
>>>> calls.
>>>>=20
>>>> I'm thinking this is the simplest way to
>>>> not pollute the privilege port space.
>>>=20
>>> This is going in the right direction, but the problem
>>> needs to be addressed in svc_tli_create, not in each
>>> application that calls svc_tli_create.
>>>=20
>>> This is the same issue that Guillem Jover was trying to
>>> address by making bindresvport skip well-known ports.
>>>=20
>>> In other words: this code in src/svc_generic.c is wrong:
>>>=20
>>> 218 /*
>>> 219 * If the fd is unbound, try to bind it.
>>> 220 */
>>> 221 if (madefd || !__rpc_sockisbound(fd)) {
>>> 222 if (bindaddr =3D=3D NULL) {
>>> 223 if (bindresvport(fd, NULL) < 0) {
>>> ^^^^^^^^^^^^
>>>=20
>>> 224 memset(&ss, 0, sizeof ss);
>>> 225 ss.ss_family =3D si.si_af;
>>> 226 if (bind(fd, (struct sockaddr =
*)(void *)&ss,
>>> 227 (socklen_t)si.si_alen) < 0) =
{
>>> 228 warnx(
>>> 229 "svc_tli_create: could not bind to =
anonymous port");
>>> 230 goto freedata;
>>> 231 }
>>> 232 }
>>> 233 listen(fd, SOMAXCONN);
>>> 234 } else {
>>> 235 if (bind(fd,
>>> 236 (struct sockaddr =
*)bindaddr->addr.buf,
>>> 237 (socklen_t)si.si_alen) < 0) {
>>> 238 warnx(
>>> 239 "svc_tli_create: could not bind to requested =
address");
>>> 240 goto freedata;
>>> 241 }
>>> 242 listen(fd, (int)bindaddr->qlen);
>>> 243 }
>>> 244
>>> 245 }
>>>=20
>>>=20
>>>> Steve Dickson (1):
>>>> rmtcalls: Don't use privileged ports for remote calls.
>>>>=20
>>>> src/rpcb_svc_com.c | 19 ++++++++++++++++++-
>>>> 1 file changed, 18 insertions(+), 1 deletion(-)
>>>=20
>>>=20
>>> --
>>> Chuck Lever
>>>=20
>>>=20
>>>=20
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" =
in
>>> the body of a message to [email protected]
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>>=20
>>>=20
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" =
in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html

--
Chuck Lever




2018-02-07 21:16:42

by NeilBrown

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports

On Wed, Feb 07 2018, Chuck Lever wrote:

>> On Feb 6, 2018, at 11:35 PM, NeilBrown <[email protected]> wrote:
>>
>> On Mon, Feb 05 2018, Tom Talpey wrote:
>>
>>> On 2/5/2018 12:02 PM, Chuck Lever wrote:
>>>> Heya Steve-
>>>>
>>>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> wrote:
>>>>>
>>>>> Over the weekend I did some experimenting with
>>>>> the remote call code in rpcbind. The code does
>>>>> functionally work but is very antiquated when
>>>>> it comes to the latest NFS versions.
>>>>>
>>>>> Since only UDP sockets are used to do remote calls
>>>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>>>> calls to NFS will fail (actual times out) since UDP is no
>>>>> longer supported.
>>>>>
>>>>> The undocumented interface rpc_call() can be used to
>>>>> call into NFS since the protocol can specified, which
>>>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>>>
>>>>> It turns out privilege port are not needed to make
>>>>> remote calls, at least with my testing.
>>>>
>>>> It's not quite clear what you are claiming here, but
>>>> I'm guessing that what you demonstrated is that the
>>>> CALLIT _listener_ does not have to be privileged?
>>
>> rpcbind listens for CALLIT on port 111.
>
> Right, my bad. CALLIT is an RPC procedure, not an RPC
> program.
>
>
>> Listening on some other port wouldn't ever get the messges...
>
> Then we still do not understand why rpcbind is opening
> and registering a second listener port. I can't think of
> any reason it should do this other than that there is a
> bug.

This is a port on which it forwards CALLIT messages and listens for
replies, which it then sends back to the originator. In order to be
able to handle CALLIT asynchronously with other requests, it needs to
register the port with the internal listening framework.
For comparison, portmap handles CALLIT asynchronously by forking.

Thanks,
NeilBrown


Attachments:
signature.asc (832.00 B)

2018-02-07 21:24:04

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports



> On Feb 7, 2018, at 4:16 PM, NeilBrown <[email protected]> wrote:
>
> On Wed, Feb 07 2018, Chuck Lever wrote:
>
>>> On Feb 6, 2018, at 11:35 PM, NeilBrown <[email protected]> wrote:
>>>
>>> On Mon, Feb 05 2018, Tom Talpey wrote:
>>>
>>>> On 2/5/2018 12:02 PM, Chuck Lever wrote:
>>>>> Heya Steve-
>>>>>
>>>>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> wrote:
>>>>>>
>>>>>> Over the weekend I did some experimenting with
>>>>>> the remote call code in rpcbind. The code does
>>>>>> functionally work but is very antiquated when
>>>>>> it comes to the latest NFS versions.
>>>>>>
>>>>>> Since only UDP sockets are used to do remote calls
>>>>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>>>>> calls to NFS will fail (actual times out) since UDP is no
>>>>>> longer supported.
>>>>>>
>>>>>> The undocumented interface rpc_call() can be used to
>>>>>> call into NFS since the protocol can specified, which
>>>>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>>>>
>>>>>> It turns out privilege port are not needed to make
>>>>>> remote calls, at least with my testing.
>>>>>
>>>>> It's not quite clear what you are claiming here, but
>>>>> I'm guessing that what you demonstrated is that the
>>>>> CALLIT _listener_ does not have to be privileged?
>>>
>>> rpcbind listens for CALLIT on port 111.
>>
>> Right, my bad. CALLIT is an RPC procedure, not an RPC
>> program.
>>
>>
>>> Listening on some other port wouldn't ever get the messges...
>>
>> Then we still do not understand why rpcbind is opening
>> and registering a second listener port. I can't think of
>> any reason it should do this other than that there is a
>> bug.
>
> This is a port on which it forwards CALLIT messages and listens for
> replies, which it then sends back to the originator. In order to be
> able to handle CALLIT asynchronously with other requests, it needs to
> register the port with the internal listening framework.

Sorry, this is still not making sense to me. Can you create a
ladder diagram that shows the exchange of Call and Reply messages?


> For comparison, portmap handles CALLIT asynchronously by forking.
>
> Thanks,
> NeilBrown

--
Chuck Lever




2018-02-07 23:16:40

by NeilBrown

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports

On Wed, Feb 07 2018, Chuck Lever wrote:

>> On Feb 7, 2018, at 4:16 PM, NeilBrown <[email protected]> wrote:
>>
>> On Wed, Feb 07 2018, Chuck Lever wrote:
>>
>>>> On Feb 6, 2018, at 11:35 PM, NeilBrown <[email protected]> wrote:
>>>>
>>>> On Mon, Feb 05 2018, Tom Talpey wrote:
>>>>
>>>>> On 2/5/2018 12:02 PM, Chuck Lever wrote:
>>>>>> Heya Steve-
>>>>>>
>>>>>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> wrote:
>>>>>>>
>>>>>>> Over the weekend I did some experimenting with
>>>>>>> the remote call code in rpcbind. The code does
>>>>>>> functionally work but is very antiquated when
>>>>>>> it comes to the latest NFS versions.
>>>>>>>
>>>>>>> Since only UDP sockets are used to do remote calls
>>>>>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>>>>>> calls to NFS will fail (actual times out) since UDP is no
>>>>>>> longer supported.
>>>>>>>
>>>>>>> The undocumented interface rpc_call() can be used to
>>>>>>> call into NFS since the protocol can specified, which
>>>>>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>>>>>
>>>>>>> It turns out privilege port are not needed to make
>>>>>>> remote calls, at least with my testing.
>>>>>>
>>>>>> It's not quite clear what you are claiming here, but
>>>>>> I'm guessing that what you demonstrated is that the
>>>>>> CALLIT _listener_ does not have to be privileged?
>>>>
>>>> rpcbind listens for CALLIT on port 111.
>>>
>>> Right, my bad. CALLIT is an RPC procedure, not an RPC
>>> program.
>>>
>>>
>>>> Listening on some other port wouldn't ever get the messges...
>>>
>>> Then we still do not understand why rpcbind is opening
>>> and registering a second listener port. I can't think of
>>> any reason it should do this other than that there is a
>>> bug.
>>
>> This is a port on which it forwards CALLIT messages and listens for
>> replies, which it then sends back to the originator. In order to be
>> able to handle CALLIT asynchronously with other requests, it needs to
>> register the port with the internal listening framework.
>
> Sorry, this is still not making sense to me. Can you create a
> ladder diagram that shows the exchange of Call and Reply messages?

Firstly, portmap binds 2 sockets (ignoring tcp for now), one on port 111
and one on an ephemeral port (EP). It registers both of these internally so
incoming packets get noticed.
If it receives SET or UNSET or GETADDR etc on 111, it replies directly.
CALLIT is a bit more complete.

remote-client rpcbind local-service
111
send CALLIT(XX) ------>rpcbproc_callit_com() EP
unwrap/send XX ----------------->handle
EP
111 handle_reply()<----------------send reply
receive reply<-------wrap-and-send


does that help? The callit request/reply to/from port 111 has
some other request/reply embeded in it.
This embedded request/reply is sent/received unwrapped on the ephemeral
port.

NeilBrown



>
>> For comparison, portmap handles CALLIT asynchronously by forking.
>>
>> Thanks,
>> NeilBrown
>
> --
> Chuck Lever


Attachments:
signature.asc (832.00 B)

2018-02-08 00:13:44

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports



> On Feb 7, 2018, at 6:16 PM, NeilBrown <[email protected]> wrote:
>=20
> On Wed, Feb 07 2018, Chuck Lever wrote:
>=20
>>> On Feb 7, 2018, at 4:16 PM, NeilBrown <[email protected]> wrote:
>>>=20
>>> On Wed, Feb 07 2018, Chuck Lever wrote:
>>>=20
>>>>> On Feb 6, 2018, at 11:35 PM, NeilBrown <[email protected]> wrote:
>>>>>=20
>>>>> On Mon, Feb 05 2018, Tom Talpey wrote:
>>>>>=20
>>>>>> On 2/5/2018 12:02 PM, Chuck Lever wrote:
>>>>>>> Heya Steve-
>>>>>>>=20
>>>>>>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> =
wrote:
>>>>>>>>=20
>>>>>>>> Over the weekend I did some experimenting with
>>>>>>>> the remote call code in rpcbind. The code does
>>>>>>>> functionally work but is very antiquated when
>>>>>>>> it comes to the latest NFS versions.
>>>>>>>>=20
>>>>>>>> Since only UDP sockets are used to do remote calls
>>>>>>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>>>>>>> calls to NFS will fail (actual times out) since UDP is no
>>>>>>>> longer supported.
>>>>>>>>=20
>>>>>>>> The undocumented interface rpc_call() can be used to
>>>>>>>> call into NFS since the protocol can specified, which
>>>>>>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>>>>>>=20
>>>>>>>> It turns out privilege port are not needed to make
>>>>>>>> remote calls, at least with my testing.
>>>>>>>=20
>>>>>>> It's not quite clear what you are claiming here, but
>>>>>>> I'm guessing that what you demonstrated is that the
>>>>>>> CALLIT _listener_ does not have to be privileged?
>>>>>=20
>>>>> rpcbind listens for CALLIT on port 111.
>>>>=20
>>>> Right, my bad. CALLIT is an RPC procedure, not an RPC
>>>> program.
>>>>=20
>>>>=20
>>>>> Listening on some other port wouldn't ever get the messges...
>>>>=20
>>>> Then we still do not understand why rpcbind is opening
>>>> and registering a second listener port. I can't think of
>>>> any reason it should do this other than that there is a
>>>> bug.
>>>=20
>>> This is a port on which it forwards CALLIT messages and listens for
>>> replies, which it then sends back to the originator. In order to be
>>> able to handle CALLIT asynchronously with other requests, it needs =
to
>>> register the port with the internal listening framework.
>>=20
>> Sorry, this is still not making sense to me. Can you create a
>> ladder diagram that shows the exchange of Call and Reply messages?
>=20
> Firstly, portmap binds 2 sockets (ignoring tcp for now), one on port =
111
> and one on an ephemeral port (EP). It registers both of these =
internally so
> incoming packets get noticed.

So we have:

1 listener bound to 111. This is the main rpcbind service, and it
is "registered" with the rpcbind service so that it is advertised
to other RPC clients.

1 ephemeral port bound to N. This is an RPC client. This socket
should be completely invisible to remote systems; ie. it is not
"registered" with the rpcbind service, it is not a passive listener.

I don't understand what you mean by "registers both of these
internally."

What was reported (in another email thread) is that there appears
to be a second rpcbind registration on another port visible in the
rpcinfo listing. I'm trying to understand what that port is for
(and secondarily why it is using a port < 1024).

https://marc.info/?l=3Dlinux-nfs&m=3D151705744428289&w=3D2

I still don't see the point of the listener on port 831. I don't
expect that ephemeral "client" socket to be visible in the rpcinfo
listing, for example.


> If it receives SET or UNSET or GETADDR etc on 111, it replies =
directly.
> CALLIT is a bit more complete.
>=20
> remote-client rpcbind local-service
> 111
> send CALLIT(XX) ------>rpcbproc_callit_com() EP
> unwrap/send XX ----------------->handle
> EP
> 111 handle_reply()<----------------send reply
> receive reply<-------wrap-and-send
>=20
>=20
> does that help? The callit request/reply to/from port 111 has
> some other request/reply embeded in it.
> This embedded request/reply is sent/received unwrapped on the =
ephemeral
> port.

That aligns with my understanding of how CALLIT works. The second
socket is not a listener, as I understand it, unless you're
suggesting that rpcbind sets up the second socket as a listener
to receive only replies to forwarded CALLIT requests?

The bug, then, would be that the second socket shouldn't be
registered with the official rpcbind service, so that it will not
be displayed in rpcinfo output.

Clients have "port 111" nailed in as the portmapper, so I can't
see what use a second rpcbind registration would provide.


> NeilBrown
>=20
>=20
>=20
>>=20
>>> For comparison, portmap handles CALLIT asynchronously by forking.
>>>=20
>>> Thanks,
>>> NeilBrown
>>=20
>> --
>> Chuck Lever

--
Chuck Lever




2018-02-08 00:45:09

by NeilBrown

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports

On Wed, Feb 07 2018, Chuck Lever wrote:

>> On Feb 7, 2018, at 6:16 PM, NeilBrown <[email protected]> wrote:
>>
>> On Wed, Feb 07 2018, Chuck Lever wrote:
>>
>>>> On Feb 7, 2018, at 4:16 PM, NeilBrown <[email protected]> wrote:
>>>>
>>>> On Wed, Feb 07 2018, Chuck Lever wrote:
>>>>
>>>>>> On Feb 6, 2018, at 11:35 PM, NeilBrown <[email protected]> wrote:
>>>>>>
>>>>>> On Mon, Feb 05 2018, Tom Talpey wrote:
>>>>>>
>>>>>>> On 2/5/2018 12:02 PM, Chuck Lever wrote:
>>>>>>>> Heya Steve-
>>>>>>>>
>>>>>>>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson <[email protected]> wrote:
>>>>>>>>>
>>>>>>>>> Over the weekend I did some experimenting with
>>>>>>>>> the remote call code in rpcbind. The code does
>>>>>>>>> functionally work but is very antiquated when
>>>>>>>>> it comes to the latest NFS versions.
>>>>>>>>>
>>>>>>>>> Since only UDP sockets are used to do remote calls
>>>>>>>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>>>>>>>> calls to NFS will fail (actual times out) since UDP is no
>>>>>>>>> longer supported.
>>>>>>>>>
>>>>>>>>> The undocumented interface rpc_call() can be used to
>>>>>>>>> call into NFS since the protocol can specified, which
>>>>>>>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>>>>>>>
>>>>>>>>> It turns out privilege port are not needed to make
>>>>>>>>> remote calls, at least with my testing.
>>>>>>>>
>>>>>>>> It's not quite clear what you are claiming here, but
>>>>>>>> I'm guessing that what you demonstrated is that the
>>>>>>>> CALLIT _listener_ does not have to be privileged?
>>>>>>
>>>>>> rpcbind listens for CALLIT on port 111.
>>>>>
>>>>> Right, my bad. CALLIT is an RPC procedure, not an RPC
>>>>> program.
>>>>>
>>>>>
>>>>>> Listening on some other port wouldn't ever get the messges...
>>>>>
>>>>> Then we still do not understand why rpcbind is opening
>>>>> and registering a second listener port. I can't think of
>>>>> any reason it should do this other than that there is a
>>>>> bug.
>>>>
>>>> This is a port on which it forwards CALLIT messages and listens for
>>>> replies, which it then sends back to the originator. In order to be
>>>> able to handle CALLIT asynchronously with other requests, it needs to
>>>> register the port with the internal listening framework.
>>>
>>> Sorry, this is still not making sense to me. Can you create a
>>> ladder diagram that shows the exchange of Call and Reply messages?
>>
>> Firstly, portmap binds 2 sockets (ignoring tcp for now), one on port 111
>> and one on an ephemeral port (EP). It registers both of these internally so
>> incoming packets get noticed.
>
> So we have:
>
> 1 listener bound to 111. This is the main rpcbind service, and it
> is "registered" with the rpcbind service so that it is advertised
> to other RPC clients.
>
> 1 ephemeral port bound to N. This is an RPC client. This socket
> should be completely invisible to remote systems; ie. it is not
> "registered" with the rpcbind service, it is not a passive listener.
>
> I don't understand what you mean by "registers both of these
> internally."

Maybe we are using the word "register" a bit differently because .....

>
> What was reported (in another email thread) is that there appears
> to be a second rpcbind registration on another port visible in the
> rpcinfo listing. I'm trying to understand what that port is for
> (and secondarily why it is using a port < 1024).

.... I can see no evidence of what you say.

>
> https://marc.info/?l=linux-nfs&m=151705744428289&w=2

the "listing" is this email message is *not* an rpcinfo listing.
"rpcinfo" is not mentioned in the email.
The listing results "when I do netstat".

If I run
netstat -uanp | grep rpcbind

I see a very similar listing, though only of the non-111 port (702 on my
desktop).
The 111 port is attributed to systemd, which is expected when rpcbind
was started by systemd's socket-activation.

Thanks,
NeilBrown


Attachments:
signature.asc (832.00 B)

2018-02-08 00:46:41

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 0/1] Remote calls don't need to use privilege ports



> On Feb 7, 2018, at 7:45 PM, NeilBrown <[email protected]> wrote:
>=20
> On Wed, Feb 07 2018, Chuck Lever wrote:
>=20
>>> On Feb 7, 2018, at 6:16 PM, NeilBrown <[email protected]> wrote:
>>>=20
>>> On Wed, Feb 07 2018, Chuck Lever wrote:
>>>=20
>>>>> On Feb 7, 2018, at 4:16 PM, NeilBrown <[email protected]> wrote:
>>>>>=20
>>>>> On Wed, Feb 07 2018, Chuck Lever wrote:
>>>>>=20
>>>>>>> On Feb 6, 2018, at 11:35 PM, NeilBrown <[email protected]> wrote:
>>>>>>>=20
>>>>>>> On Mon, Feb 05 2018, Tom Talpey wrote:
>>>>>>>=20
>>>>>>>> On 2/5/2018 12:02 PM, Chuck Lever wrote:
>>>>>>>>> Heya Steve-
>>>>>>>>>=20
>>>>>>>>>> On Feb 5, 2018, at 11:36 AM, Steve Dickson =
<[email protected]> wrote:
>>>>>>>>>>=20
>>>>>>>>>> Over the weekend I did some experimenting with
>>>>>>>>>> the remote call code in rpcbind. The code does
>>>>>>>>>> functionally work but is very antiquated when
>>>>>>>>>> it comes to the latest NFS versions.
>>>>>>>>>>=20
>>>>>>>>>> Since only UDP sockets are used to do remote calls
>>>>>>>>>> using the documented interfaces pmap_rmtcall() and callrpc()
>>>>>>>>>> calls to NFS will fail (actual times out) since UDP is no
>>>>>>>>>> longer supported.
>>>>>>>>>>=20
>>>>>>>>>> The undocumented interface rpc_call() can be used to
>>>>>>>>>> call into NFS since the protocol can specified, which
>>>>>>>>>> also means the PMAPPROC_CALLIT protocol is not used.
>>>>>>>>>>=20
>>>>>>>>>> It turns out privilege port are not needed to make
>>>>>>>>>> remote calls, at least with my testing.
>>>>>>>>>=20
>>>>>>>>> It's not quite clear what you are claiming here, but
>>>>>>>>> I'm guessing that what you demonstrated is that the
>>>>>>>>> CALLIT _listener_ does not have to be privileged?
>>>>>>>=20
>>>>>>> rpcbind listens for CALLIT on port 111.
>>>>>>=20
>>>>>> Right, my bad. CALLIT is an RPC procedure, not an RPC
>>>>>> program.
>>>>>>=20
>>>>>>=20
>>>>>>> Listening on some other port wouldn't ever get the messges...
>>>>>>=20
>>>>>> Then we still do not understand why rpcbind is opening
>>>>>> and registering a second listener port. I can't think of
>>>>>> any reason it should do this other than that there is a
>>>>>> bug.
>>>>>=20
>>>>> This is a port on which it forwards CALLIT messages and listens =
for
>>>>> replies, which it then sends back to the originator. In order to =
be
>>>>> able to handle CALLIT asynchronously with other requests, it needs =
to
>>>>> register the port with the internal listening framework.
>>>>=20
>>>> Sorry, this is still not making sense to me. Can you create a
>>>> ladder diagram that shows the exchange of Call and Reply messages?
>>>=20
>>> Firstly, portmap binds 2 sockets (ignoring tcp for now), one on port =
111
>>> and one on an ephemeral port (EP). It registers both of these =
internally so
>>> incoming packets get noticed.
>>=20
>> So we have:
>>=20
>> 1 listener bound to 111. This is the main rpcbind service, and it
>> is "registered" with the rpcbind service so that it is advertised
>> to other RPC clients.
>>=20
>> 1 ephemeral port bound to N. This is an RPC client. This socket
>> should be completely invisible to remote systems; ie. it is not
>> "registered" with the rpcbind service, it is not a passive listener.
>>=20
>> I don't understand what you mean by "registers both of these
>> internally."
>=20
> Maybe we are using the word "register" a bit differently because .....
>=20
>>=20
>> What was reported (in another email thread) is that there appears
>> to be a second rpcbind registration on another port visible in the
>> rpcinfo listing. I'm trying to understand what that port is for
>> (and secondarily why it is using a port < 1024).
>=20
> .... I can see no evidence of what you say.
>=20
>>=20
>> https://marc.info/?l=3Dlinux-nfs&m=3D151705744428289&w=3D2
>=20
> the "listing" is this email message is *not* an rpcinfo listing.
> "rpcinfo" is not mentioned in the email.
> The listing results "when I do netstat".
>=20
> If I run
> netstat -uanp | grep rpcbind
>=20
> I see a very similar listing, though only of the non-111 port (702 on =
my
> desktop).
> The 111 port is attributed to systemd, which is expected when rpcbind
> was started by systemd's socket-activation.

The clouds are lifted. Thanks.


--
Chuck Lever