2c4537b
From 3256b93ee3025bf76757001ff3d24914c4c4af28 Mon Sep 17 00:00:00 2001
2c4537b
From: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>
2c4537b
Date: Tue, 9 Jul 2013 08:17:14 -0400
2c4537b
Subject: [PATCH] iscsiadm: Correctly check for invalid hostno and flashnode
2c4537b
 index
2c4537b
2c4537b
In host mode, correctly compare for invalid hostno and flashnode index.
2c4537b
2c4537b
Signed-off-by: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>
2c4537b
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
2c4537b
---
2c4537b
 usr/flashnode.h |  2 ++
2c4537b
 usr/host.h      |  2 ++
2c4537b
 usr/iscsiadm.c  | 48 ++++++++++++++++++++++++++++++------------------
2c4537b
 usr/types.h     |  1 +
2c4537b
 4 files changed, 35 insertions(+), 18 deletions(-)
2c4537b
2c4537b
diff --git a/usr/flashnode.h b/usr/flashnode.h
2c4537b
index c1de9cc..2950fb5 100644
2c4537b
--- a/usr/flashnode.h
2c4537b
+++ b/usr/flashnode.h
2c4537b
@@ -26,6 +26,8 @@
2c4537b
 #include "config.h"
2c4537b
 #include "auth.h"
2c4537b
 
2c4537b
+#define MAX_FLASHNODE_IDX UINT_MAX
2c4537b
+
2c4537b
 typedef enum portal_type {
2c4537b
 	IPV4,
2c4537b
 	IPV6,
2c4537b
diff --git a/usr/host.h b/usr/host.h
2c4537b
index 894ab91..db44cfa 100644
2c4537b
--- a/usr/host.h
2c4537b
+++ b/usr/host.h
2c4537b
@@ -5,6 +5,8 @@
2c4537b
 #include "types.h"
2c4537b
 #include "config.h"
2c4537b
 
2c4537b
+#define MAX_HOST_NO UINT_MAX
2c4537b
+
2c4537b
 #define MAX_CHAP_BUF_SZ 4096
2c4537b
 #define REQ_CHAP_BUF_SZ (MAX_CHAP_BUF_SZ + sizeof(struct iscsi_uevent))
2c4537b
 
2c4537b
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
2c4537b
index da0a3ec..c7337ae 100644
2c4537b
--- a/usr/iscsiadm.c
2c4537b
+++ b/usr/iscsiadm.c
2c4537b
@@ -1744,20 +1744,22 @@ exit_logout_sid:
2c4537b
 }
2c4537b
 
2c4537b
 static int exec_flashnode_op(int op, int info_level, uint32_t host_no,
2c4537b
-			     uint32_t flashnode_idx, int type,
2c4537b
+			     uint64_t fnode_idx, int type,
2c4537b
 			     struct list_head *params)
2c4537b
 {
2c4537b
 	struct iscsi_transport *t = NULL;
2c4537b
 	int rc = ISCSI_SUCCESS;
2c4537b
 	char *portal_type;
2c4537b
+	uint32_t flashnode_idx;
2c4537b
 
2c4537b
 	if (op != OP_SHOW && op != OP_NOOP && op != OP_NEW &&
2c4537b
-	    flashnode_idx == 0xffffffff) {
2c4537b
+	    fnode_idx > MAX_FLASHNODE_IDX) {
2c4537b
 		log_error("Invalid flashnode index");
2c4537b
 		rc = ISCSI_ERR_INVAL;
2c4537b
 		goto exit_flashnode_op;
2c4537b
 	}
2c4537b
 
2c4537b
+	flashnode_idx = (uint32_t)fnode_idx;
2c4537b
 	t = iscsi_sysfs_get_transport_by_hba(host_no);
2c4537b
 	if (!t) {
2c4537b
 		log_error("Could not match hostno %u to transport.", host_no);
2c4537b
@@ -1768,7 +1770,7 @@ static int exec_flashnode_op(int op, int info_level, uint32_t host_no,
2c4537b
 	switch (op) {
2c4537b
 	case OP_NOOP:
2c4537b
 	case OP_SHOW:
2c4537b
-		if (flashnode_idx == 0xffffffff)
2c4537b
+		if (fnode_idx > MAX_FLASHNODE_IDX)
2c4537b
 			rc = list_flashnodes(info_level, host_no);
2c4537b
 		else
2c4537b
 			rc = get_flashnode_info(host_no, flashnode_idx);
2c4537b
@@ -1880,7 +1882,7 @@ static int verify_iface_params(struct list_head *params, struct node_rec *rec)
2c4537b
 
2c4537b
 /* TODO: merge iter helpers and clean them up, so we can use them here */
2c4537b
 static int exec_iface_op(int op, int do_show, int info_level,
2c4537b
-			 struct iface_rec *iface, uint32_t host_no,
2c4537b
+			 struct iface_rec *iface, uint64_t host_no,
2c4537b
 			 struct list_head *params)
2c4537b
 {
2c4537b
 	struct host_info hinfo;
2c4537b
@@ -2001,9 +2003,9 @@ update_fail:
2c4537b
 		printf("%s applied.\n", iface->name);
2c4537b
 		break;
2c4537b
 	case OP_APPLY_ALL:
2c4537b
-		if (host_no == -1) {
2c4537b
-			log_error("Applyall requires a host number or MAC "
2c4537b
-				  "passed in with the --host argument.");
2c4537b
+		if (host_no > MAX_HOST_NO) {
2c4537b
+			log_error("Applyall requires a valid host number or MAC"
2c4537b
+				  " passed in with the --host argument.");
2c4537b
 			rc = ISCSI_ERR_INVAL;
2c4537b
 			break;
2c4537b
 		}
2c4537b
@@ -2014,7 +2016,7 @@ update_fail:
2c4537b
 		memset(&hinfo, 0, sizeof(struct host_info));
2c4537b
 		hinfo.host_no = host_no;
2c4537b
 		if (iscsi_sysfs_get_hostinfo_by_host_no(&hinfo)) {
2c4537b
-			log_error("Could not match host%u to ifaces.", host_no);
2c4537b
+			log_error("Could not match host%lu to ifaces.", host_no);
2c4537b
 			rc = ISCSI_ERR_INVAL;
2c4537b
 			break;
2c4537b
 		}
2c4537b
@@ -2025,7 +2027,7 @@ update_fail:
2c4537b
 			break;
2c4537b
 		}
2c4537b
 
2c4537b
-		printf("Applied settings to ifaces attached to host%u.\n",
2c4537b
+		printf("Applied settings to ifaces attached to host%lu.\n",
2c4537b
 		       host_no);
2c4537b
 		break;
2c4537b
 	default:
2c4537b
@@ -2637,10 +2639,10 @@ done:
2c4537b
 	return rc;
2c4537b
 }
2c4537b
 
2c4537b
-static uint32_t parse_host_info(char *optarg, int *rc)
2c4537b
+static uint64_t parse_host_info(char *optarg, int *rc)
2c4537b
 {
2c4537b
 	int err = 0;
2c4537b
-	uint32_t host_no = -1;
2c4537b
+	uint64_t host_no;
2c4537b
 
2c4537b
 	*rc = 0;
2c4537b
 	if (strstr(optarg, ":")) {
2c4537b
@@ -2653,8 +2655,11 @@ static uint32_t parse_host_info(char *optarg, int *rc)
2c4537b
 			*rc = ISCSI_ERR_INVAL;
2c4537b
 		}
2c4537b
 	} else {
2c4537b
-		host_no = strtoul(optarg, NULL, 10);
2c4537b
-		if (errno) {
2c4537b
+		host_no = strtoull(optarg, NULL, 10);
2c4537b
+		if (errno || (host_no > MAX_HOST_NO)) {
2c4537b
+			if (host_no > MAX_HOST_NO)
2c4537b
+				errno = ERANGE;
2c4537b
+
2c4537b
 			log_error("Invalid host no %s. %s.",
2c4537b
 				  optarg, strerror(errno));
2c4537b
 			*rc = ISCSI_ERR_INVAL;
2c4537b
@@ -2806,13 +2811,14 @@ main(int argc, char **argv)
2c4537b
 	int tpgt = PORTAL_GROUP_TAG_UNKNOWN, killiscsid=-1, do_show=0;
2c4537b
 	int packet_size=32, ping_count=1, ping_interval=0;
2c4537b
 	int do_discover = 0, sub_mode = -1;
2c4537b
-	int flashnode_idx = -1, portal_type = -1;
2c4537b
+	int portal_type = -1;
2c4537b
 	struct sigaction sa_old;
2c4537b
 	struct sigaction sa_new;
2c4537b
 	struct list_head ifaces;
2c4537b
 	struct iface_rec *iface = NULL, *tmp;
2c4537b
 	struct node_rec *rec = NULL;
2c4537b
-	uint32_t host_no = -1;
2c4537b
+	uint64_t host_no =  (uint64_t)MAX_HOST_NO + 1;
2c4537b
+	uint64_t flashnode_idx = (uint64_t)MAX_FLASHNODE_IDX + 1;
2c4537b
 	struct user_param *param;
2c4537b
 	struct list_head params;
2c4537b
 
2c4537b
@@ -2956,7 +2962,13 @@ main(int argc, char **argv)
2c4537b
 				ISCSI_VERSION_STR);
2c4537b
 			return 0;
2c4537b
 		case 'x':
2c4537b
-			flashnode_idx = atoi(optarg);
2c4537b
+			flashnode_idx = strtoull(optarg, NULL, 10);
2c4537b
+			if (errno) {
2c4537b
+				log_error("Invalid flashnode index %s. %s.",
2c4537b
+					  optarg, strerror(errno));
2c4537b
+				rc = ISCSI_ERR_INVAL;
2c4537b
+				goto free_ifaces;
2c4537b
+			}
2c4537b
 			break;
2c4537b
 		case 'A':
2c4537b
 			portal_type = str_to_portal_type(optarg);
2c4537b
@@ -3022,7 +3034,7 @@ main(int argc, char **argv)
2c4537b
 		if (sub_mode != -1) {
2c4537b
 			switch (sub_mode) {
2c4537b
 			case MODE_CHAP:
2c4537b
-				if (!op || !host_no) {
2c4537b
+				if (!op || (host_no > MAX_HOST_NO)) {
2c4537b
 					log_error("CHAP mode requires host "
2c4537b
 						"no and valid operation");
2c4537b
 					rc = ISCSI_ERR_INVAL;
2c4537b
@@ -3032,7 +3044,7 @@ main(int argc, char **argv)
2c4537b
 						       value);
2c4537b
 				break;
2c4537b
 			case MODE_FLASHNODE:
2c4537b
-				if (!host_no) {
2c4537b
+				if (host_no > MAX_HOST_NO) {
2c4537b
 					log_error("FLASHNODE mode requires host no");
2c4537b
 					rc = ISCSI_ERR_INVAL;
2c4537b
 					break;
2c4537b
diff --git a/usr/types.h b/usr/types.h
2c4537b
index 77e3f97..9d9ba86 100644
2c4537b
--- a/usr/types.h
2c4537b
+++ b/usr/types.h
2c4537b
@@ -10,6 +10,7 @@
2c4537b
 #include <netinet/in.h>
2c4537b
 #include <stdint.h>
2c4537b
 #include <sys/types.h>
2c4537b
+#include <limits.h>
2c4537b
 
2c4537b
 /*
2c4537b
  * using the __be types allows stricter static
2c4537b
-- 
2c4537b
1.8.3.1
2c4537b