1
1

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
Этот коммит содержится в:
Ralph Castain 2016-02-12 08:09:15 -08:00
родитель 52acd5b7ee
Коммит 233bd085ca
3 изменённых файлов: 46 добавлений и 6 удалений

Просмотреть файл

@ -10,8 +10,8 @@
# University of Stuttgart. All rights reserved. # University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California. # Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved. # All rights reserved.
# Copyright (c) 2014-2015 Intel, Inc. All rights reserved. # Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
# Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$ # $COPYRIGHT$
# #
# Additional copyrights may follow # Additional copyrights may follow
@ -96,3 +96,13 @@ eventually timeout / abort.
Errno: %d (%s) Errno: %d (%s)
Probable cause: %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.

Просмотреть файл

@ -13,7 +13,7 @@
* All rights reserved. * All rights reserved.
* Copyright (c) 2009-2015 Cisco Systems, Inc. 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) 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 * Copyright (c) 2015 Research Organization for Information Science
* and Technology (RIST). All rights reserved. * and Technology (RIST). All rights reserved.
* $COPYRIGHT$ * $COPYRIGHT$
@ -384,6 +384,7 @@ static int create_listen(void)
/* add this port to our connections */ /* add this port to our connections */
conn = OBJ_NEW(mca_oob_tcp_listener_t); conn = OBJ_NEW(mca_oob_tcp_listener_t);
conn->sd = sd; conn->sd = sd;
conn->port = ntohs(((struct sockaddr_in*) &inaddr)->sin_port);
opal_list_append(&mca_oob_tcp_component.listeners, &conn->item); opal_list_append(&mca_oob_tcp_component.listeners, &conn->item);
/* and to our ports */ /* and to our ports */
asprintf(&tconn, "%d", ntohs(((struct sockaddr_in*) &inaddr)->sin_port)); 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 */ /* add this port to our connections */
conn = OBJ_NEW(mca_oob_tcp_listener_t); conn = OBJ_NEW(mca_oob_tcp_listener_t);
conn->tcp6 = true;
conn->sd = sd; conn->sd = sd;
conn->port = ntohs(((struct sockaddr_in6*) &inaddr)->sin6_port);
opal_list_append(&mca_oob_tcp_component.listeners, &conn->item); opal_list_append(&mca_oob_tcp_component.listeners, &conn->item);
/* and to our ports */ /* and to our ports */
asprintf(&tconn, "%d", ntohs(((struct sockaddr_in6*) &inaddr)->sin6_port)); 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, pending_connection->fd = accept(sd,
(struct sockaddr*)&(pending_connection->addr), (struct sockaddr*)&(pending_connection->addr),
&addrlen); &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) { if (pending_connection->fd < 0) {
OBJ_RELEASE(pending_connection); OBJ_RELEASE(pending_connection); // this closes the incoming fd
/* Non-fatal errors */ /* Non-fatal errors */
if (EAGAIN == opal_socket_errno || if (EAGAIN == opal_socket_errno ||
@ -764,10 +791,9 @@ static void* listen_thread(opal_object_t *obj)
goto done; goto done;
} }
/* For all other cases, close the socket, print a /* For all other cases, print a
warning but try to continue */ warning but try to continue */
else { else {
CLOSE_THE_SOCKET(sd);
orte_show_help("help-oob-tcp.txt", orte_show_help("help-oob-tcp.txt",
"accept failed", "accept failed",
true, 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) static void tcp_ev_cons(mca_oob_tcp_listener_t* event)
{ {
event->ev_active = false; event->ev_active = false;
event->tcp6 = false;
event->sd = -1; event->sd = -1;
event->port = 0;
} }
static void tcp_ev_des(mca_oob_tcp_listener_t* event) static void tcp_ev_des(mca_oob_tcp_listener_t* event)
{ {

Просмотреть файл

@ -41,7 +41,9 @@ struct mca_oob_tcp_listener_t {
opal_list_item_t item; opal_list_item_t item;
bool ev_active; bool ev_active;
opal_event_t event; opal_event_t event;
bool tcp6;
int sd; int sd;
uint16_t port;
}; };
typedef struct mca_oob_tcp_listener_t mca_oob_tcp_listener_t; typedef struct mca_oob_tcp_listener_t mca_oob_tcp_listener_t;
OBJ_CLASS_DECLARATION(mca_oob_tcp_listener_t); OBJ_CLASS_DECLARATION(mca_oob_tcp_listener_t);