cluster: RHEL510 - ccs_tool: fix several segfaults

Jan Pokorný jpokorny at fedoraproject.org
Wed Apr 17 13:36:48 UTC 2013


Gitweb:        http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=d55fe105fd6c3dc5ceafb60e08880a5653440732
Commit:        d55fe105fd6c3dc5ceafb60e08880a5653440732
Parent:        07766f691733c71344a703eff31636fac3ca1d30
Author:        Jan Pokorný <jpokorny at redhat.com>
AuthorDate:    Wed Apr 17 15:21:54 2013 +0200
Committer:     Jan Pokorný <jpokorny at redhat.com>
CommitterDate: Wed Apr 17 15:21:54 2013 +0200

ccs_tool: fix several segfaults

(1) input file = output file and subcommand gets some options
(2) update gets no input file
+ several overflows in case the output file was specified explicitly
  and contained, as a global path, around 255 bytes or more

Signed-off-by: Jan Pokorný <jpokorny at redhat.com>
---
 ccs/ccs_tool/ccs_tool.c |    2 +-
 ccs/ccs_tool/update.c   |   28 ++++++++++++++++++++--------
 2 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/ccs/ccs_tool/ccs_tool.c b/ccs/ccs_tool/ccs_tool.c
index 5fcd667..bde7d30 100644
--- a/ccs/ccs_tool/ccs_tool.c
+++ b/ccs/ccs_tool/ccs_tool.c
@@ -12,7 +12,7 @@ static void print_usage(FILE *stream);
 
 int main(int argc, char *argv[])
 {
-  optind = 1;
+  /* implicitly initialized by the library: optind = 1; */
 
   if (argc < 2 || !strcmp(argv[optind], "-h")) {
       print_usage(stdout);
diff --git a/ccs/ccs_tool/update.c b/ccs/ccs_tool/update.c
index 3af779b..c6f4362 100644
--- a/ccs/ccs_tool/update.c
+++ b/ccs/ccs_tool/update.c
@@ -15,6 +15,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <ctype.h>
+#include <getopt.h>
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 #include <libxml/xpath.h>
@@ -117,6 +118,7 @@ static int parse_args(int argc, char **argv, char **loc)
 {
   int c, error, ret;
 
+  optind = 1;  /* reset the global for getopt from previous use */
   while ((c = getopt(argc, argv, "P:")) != EOF) {
     switch(c) {
     case 'P':
@@ -191,19 +193,28 @@ int update2(int argc, char **argv)
 
   struct timeval tv;
 
-  if (parse_args(argc, argv, &location))
+  if (parse_args(argc, argv, &location) || !location) {
+    if (!location)
+      fprintf(stderr, "Source configuration file not specified.\n");
     return -1;
+  }
 
   if (location[0] != '/') {
-    memset(true_location, 0, 256);
-    if (!getcwd(true_location, 256)) {
+    if (!getcwd(true_location, sizeof(true_location))) {
       fprintf(stderr, "Unable to get the current working directory.\n");
       return -errno;
     }
-    true_location[strlen(true_location)] = '/';
-    strncpy(true_location+strlen(true_location), location, 256-strlen(true_location));
+    i = (int) strlen(true_location);
+    if (i >= sizeof(true_location) - 2
+        || strlen(location) + i > sizeof(true_location) - 2) {
+      /* tl[254]='/', tl[255]=first char of location ... nul-termination? */
+      fprintf(stderr, "Overly nested location a/o a long relative path.\n");
+      return -1;
+    }
+    true_location[i] = '/';
+    strcpy(true_location + (i+1), location);
   } else {
-    strncpy(true_location, location, 256);
+    true_location[0] = '\0';
   }
 
   desc = ccs_connect();
@@ -232,10 +243,11 @@ int update2(int argc, char **argv)
   v1 = atoi(v1_str);
   free(v1_str);
 
-  doc = xmlParseFile(true_location);
+  doc = xmlParseFile(true_location[0] ? true_location : location);
 
   if (!doc) {
-    fprintf(stderr, "Unable to parse %s\n", true_location);
+    fprintf(stderr, "Unable to parse %s\n",
+            true_location[0] ? true_location : location);
     return -EINVAL;
   }
 


More information about the cluster-commits mailing list