Applied. On Fri, Jan 20, 2017 at 2:39 PM, Gris Ge <[email protected]> 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 <[email protected]> > --- > 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 > [email protected] > https://www.redhat.com/mailman/listinfo/dm-devel >
-- dm-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/dm-devel
