diff options
author | Alasdair Kergon <agk@redhat.com> | 2010-07-28 13:55:42 +0000 |
---|---|---|
committer | Alasdair Kergon <agk@redhat.com> | 2010-07-28 13:55:42 +0000 |
commit | 8bae0a1ecf3fce3817a96f368f38200e115e25c6 (patch) | |
tree | 7f4355e56f6e7d6ceb103e0f21fe235ec1ca1e78 /daemons/clvmd | |
parent | 64f95b40ca93a053f088114624e32d83570c720f (diff) | |
download | lvm2-8bae0a1ecf3fce3817a96f368f38200e115e25c6.tar.gz lvm2-8bae0a1ecf3fce3817a96f368f38200e115e25c6.tar.xz lvm2-8bae0a1ecf3fce3817a96f368f38200e115e25c6.zip |
Change clvmd to communicate with lvm via a socket in /var/run/lvm. (mbroz)
https://bugzilla.redhat.com/show_bug.cgi?id=614248 [CVE-2010-2526]
Diffstat (limited to 'daemons/clvmd')
-rw-r--r-- | daemons/clvmd/clvm.h | 7 | ||||
-rw-r--r-- | daemons/clvmd/clvmd.c | 55 | ||||
-rw-r--r-- | daemons/clvmd/clvmd.h | 3 |
3 files changed, 48 insertions, 17 deletions
diff --git a/daemons/clvmd/clvm.h b/daemons/clvmd/clvm.h index 92f807f7..c9ea10c4 100644 --- a/daemons/clvmd/clvm.h +++ b/daemons/clvmd/clvm.h @@ -22,6 +22,8 @@ #ifndef _CLVM_H #define _CLVM_H +#include "configure.h" + struct clvm_header { uint8_t cmd; /* See below */ uint8_t flags; /* See below */ @@ -45,9 +47,8 @@ struct clvm_header { #define CLVMD_FLAG_SYSTEMLV 2 /* Data in system LV under my node name */ #define CLVMD_FLAG_NODEERRS 4 /* Reply has errors in node-specific portion */ -/* Name of the local socket to communicate between libclvm and clvmd */ -//static const char CLVMD_SOCKNAME[]="/var/run/clvmd"; -static const char CLVMD_SOCKNAME[] = "\0clvmd"; +/* Name of the local socket to communicate between lvm and clvmd */ +static const char CLVMD_SOCKNAME[]= DEFAULT_RUN_DIR "/clvmd.sock"; /* Internal commands & replies */ #define CLVMD_CMD_REPLY 1 diff --git a/daemons/clvmd/clvmd.c b/daemons/clvmd/clvmd.c index 4f5ed977..2365a331 100644 --- a/daemons/clvmd/clvmd.c +++ b/daemons/clvmd/clvmd.c @@ -123,6 +123,7 @@ static void process_remote_command(struct clvm_header *msg, int msglen, int fd, static int process_reply(const struct clvm_header *msg, int msglen, const char *csid); static int open_local_sock(void); +static void close_local_sock(int local_socket); static int check_local_clvmd(void); static struct local_client *find_client(int clientid); static void main_loop(int local_sock, int cmd_timeout); @@ -276,6 +277,23 @@ static void remove_lockfile(void) unlink(CLVMD_PIDFILE); } +/* + * clvmd require dm-ioctl capability for operation + */ +static void check_permissions() +{ + if (getuid() || geteuid()) { + log_error("Cannot run as a non-root user."); + + /* + * Fail cleanly here if not run as root, instead of failing + * later when attempting a root-only operation + * Preferred exit code from an initscript for this. + */ + exit(4); + } +} + int main(int argc, char *argv[]) { int local_sock; @@ -305,9 +323,11 @@ int main(int argc, char *argv[]) exit(0); case 'R': + check_permissions(); return refresh_clvmd(1)==1?0:1; case 'S': + check_permissions(); return restart_clvmd(clusterwide_opt)==1?0:1; case 'C': @@ -353,6 +373,8 @@ int main(int argc, char *argv[]) } } + check_permissions(); + /* Setting debug options on an existing clvmd */ if (debug_opt && !check_local_clvmd()) { @@ -521,6 +543,7 @@ int main(int argc, char *argv[]) /* Do some work */ main_loop(local_sock, cmd_timeout); + close_local_sock(local_sock); destroy_lvm(); return 0; @@ -864,7 +887,6 @@ static void main_loop(int local_sock, int cmd_timeout) closedown: clops->cluster_closedown(); - close(local_sock); } static __attribute__ ((noreturn)) void wait_for_child(int c_pipe, int timeout) @@ -1963,20 +1985,30 @@ static int check_local_clvmd(void) return ret; } +static void close_local_sock(int local_socket) +{ + if (local_socket != -1 && close(local_socket)) + stack; + + if (CLVMD_SOCKNAME[0] != '\0' && unlink(CLVMD_SOCKNAME)) + stack; +} /* Open the local socket, that's the one we talk to libclvm down */ static int open_local_sock() { - int local_socket; + int local_socket = -1; struct sockaddr_un sockaddr; + mode_t old_mask; + + close_local_sock(local_socket); + old_mask = umask(0077); /* Open local socket */ - if (CLVMD_SOCKNAME[0] != '\0') - unlink(CLVMD_SOCKNAME); local_socket = socket(PF_UNIX, SOCK_STREAM, 0); if (local_socket < 0) { log_error("Can't create local socket: %m"); - return -1; + goto error; } /* Set Close-on-exec & non-blocking */ @@ -1989,18 +2021,19 @@ static int open_local_sock() sockaddr.sun_family = AF_UNIX; if (bind(local_socket, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) { log_error("can't bind local socket: %m"); - close(local_socket); - return -1; + goto error; } if (listen(local_socket, 1) != 0) { log_error("listen local: %m"); - close(local_socket); - return -1; + goto error; } - if (CLVMD_SOCKNAME[0] != '\0') - chmod(CLVMD_SOCKNAME, 0600); + umask(old_mask); return local_socket; +error: + close_local_sock(local_socket); + umask(old_mask); + return -1; } void process_message(struct local_client *client, const char *buf, int len, diff --git a/daemons/clvmd/clvmd.h b/daemons/clvmd/clvmd.h index aec31b2c..ccc79cc3 100644 --- a/daemons/clvmd/clvmd.h +++ b/daemons/clvmd/clvmd.h @@ -20,9 +20,6 @@ #define CLVMD_MINOR_VERSION 2 #define CLVMD_PATCH_VERSION 1 -/* Name of the cluster LVM admin lock */ -#define ADMIN_LOCK_NAME "CLVMD_ADMIN" - /* Default time (in seconds) we will wait for all remote commands to execute before declaring them dead */ #define DEFAULT_CMD_TIMEOUT 60 |