Преглед изворни кода

tools: use util_strtonum for options checking

Function atoi is not safe since miss validation;
Function strtol is better but need to consider empty string and
overflows
Function util_strtonum is a safer wrapper of strtoll

Use util_strtonum to check nodeid option and strict checking condition.

(backported from master fb5e0fae92417093127335a2114fadde9262315d)

Signed-off-by: liangxin1300 <XLiang@suse.com>
Reviewed-by: Jan Friesse <jfriesse@redhat.com>
liangxin1300 пре 5 година
родитељ
комит
c7e3045199
5 измењених фајлова са 76 додато и 10 уклоњено
  1. 6 0
      tools/Makefile.am
  2. 13 2
      tools/corosync-cfgtool.c
  3. 7 8
      tools/corosync-quorumtool.c
  4. 35 0
      tools/util.c
  5. 15 0
      tools/util.h

+ 6 - 0
tools/Makefile.am

@@ -42,10 +42,16 @@ if INSTALL_XMLCONF
 bin_SCRIPTS		+= corosync-xmlproc
 endif
 
+noinst_HEADERS          = util.h
+
 EXTRA_DIST		= corosync-xmlproc.sh \
 			  corosync-notifyd.sysconfig.example \
                           corosync-blackbox.sh
 
+corosync_cfgtool_SOURCES = corosync-cfgtool.c util.c
+
+corosync_quorumtool_SOURCES = corosync-quorumtool.c util.c
+
 corosync-xmlproc: corosync-xmlproc.sh
 	sed -e 's#@''DATADIR@#${datadir}#g' \
 	    -e 's#@''BASHPATH@#${BASHPATH}#g' \

+ 13 - 2
tools/corosync-cfgtool.c

@@ -46,10 +46,12 @@
 #include <sys/un.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <limits.h>
 
 #include <corosync/corotypes.h>
 #include <corosync/totem/totem.h>
 #include <corosync/cfg.h>
+#include "util.h"
 
 #define cs_repeat(result, max, code)				\
 	do {							\
@@ -280,6 +282,7 @@ int main (int argc, char *argv[]) {
 	unsigned int nodeid;
 	char interface_name[128] = "";
 	int rc = EXIT_SUCCESS;
+	long long int l;
 
 	if (argc == 1) {
 		usage_do ();
@@ -300,14 +303,22 @@ int main (int argc, char *argv[]) {
 			ringreenable_do ();
 			break;
 		case 'k':
-			nodeid = atoi (optarg);
+			if (util_strtonum(optarg, 1, UINT_MAX, &l) == -1) {
+				fprintf(stderr, "The nodeid was not valid, try a positive number\n");
+				exit(EXIT_FAILURE);
+			}
+			nodeid = l;
 			killnode_do(nodeid);
 			break;
 		case 'H':
 			shutdown_do();
 			break;
 		case 'a':
-			nodeid = atoi (optarg);
+			if (util_strtonum(optarg, 1, UINT_MAX, &l) == -1) {
+				fprintf(stderr, "The nodeid was not valid, try a positive number\n");
+				exit(EXIT_FAILURE);
+			}
+			nodeid = l;
 			showaddrs_do(nodeid);
 			break;
 		case 'h':

+ 7 - 8
tools/corosync-quorumtool.c

@@ -48,6 +48,7 @@
 #include <corosync/cmap.h>
 #include <corosync/quorum.h>
 #include <corosync/votequorum.h>
+#include "util.h"
 
 typedef enum {
 	NODEID_FORMAT_DECIMAL,
@@ -879,7 +880,6 @@ static void close_all(void) {
 
 int main (int argc, char *argv[]) {
 	const char *options = "VHaslpmfe:v:hin:o:";
-	char *endptr;
 	int opt;
 	int votes = 0;
 	int ret = 0;
@@ -890,7 +890,7 @@ int main (int argc, char *argv[]) {
 	command_t command_opt = CMD_SHOWSTATUS;
 	sorttype_t sort_opt = SORT_ADDR;
 	char sortchar;
-	long int l;
+	long long int l;
 
 	if (init_all()) {
 		close_all();
@@ -930,11 +930,11 @@ int main (int argc, char *argv[]) {
 			break;
 		case 'e':
 			if (using_votequorum() > 0) {
-				votes = strtol(optarg, &endptr, 0);
-				if ((votes == 0 && endptr == optarg) || votes <= 0) {
+				if (util_strtonum(optarg, 1, INT_MAX, &l) == -1) {
 					fprintf(stderr, "New expected votes value was not valid, try a positive number\n");
 					exit(EXIT_FAILURE);
 				} else {
+					votes = l;
 					command_opt = CMD_SETEXPECTED;
 				}
 			} else {
@@ -943,8 +943,7 @@ int main (int argc, char *argv[]) {
 			}
 			break;
 		case 'n':
-			l = strtol(optarg, &endptr, 0);
-			if ((l == 0 && endptr == optarg) || l < 0) {
+			if (util_strtonum(optarg, 1, UINT_MAX, &l) == -1) {
 				fprintf(stderr, "The nodeid was not valid, try a positive number\n");
 				exit(EXIT_FAILURE);
 			}
@@ -953,11 +952,11 @@ int main (int argc, char *argv[]) {
 			break;
 		case 'v':
 			if (using_votequorum() > 0) {
-				votes = strtol(optarg, &endptr, 0);
-				if ((votes == 0 && endptr == optarg) || votes < 0) {
+				if (util_strtonum(optarg, 0, INT_MAX, &l) == -1) {
 					fprintf(stderr, "New votes value was not valid, try a positive number or zero\n");
 					exit(EXIT_FAILURE);
 				} else {
+					votes = l;
 					command_opt = CMD_SETVOTES;
 				}
 			}

+ 35 - 0
tools/util.c

@@ -0,0 +1,35 @@
+#include <stdlib.h>
+#include <errno.h>
+
+#include "util.h"
+
+/*
+ * Safer wrapper of strtoll. Return 0 on success, otherwise -1.
+ * Idea from corosync-qdevice project
+ */
+int
+util_strtonum(const char *str, long long int min_val, long long int max_val,
+    long long int *res)
+{
+        long long int tmp_ll;
+        char *ep;
+
+        if (min_val > max_val) {
+                return (-1);
+        }
+
+        errno = 0;
+
+        tmp_ll = strtoll(str, &ep, 10);
+        if (ep == str || *ep != '\0' || errno != 0) {
+                return (-1);
+        }
+
+        if (tmp_ll < min_val || tmp_ll > max_val) {
+                return (-1);
+        }
+
+        *res = tmp_ll;
+
+        return (0);
+}

+ 15 - 0
tools/util.h

@@ -0,0 +1,15 @@
+#ifndef COROSYNC_TOOLS_UTIL_H_DEFINED
+#define COROSYNC_TOOLS_UTIL_H_DEFINED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int              util_strtonum(const char *str, long long int min_val,
+    long long int max_val, long long int *res);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COROSYNC_TOOLS_UTIL_H_DEFINED */