On 10/27/20 7:07 AM, jma...@redhat.com wrote:
> From: Jon Maloy <jma...@redhat.com>
> 
> TIPC reserves 64 service types for current and future internal use.
> Therefore, the bind() function is meant to block regular user sockets
> from being bound to these values, while it should let through such
> bindings from internal users.
> 
> However, since we at the design moment saw no way to distinguish
> between regular and internal users the filter function ended up
> with allowing all bindings of the reserved types which were really
> in use ([0,1]), and block all the rest ([2,63]).
> 
> This is risky, since a regular user may bind to the service type
> representing the topology server (TIPC_TOP_SRV == 1) or the one used
> for indicating neigboring node status (TIPC_CFG_SRV == 0), and wreak
> havoc for users of those services, i.e., most users.
> 
> The reality is however that TIPC_CFG_SRV never is bound through the
> bind() function, since it doesn't represent a regular socket, and
> TIPC_TOP_SRV can also be made to bypass the checks in tipc_bind()
> by introducing a different entry function, tipc_sk_bind().
> 
> It should be noted that, although this is a change of the API semantics,
> there is no risk we will break any currently working applications by
> doing this. Any application trying to bind to the values in question
> would be badly broken from the outset, so there is no chance we would
> find any such applications in real-world production systems.
> 
> Signed-off-by: Jon Maloy <jma...@redhat.com>

Acked-by: Ying Xue <ying....@windriver.com>

> ---
>  net/tipc/socket.c | 24 +++++++++++++++---------
>  net/tipc/socket.h |  2 +-
>  net/tipc/topsrv.c |  4 ++--
>  3 files changed, 18 insertions(+), 12 deletions(-)
> 
> diff --git a/net/tipc/socket.c b/net/tipc/socket.c
> index e795a8a2955b..222fd53da2d0 100644
> --- a/net/tipc/socket.c
> +++ b/net/tipc/socket.c
> @@ -658,8 +658,8 @@ static int tipc_release(struct socket *sock)
>   * NOTE: This routine doesn't need to take the socket lock since it doesn't
>   *       access any non-constant socket information.
>   */
> -static int tipc_bind(struct socket *sock, struct sockaddr *uaddr,
> -                  int uaddr_len)
> +
> +int tipc_sk_bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
>  {
>       struct sock *sk = sock->sk;
>       struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
> @@ -691,13 +691,6 @@ static int tipc_bind(struct socket *sock, struct 
> sockaddr *uaddr,
>               goto exit;
>       }
>  
> -     if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) &&
> -         (addr->addr.nameseq.type != TIPC_TOP_SRV) &&
> -         (addr->addr.nameseq.type != TIPC_CFG_SRV)) {
> -             res = -EACCES;
> -             goto exit;
> -     }
> -
>       res = (addr->scope >= 0) ?
>               tipc_sk_publish(tsk, addr->scope, &addr->addr.nameseq) :
>               tipc_sk_withdraw(tsk, -addr->scope, &addr->addr.nameseq);
> @@ -706,6 +699,19 @@ static int tipc_bind(struct socket *sock, struct 
> sockaddr *uaddr,
>       return res;
>  }
>  
> +static int tipc_bind(struct socket *sock, struct sockaddr *skaddr, int alen)
> +{
> +     struct sockaddr_tipc *addr = (struct sockaddr_tipc *)skaddr;
> +
> +     if (alen) {
> +             if (alen < sizeof(struct sockaddr_tipc))
> +                     return -EINVAL;
> +             if (addr->addr.nameseq.type < TIPC_RESERVED_TYPES)
> +                     return -EACCES;
> +     }
> +     return tipc_sk_bind(sock, skaddr, alen);
> +}
> +
>  /**
>   * tipc_getname - get port ID of socket or peer socket
>   * @sock: socket structure
> diff --git a/net/tipc/socket.h b/net/tipc/socket.h
> index b11575afc66f..02cdf166807d 100644
> --- a/net/tipc/socket.h
> +++ b/net/tipc/socket.h
> @@ -74,7 +74,7 @@ int tipc_dump_done(struct netlink_callback *cb);
>  u32 tipc_sock_get_portid(struct sock *sk);
>  bool tipc_sk_overlimit1(struct sock *sk, struct sk_buff *skb);
>  bool tipc_sk_overlimit2(struct sock *sk, struct sk_buff *skb);
> -
> +int tipc_sk_bind(struct socket *sock, struct sockaddr *skaddr, int alen);
>  int tsk_set_importance(struct sock *sk, int imp);
>  
>  #endif
> diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
> index 5f6f86051c83..cec029349662 100644
> --- a/net/tipc/topsrv.c
> +++ b/net/tipc/topsrv.c
> @@ -520,12 +520,12 @@ static int tipc_topsrv_create_listener(struct 
> tipc_topsrv *srv)
>  
>       saddr.family                    = AF_TIPC;
>       saddr.addrtype                  = TIPC_ADDR_NAMESEQ;
> -     saddr.addr.nameseq.type         = TIPC_TOP_SRV;
> +     saddr.addr.nameseq.type         = TIPC_TOP_SRV;
>       saddr.addr.nameseq.lower        = TIPC_TOP_SRV;
>       saddr.addr.nameseq.upper        = TIPC_TOP_SRV;
>       saddr.scope                     = TIPC_NODE_SCOPE;
>  
> -     rc = kernel_bind(lsock, (struct sockaddr *)&saddr, sizeof(saddr));
> +     rc = tipc_sk_bind(lsock, (struct sockaddr *)&saddr, sizeof(saddr));
>       if (rc < 0)
>               goto err;
>       rc = kernel_listen(lsock, 0);
> 


_______________________________________________
tipc-discussion mailing list
tipc-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

Reply via email to