diff options
author | Lee Duncan <lduncan@suse.com> | 2017-12-15 10:36:11 -0800 |
---|---|---|
committer | Lee Duncan <lduncan@suse.com> | 2017-12-15 10:36:11 -0800 |
commit | e313bd648a4c8a9526421e270eb597a5de1e0c7f (patch) | |
tree | 132f0b7894c6ab70f7d39dd5fde6fa2b19c22890 /iscsiuio | |
parent | c93fc2e030b7cad43a4b4d6a6e8a5432e4d27730 (diff) | |
download | open-iscsi-e313bd648a4c8a9526421e270eb597a5de1e0c7f.tar.gz |
Check for root peer user for iscsiuio IPC
This fixes a possible vulnerability where a non-root
process could connect with iscsiuio. Fouund by Qualsys.
Diffstat (limited to 'iscsiuio')
-rw-r--r-- | iscsiuio/src/unix/Makefile.am | 3 | ||||
-rw-r--r-- | iscsiuio/src/unix/iscsid_ipc.c | 47 |
2 files changed, 49 insertions, 1 deletions
diff --git a/iscsiuio/src/unix/Makefile.am b/iscsiuio/src/unix/Makefile.am index 71d5463..a989ef0 100644 --- a/iscsiuio/src/unix/Makefile.am +++ b/iscsiuio/src/unix/Makefile.am @@ -20,7 +20,8 @@ iscsiuio_SOURCES = build_date.c \ nic_utils.c \ packet.c \ iscsid_ipc.c \ - ping.c + ping.c \ + ${top_srcdir}/../utils/sysdeps/sysdeps.c iscsiuio_CFLAGS = $(AM_CFLAGS) \ $(LIBNL_CFLAGS) \ diff --git a/iscsiuio/src/unix/iscsid_ipc.c b/iscsiuio/src/unix/iscsid_ipc.c index 6583628..6476265 100644 --- a/iscsiuio/src/unix/iscsid_ipc.c +++ b/iscsiuio/src/unix/iscsid_ipc.c @@ -37,6 +37,8 @@ * */ +#define _GNU_SOURCE + #include <errno.h> #include <pthread.h> #include <signal.h> @@ -47,6 +49,8 @@ #include <sys/socket.h> #include <sys/time.h> #include <sys/un.h> +#include <sys/types.h> +#include <pwd.h> #define PFX "iscsi_ipc " @@ -61,6 +65,7 @@ #include "iscsid_ipc.h" #include "uip.h" #include "uip_mgmt_ipc.h" +#include "sysdeps.h" #include "logger.h" #include "uip.h" @@ -102,6 +107,7 @@ struct iface_rec_decode { uint16_t mtu; }; +#define PEERUSER_MAX 64 /****************************************************************************** * Globals @@ -1024,6 +1030,40 @@ static void iscsid_loop_close(void *arg) LOG_INFO(PFX "iSCSI daemon socket closed"); } +/* + * check that the peer user is privilidged + * + * return 1 if peer is ok else 0 + * + * XXX: this function is copied from iscsid_ipc.c and should be + * moved into a common library + */ +static int +mgmt_peeruser(int sock, char *user) +{ + struct ucred peercred; + socklen_t so_len = sizeof(peercred); + struct passwd *pass; + + errno = 0; + if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, + &so_len) != 0 || so_len != sizeof(peercred)) { + /* We didn't get a valid credentials struct. */ + LOG_ERR(PFX "peeruser_unux: error receiving credentials: %m"); + return 0; + } + + pass = getpwuid(peercred.uid); + if (pass == NULL) { + LOG_ERR(PFX "peeruser_unix: unknown local user with uid %d", + (int) peercred.uid); + return 0; + } + + strlcpy(user, pass->pw_name, PEERUSER_MAX); + return 1; +} + /** * iscsid_loop() - This is the function which will process the broadcast * messages from iscsid @@ -1033,6 +1073,7 @@ static void *iscsid_loop(void *arg) { int rc; sigset_t set; + char user[PEERUSER_MAX]; pthread_cleanup_push(iscsid_loop_close, arg); @@ -1072,6 +1113,12 @@ static void *iscsid_loop(void *arg) continue; } + if (!mgmt_peeruser(iscsid_opts.fd, user) || strncmp(user, "root", PEERUSER_MAX)) { + close(s2); + LOG_ERR(PFX "Access error: non-administrative connection rejected"); + break; + } + process_iscsid_broadcast(s2); close(s2); } |