From 233bd085ca6fcd464caab911696abc3494255f5f Mon Sep 17 00:00:00 2001 From: Ralph Castain Date: Fri, 12 Feb 2016 08:09:15 -0800 Subject: [PATCH] Protect against a non-privileged port connecting to us when we are running as root Don't close the listener socket upon error unless we are giving up Cleanup the incoming socket --- orte/mca/oob/tcp/help-oob-tcp.txt | 14 +++++++++-- orte/mca/oob/tcp/oob_tcp_listener.c | 36 +++++++++++++++++++++++++---- orte/mca/oob/tcp/oob_tcp_listener.h | 2 ++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/orte/mca/oob/tcp/help-oob-tcp.txt b/orte/mca/oob/tcp/help-oob-tcp.txt index d20ea17e1b..6dc3ed9c8f 100644 --- a/orte/mca/oob/tcp/help-oob-tcp.txt +++ b/orte/mca/oob/tcp/help-oob-tcp.txt @@ -10,8 +10,8 @@ # University of Stuttgart. All rights reserved. # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. -# Copyright (c) 2014-2015 Intel, Inc. All rights reserved. -# Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2014-2016 Intel, Inc. All rights reserved. +# Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow @@ -96,3 +96,13 @@ eventually timeout / abort. Errno: %d (%s) Probable cause: %s # +[privilege failure] +An attempt was made to initiate a TCP connection from an +unprivileged source while we are operating at privileged +levels. + + Local host: %s + Inbound port: %d + Listening port: %d + +The connection was rejected. diff --git a/orte/mca/oob/tcp/oob_tcp_listener.c b/orte/mca/oob/tcp/oob_tcp_listener.c index a926dd3cdd..535e3823a1 100644 --- a/orte/mca/oob/tcp/oob_tcp_listener.c +++ b/orte/mca/oob/tcp/oob_tcp_listener.c @@ -13,7 +13,7 @@ * All rights reserved. * Copyright (c) 2009-2015 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved. - * Copyright (c) 2013-2014 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ @@ -384,6 +384,7 @@ static int create_listen(void) /* add this port to our connections */ conn = OBJ_NEW(mca_oob_tcp_listener_t); conn->sd = sd; + conn->port = ntohs(((struct sockaddr_in*) &inaddr)->sin_port); opal_list_append(&mca_oob_tcp_component.listeners, &conn->item); /* and to our ports */ asprintf(&tconn, "%d", ntohs(((struct sockaddr_in*) &inaddr)->sin_port)); @@ -621,7 +622,9 @@ static int create_listen6(void) /* add this port to our connections */ conn = OBJ_NEW(mca_oob_tcp_listener_t); + conn->tcp6 = true; conn->sd = sd; + conn->port = ntohs(((struct sockaddr_in6*) &inaddr)->sin6_port); opal_list_append(&mca_oob_tcp_component.listeners, &conn->item); /* and to our ports */ asprintf(&tconn, "%d", ntohs(((struct sockaddr_in6*) &inaddr)->sin6_port)); @@ -739,8 +742,32 @@ static void* listen_thread(opal_object_t *obj) pending_connection->fd = accept(sd, (struct sockaddr*)&(pending_connection->addr), &addrlen); + + /* if we are on a privileged port, we only accept connections + * from other privileged sockets. A privileged port is one + * whose port is less than 1024 on Linux, so we'll check for that. */ + if (1024 >= listener->port) { + uint16_t inport; + if (listener->tcp6) { + inport = ntohs(((struct sockaddr_in6*)&pending_connection->addr)->sin6_port); + } else { + inport = ntohs(((struct sockaddr_in*)&pending_connection->addr)->sin_port); + } + if (1024 < inport) { + /* someone tried to cross-connect privileges, + * say something */ + orte_show_help("help-oob-tcp.txt", + "privilege failure", + true, opal_process_info.nodename, + listener->port, inport); + CLOSE_THE_SOCKET(pending_connection->fd); + OBJ_RELEASE(pending_connection); + continue; + } + } + /* check for < 0 as indicating an error upon accept */ if (pending_connection->fd < 0) { - OBJ_RELEASE(pending_connection); + OBJ_RELEASE(pending_connection); // this closes the incoming fd /* Non-fatal errors */ if (EAGAIN == opal_socket_errno || @@ -764,10 +791,9 @@ static void* listen_thread(opal_object_t *obj) goto done; } - /* For all other cases, close the socket, print a + /* For all other cases, print a warning but try to continue */ else { - CLOSE_THE_SOCKET(sd); orte_show_help("help-oob-tcp.txt", "accept failed", true, @@ -909,7 +935,9 @@ static void connection_event_handler(int incoming_sd, short flags, void* cbdata) static void tcp_ev_cons(mca_oob_tcp_listener_t* event) { event->ev_active = false; + event->tcp6 = false; event->sd = -1; + event->port = 0; } static void tcp_ev_des(mca_oob_tcp_listener_t* event) { diff --git a/orte/mca/oob/tcp/oob_tcp_listener.h b/orte/mca/oob/tcp/oob_tcp_listener.h index fe039e5721..5f8bbd2094 100644 --- a/orte/mca/oob/tcp/oob_tcp_listener.h +++ b/orte/mca/oob/tcp/oob_tcp_listener.h @@ -41,7 +41,9 @@ struct mca_oob_tcp_listener_t { opal_list_item_t item; bool ev_active; opal_event_t event; + bool tcp6; int sd; + uint16_t port; }; typedef struct mca_oob_tcp_listener_t mca_oob_tcp_listener_t; OBJ_CLASS_DECLARATION(mca_oob_tcp_listener_t);