Re: [PATCH 5/5] multipath-tools: Perform socket client uid check on IPC commands.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Applied.

On Fri, Jan 20, 2017 at 2:39 PM, Gris Ge <fge@xxxxxxxxxx> wrote:
Problem:
    A non-root user could send and execute 'shutdown' IPC command to
    multipathd.

Fix:
    Use getsockopt() to find out socket client uid, only query (list or
    show) command are allowed for non-root(uid != 0) socket connection.
    An error message "permission deny: need to be root" will be sent
    otherwise.

Signed-off-by: Gris Ge <fge@xxxxxxxxxx>
---
 multipathd/main.c   | 12 +++++++++++-
 multipathd/uxlsnr.c | 19 +++++++++++++++++++
 multipathd/uxlsnr.h |  4 +++-
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/multipathd/main.c b/multipathd/main.c
index adc3258..1e64afc 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -23,6 +23,7 @@
 #endif
 #include <semaphore.h>
 #include <time.h>
+#include <stdbool.h>

 /*
  * libmultipath
@@ -1048,7 +1049,8 @@ map_discovery (struct vectors * vecs)
 }

 int
-uxsock_trigger (char * str, char ** reply, int * len, void * trigger_data)
+uxsock_trigger (char * str, char ** reply, int * len, bool is_root,
+               void * trigger_data)
 {
        struct vectors * vecs;
        int r;
@@ -1057,6 +1059,14 @@ uxsock_trigger (char * str, char ** reply, int * len, void * trigger_data)
        *len = 0;
        vecs = (struct vectors *)trigger_data;

+       if ((str != NULL) && (is_root == false) &&
+           (strncmp(str, "list", strlen("list")) != 0) &&
+           (strncmp(str, "show", strlen("show")) != 0)) {
+               *reply = STRDUP("permission deny: need to be root");
+               *len = strlen(*reply) + 1;
+               return 1;
+       }
+
        r = parse_cmd(str, reply, len, vecs, uxsock_timeout / 1000);

        if (r > 0) {
diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c
index 6ca62af..98ac25a 100644
--- a/multipathd/uxlsnr.c
+++ b/multipathd/uxlsnr.c
@@ -22,6 +22,7 @@
 #include <poll.h>
 #include <sys/time.h>
 #include <signal.h>
+#include <stdbool.h>
 #include "checkers.h"
 #include "memory.h"
 #include "debug.h"
@@ -51,6 +52,23 @@ LIST_HEAD(clients);
 pthread_mutex_t client_lock = PTHREAD_MUTEX_INITIALIZER;
 struct pollfd *polls;

+static bool _socket_client_is_root(int fd);
+
+static bool _socket_client_is_root(int fd)
+{
+       socklen_t len = 0;
+       struct ucred uc;
+
+       len = sizeof(struct ucred);
+       if ((fd >= 0) &&
+           (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &uc, &len) == 0) &&
+           (uc.uid == 0))
+                       return true;
+
+       /* Treat error as not root client */
+       return false;
+}
+
 /*
  * handle a new client joining
  */
@@ -255,6 +273,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
                                condlog(4, "cli[%d]: Got request [%s]",
                                        i, inbuf);
                                uxsock_trigger(inbuf, &reply, &rlen,
+                                              _socket_client_is_root(c->fd),
                                               trigger_data);
                                if (reply) {
                                        if (send_packet(c->fd,
diff --git a/multipathd/uxlsnr.h b/multipathd/uxlsnr.h
index 4ef47d5..d51a8f9 100644
--- a/multipathd/uxlsnr.h
+++ b/multipathd/uxlsnr.h
@@ -1,7 +1,9 @@
 #ifndef _UXLSNR_H
 #define _UXLSNR_H

-typedef int (uxsock_trigger_fn)(char *, char **, int *, void *);
+#include <stdbool.h>
+
+typedef int (uxsock_trigger_fn)(char *, char **, int *, bool, void *);

 void * uxsock_listen(uxsock_trigger_fn uxsock_trigger,
                     void * trigger_data);
--
1.8.3.1

--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/dm-devel

--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/dm-devel

[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux