From e313bd648a4c8a9526421e270eb597a5de1e0c7f Mon Sep 17 00:00:00 2001
From: Lee Duncan <lduncan@suse.com>
Date: Fri, 15 Dec 2017 10:36:11 -0800
Subject: [PATCH] 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.
---
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 71d54633a764..a989ef029b59 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 658362899234..64762654c523 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);
}
--
2.17.2