From eb516ac5f9dddc80564f6becee08a0011e7aa58b Mon Sep 17 00:00:00 2001 From: Lee Duncan Date: Fri, 15 Dec 2017 10:36:11 -0800 Subject: [PATCH 1/7] 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. CVE: CVE-2017-17840 Upstream-Status: Backport Signed-off-by: Zhixiong Chi --- iscsiuio/src/unix/Makefile.am | 3 ++- iscsiuio/src/unix/iscsid_ipc.c | 47 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) 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 a2a59a8..08e49e5 100644 --- a/iscsiuio/src/unix/iscsid_ipc.c +++ b/iscsiuio/src/unix/iscsid_ipc.c @@ -37,6 +37,8 @@ * */ +#define _GNU_SOURCE + #include #include #include @@ -47,6 +49,8 @@ #include #include #include +#include +#include #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 /****************************************************************************** * iscsid_ipc Constants @@ -1029,6 +1035,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 @@ -1038,6 +1078,7 @@ static void *iscsid_loop(void *arg) { int rc; sigset_t set; + char user[PEERUSER_MAX]; pthread_cleanup_push(iscsid_loop_close, arg); @@ -1077,6 +1118,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); } -- 1.9.1