Re: [PATCH] Do not bind to reserved ports registered in /etc/services

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> On Jan 9, 2018, at 7:49 PM, Guillem Jover <gjover@xxxxxxxxxxx> wrote:
> 
> When using the bindresvport() function a privileged port will be looked
> for and bound to a socket. The problem is that any service using a static
> privileged port registered in the /etc/services file, can get its port
> taken over by libtirpc users, making the other service fail to start.
> 
> Starting the other service before libtircp users is not an option as
> this does not cover restart situations, for example during package
> upgrades or HA switchovers and similar.
> 
> In addition honoring the /etc/services registry is already done for
> example by rpc.statd, so it seems obvious to make libtirpc follow this
> same pattern too.

Does the glibc version of bindresvport(3) skip ports? I ask because
this hasn't been a noted problem before. Which service exactly is
causing the difficulty?

Usually applications that grab a privileged port are short-lived.
statd is careful to avoid ports in /etc/services because it allocates
one socket with a privileged port for contacting the kernel, and keeps
it in place.


> Signed-off-by: Guillem Jover <gjover@xxxxxxxxxxx>
> ---
> src/bindresvport.c | 28 +++++++++++++++++++++++++++-
> 1 file changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/src/bindresvport.c b/src/bindresvport.c
> index 2d8f2bc..98e5f40 100644
> --- a/src/bindresvport.c
> +++ b/src/bindresvport.c
> @@ -40,6 +40,7 @@
> #include <netinet/in.h>
> 
> #include <errno.h>
> +#include <netdb.h>
> #include <string.h>
> #include <unistd.h>
> 
> @@ -73,12 +74,15 @@ bindresvport_sa(sd, sa)
>         int sd;
>         struct sockaddr *sa;
> {
> -        int res, af;
> +        int res, af, so_proto;
> +        socklen_t so_proto_len;
>         struct sockaddr_storage myaddr;
> 	struct sockaddr_in *sin;
> #ifdef INET6
> 	struct sockaddr_in6 *sin6;
> #endif
> +	struct servent *se;
> +	const char *se_proto;
> 	u_int16_t *portp;
> 	static u_int16_t port;
> 	static short startport = STARTPORT;
> @@ -125,6 +129,25 @@ bindresvport_sa(sd, sa)
>         }
>         sa->sa_family = af;
> 
> +        so_proto_len = sizeof(so_proto);
> +        if (getsockopt(sd, SOL_SOCKET, SO_PROTOCOL, &so_proto, &so_proto_len) == -1) {
> +                mutex_unlock(&port_lock);
> +                return -1;      /* errno is correctly set */
> +        }
> +        switch (so_proto) {
> +        case IPPROTO_UDP:
> +        case IPPROTO_UDPLITE:

What is UDPLITE? Would it require a separate netid
or other infrastructure? IMO it's not correct to add
this transport protocol in this patch. If you resend,
please remove this line.


> +                se_proto = "udp";
> +                break;
> +        case IPPROTO_TCP:
> +                se_proto = "tcp";
> +                break;
> +        default:
> +                errno = ENOPROTOOPT;
> +                mutex_unlock(&port_lock);
> +                return -1;
> +        }
> +
>         if (port == 0) {
>                 port = (getpid() % NPORTS) + STARTPORT;
>         }
> @@ -135,6 +158,9 @@ bindresvport_sa(sd, sa)
>                 *portp = htons(port++);
>                  if (port > endport) 
>                         port = startport;
> +                se = getservbyport(*portp, se_proto);
> +                if (se != NULL)
> +                        continue;
>                 res = bind(sd, sa, salen);
> 		if (res >= 0 || errno != EADDRINUSE)
> 	                break;
> -- 
> 2.15.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
Chuck Lever



--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux