summaryrefslogtreecommitdiff
path: root/iscsiuio/src/unix/iscsid_ipc.c
diff options
context:
space:
mode:
authorLee Duncan <lduncan@suse.com>2017-12-15 10:36:11 -0800
committerLee Duncan <lduncan@suse.com>2017-12-15 10:36:11 -0800
commite313bd648a4c8a9526421e270eb597a5de1e0c7f (patch)
tree132f0b7894c6ab70f7d39dd5fde6fa2b19c22890 /iscsiuio/src/unix/iscsid_ipc.c
parentc93fc2e030b7cad43a4b4d6a6e8a5432e4d27730 (diff)
downloadopen-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/src/unix/iscsid_ipc.c')
-rw-r--r--iscsiuio/src/unix/iscsid_ipc.c47
1 files changed, 47 insertions, 0 deletions
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);
}