2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00

bridge: allow OVS to interact with controller through sockets outside run dir

Currently Open vSwitch is unable to create or connect to Unix Domain
Sockets outside designated 'run' directory, because of fear of potential
remote exploits where a hacked remote OVSDB manager would tell Open vSwitch
to connect to a unix domain socket owned by other daemon on the same
hypervisor.

This patch allows to disable this behavior by changing
/etc/default/openvswitch (Ubuntu) or /etc/sysconfig/openvswitch (RHEL)
file to:

...
OVS_CTL_OPTS=--no-self-confinement
...

Note, that it is better to stick with default behavior, unless:
1. You have Open vSwitch running under SELinux or AppArmor
   that would prevent OVS from messing with sockets owned by other
   daemons; OR
2. You are sure that relying on OpenFlow handshake is enough to
   prevent OVS to adversely interact with those other daemons
   running on the same hypervisor; OR
3. You don't have much worries of remote exploits in the first
   place, because perhaps OVSDB manager is running on the same host
   as OVS.

The initial use-case for this patch is to allow to connect to OpenFlow
controller that has its socket outside OVS run directory.  However,
in the future it could be generalized to allow to disable self-confinement
for other things like DPDK vhost-user sockets or anything else
that is specifiable in OVSDB with full path.

Signed-off-by: Ansis Atteka <aatteka@ovn.org>
Acked-by: Jesse Gross <jesse@kernel.org>
VMware-BZ: #1525857
This commit is contained in:
Ansis Atteka 2016-06-20 14:19:40 -07:00
parent 1ec0750ea8
commit 81d2f75cfc
8 changed files with 92 additions and 9 deletions

2
NEWS
View File

@ -73,6 +73,8 @@ Post-v2.5.0
* Added support for IPv6 tunnels to native tunneling.
- A wrapper script, 'ovs-tcpdump', to easily port-mirror an OVS port and
watch with tcpdump
- Introduce --no-self-confinement flag that allows daemons to work with
sockets outside their run directory.
v2.5.0 - 26 Feb 2016
---------------------

View File

@ -3,3 +3,4 @@
[\fB\-\-overwrite\-pidfile\fR]
[\fB\-\-detach\fR]
[\fB\-\-no\-chdir\fR]
[\fB\-\-no\-self\-confinement\fR]

View File

@ -29,6 +29,13 @@ VLOG_DEFINE_THIS_MODULE(daemon);
* /dev/null (if false) or keep it for the daemon to use (if true). */
static bool save_fds[3];
/* Self Confinement is a security feature that introduces additional
* layer of defense where OVS in self-denying manner would refuse to connect
* to or create unix domain sockets outside designated 'run' directory even
* if remote (or local) OVSDB manager asked it to do so. This feature may
* be disabled if Mandatory Access Control is used. */
static bool self_confine = true;
/* Will daemonize() really detach? */
bool
get_detach(void)
@ -59,6 +66,21 @@ set_pidfile(const char *name)
pidfile = make_pidfile_name(name);
}
/* Disables self confinement. */
void
daemon_disable_self_confinement(void)
{
self_confine = false;
}
/* Returns true, if self-confinement should be enforced.
* Otherwise, returns false. */
bool
daemon_should_self_confine(void)
{
return self_confine;
}
/* A daemon doesn't normally have any use for the file descriptors for stdin,
* stdout, and stderr after it detaches. To keep these file descriptors from
* e.g. holding an SSH session open, by default detaching replaces each of

View File

@ -39,6 +39,7 @@
#ifndef _WIN32
#define DAEMON_OPTION_ENUMS \
OPT_DETACH, \
OPT_NO_SELF_CONFINEMENT, \
OPT_NO_CHDIR, \
OPT_OVERWRITE_PIDFILE, \
OPT_PIDFILE, \
@ -47,6 +48,7 @@
#define DAEMON_LONG_OPTIONS \
{"detach", no_argument, NULL, OPT_DETACH}, \
{"no-self-confinement", no_argument, NULL, OPT_NO_SELF_CONFINEMENT}, \
{"no-chdir", no_argument, NULL, OPT_NO_CHDIR}, \
{"pidfile", optional_argument, NULL, OPT_PIDFILE}, \
{"overwrite-pidfile", no_argument, NULL, OPT_OVERWRITE_PIDFILE}, \
@ -58,6 +60,10 @@
set_detach(); \
break; \
\
case OPT_NO_SELF_CONFINEMENT: \
daemon_disable_self_confinement(); \
break; \
\
case OPT_NO_CHDIR: \
set_no_chdir(); \
break; \
@ -86,6 +92,7 @@ pid_t read_pidfile(const char *name);
#else
#define DAEMON_OPTION_ENUMS \
OPT_DETACH, \
OPT_NO_SELF_CONFINEMENT, \
OPT_NO_CHDIR, \
OPT_PIDFILE, \
OPT_PIPE_HANDLE, \
@ -95,6 +102,7 @@ pid_t read_pidfile(const char *name);
#define DAEMON_LONG_OPTIONS \
{"detach", no_argument, NULL, OPT_DETACH}, \
{"no-self-confinement" no_argument, NULL, OPT_NO_SELF_CONFINEMENT}, \
{"no-chdir", no_argument, NULL, OPT_NO_CHDIR}, \
{"pidfile", optional_argument, NULL, OPT_PIDFILE}, \
{"pipe-handle", required_argument, NULL, OPT_PIPE_HANDLE}, \
@ -106,6 +114,10 @@ pid_t read_pidfile(const char *name);
case OPT_DETACH: \
break; \
\
case OPT_NO_SELF_CONFINEMENT: \
daemon_disable_self_confinement(); \
break; \
\
case OPT_NO_CHDIR: \
break; \
\
@ -138,6 +150,8 @@ void daemonize_complete(void);
void daemon_set_new_user(const char * user_spec);
void daemon_become_new_user(bool access_datapath);
void daemon_usage(void);
void daemon_disable_self_confinement(void);
bool daemon_should_self_confine(void);
void service_start(int *argcp, char **argvp[]);
void service_stop(void);
bool should_service_stop(void);

View File

@ -55,6 +55,18 @@ is not a good directory to use.
This option has no effect when \fB\-\-detach\fR is not specified.
.
.TP
\fB\-\-no\-self\-confinement\fR
By default daemon will try to self-confine itself to work with
files under well-know, at build-time whitelisted directories. It
is better to stick with this default behavior and not to use this
flag unless some other Access Control is used to confine daemon.
Note that in contrast to other access control implementations that
are typically enforced from kernel-space (e.g. DAC or MAC),
self-confinement is imposed from the user-space daemon itself and
hence should not be considered as a full confinement strategy, but
instead should be viewed as an additional layer of security.
.
.TP
\fB\-\-user\fR
Causes \fB\*(PN\fR to run as a different user specified in "user:group", thus
dropping most of the root privileges. Short forms "user" and ":group" are also

View File

@ -180,6 +180,30 @@ By default \fBovs\-ctl\fR passes \fB\-\-mlockall\fR to
memory, preventing it from being paged to disk. This option
suppresses that behavior.
.
.IP "\fB\-\-no\-self\-confinement\fR"
Disable self-confinement for \fBovs-vswitchd\fR and \fBovsdb\-server\fR
daemons. This flag may be used when, for example, OpenFlow controller
creates its Unix Domain Socket outside OVS run directory and OVS needs
to connect to it. It is better to stick with the default behavior and
not to use this flag, unless:
.
.RS
.IP \(bu
You have Open vSwitch running under SELinux or AppArmor Mandatory
Access Control that would prevent OVS from messing with sockets
outside ordinary OVS directories.
.
.IP \(bu
You believe that relying on protocol handshakes (e.g. OpenFlow)
is enough to prevent OVS to adversely interact with other daemons
running on your system.
.
.IP \(bu
You don't have much worries of remote OVSDB exploits in the first
place, because, perhaps, OVSDB manager is running on the same host
as OVS and share similar attack vectors.
.RE
.
.IP "\fB\-\-ovsdb\-server\-priority=\fIniceness\fR"
.IQ "\fB\-\-ovs\-vswitchd\-priority=\fIniceness\fR"
Sets the \fBnice\fR(1) level used for each daemon. All of them

View File

@ -162,6 +162,9 @@ do_start_ovsdb () {
log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)"
fi
done
if test X"$SELF_CONFINEMENT" = Xno; then
set "$@" --no-self-confinement
fi
set "$@" -vconsole:emer -vsyslog:err -vfile:info
set "$@" --remote=punix:"$DB_SOCK"
set "$@" --private-key=db:Open_vSwitch,SSL,private_key
@ -226,13 +229,16 @@ do_start_forwarding () {
ulimit -n $MAXFD
fi
# Start ovs-vswitchd.
set ovs-vswitchd unix:"$DB_SOCK"
set "$@" -vconsole:emer -vsyslog:err -vfile:info
if test X"$MLOCKALL" != Xno; then
set "$@" --mlockall
fi
start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@"
# Start ovs-vswitchd.
set ovs-vswitchd unix:"$DB_SOCK"
set "$@" -vconsole:emer -vsyslog:err -vfile:info
if test X"$MLOCKALL" != Xno; then
set "$@" --mlockall
fi
if test X"$SELF_CONFINEMENT" = Xno; then
set "$@" --no-self-confinement
fi
start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@"
fi
}
@ -492,6 +498,7 @@ set_defaults () {
DAEMON_CWD=/
FORCE_COREFILES=yes
MLOCKALL=yes
SELF_CONFINEMENT=yes
OVSDB_SERVER=yes
OVS_VSWITCHD=yes
OVSDB_SERVER_PRIORITY=-10

View File

@ -3570,8 +3570,9 @@ bridge_configure_remotes(struct bridge *br,
for (i = 0; i < n_controllers; i++) {
struct ovsrec_controller *c = controllers[i];
if (!strncmp(c->target, "punix:", 6)
|| !strncmp(c->target, "unix:", 5)) {
if (daemon_should_self_confine()
&& (!strncmp(c->target, "punix:", 6)
|| !strncmp(c->target, "unix:", 5))) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
char *whitelist;