31caedf
From 529c79dcfb0dc20c123865d1caf1142b085080d5 Mon Sep 17 00:00:00 2001
31caedf
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
31caedf
Date: Wed, 15 Feb 2017 15:05:35 +0100
31caedf
Subject: [PATCH] Fix parsing wmfrog arguments
31caedf
MIME-Version: 1.0
31caedf
Content-Type: text/plain; charset=UTF-8
31caedf
Content-Transfer-Encoding: 8bit
31caedf
31caedf
A command like "wmfrog -s KSEA -o 7 -tmp /home/stela010/tmp/wmfrog"
31caedf
crashed because the -tmp argument was bigger than a static buffer used
31caedf
for storing the argument value. There were similar issues with other
31caedf
argument values.
31caedf
31caedf
This patch fixes it. It also fixes the fact that -tmp argument was
31caedf
always ignored and user's home directory was used instead.
31caedf
31caedf
<https://bugzilla.redhat.com/show_bug.cgi?id=1422319>
31caedf
31caedf
Signed-off-by: Petr Písař <ppisar@redhat.com>
31caedf
---
31caedf
 Src/wmFrog.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++-----------
31caedf
 1 file changed, 54 insertions(+), 12 deletions(-)
31caedf
31caedf
diff --git a/Src/wmFrog.c b/Src/wmFrog.c
31caedf
index 24f795c..c422e55 100644
31caedf
--- a/Src/wmFrog.c
31caedf
+++ b/Src/wmFrog.c
31caedf
@@ -12,6 +12,7 @@
31caedf
 /*
31caedf
  *   Includes
31caedf
  */
31caedf
+#define _XOPEN_SOURCE 500 /* For strdup(3) */
31caedf
 #include <signal.h>
31caedf
 #include <stdio.h>
31caedf
 #include <math.h>
31caedf
@@ -74,7 +75,7 @@ int NeedsUpdate = 1;
31caedf
 int maxWind = MAX_WIND;
31caedf
 int timeOffset = TIME_OFFSET;
31caedf
 long UpdateDelay;
31caedf
-char* folder;
31caedf
+char* folder = NULL;
31caedf
 int needsUpdate = 1;
31caedf
 
31caedf
 /*
31caedf
@@ -91,7 +92,9 @@ int main(int argc, char *argv[]) {
31caedf
      */
31caedf
     ParseCMDLine(argc, argv);
31caedf
 
31caedf
-    folder = GetTempDir(".wmapps");
31caedf
+    if (NULL == folder) {
31caedf
+        folder = GetTempDir(".wmapps");
31caedf
+    }
31caedf
 
31caedf
     initXwindow(argc, argv);
31caedf
 
31caedf
@@ -343,7 +346,11 @@ void ParseCMDLine(int argc, char *argv[]) {
31caedf
                 print_usage();
31caedf
                 exit(-1);
31caedf
             }
31caedf
-            strcpy(folder, argv[++i]);
31caedf
+            folder = strdup(argv[++i]);
31caedf
+            if (NULL == folder) {
31caedf
+                fprintf(stderr, "Not enough memory to copy -tmp argument.\n");
31caedf
+                exit(-1);
31caedf
+            }
31caedf
 
31caedf
 
31caedf
         } else if ((!strcmp(argv[i], "-station")) || (!strcmp(argv[i], "-s"))) {
31caedf
@@ -352,6 +359,10 @@ void ParseCMDLine(int argc, char *argv[]) {
31caedf
                 print_usage();
31caedf
                 exit(-1);
31caedf
             }
31caedf
+            if (strlen(argv[i + 1]) >= sizeof(StationID)/sizeof(*StationID) - 1) {
31caedf
+                fprintf(stderr, "METAR station ID is too long.\n");
31caedf
+                exit(-1);
31caedf
+            }
31caedf
             strcpy(StationID, StringToUpper(argv[++i]));
31caedf
             strcpy(Label, StationID);
31caedf
         } else if (!strcmp(argv[i], "-delay")) {
31caedf
@@ -377,6 +388,10 @@ void ParseCMDLine(int argc, char *argv[]) {
31caedf
                 print_usage();
31caedf
                 exit(-1);
31caedf
             }
31caedf
+            if (strlen(argv[i + 1]) >= sizeof(Label)/sizeof(*Label) - 1) {
31caedf
+                fprintf(stderr, "Station label is too long.\n");
31caedf
+                exit(-1);
31caedf
+            }
31caedf
             strcpy(Label, StringToUpper(argv[++i]));
31caedf
         }
31caedf
     }
31caedf
@@ -454,7 +469,8 @@ double UT;
31caedf
 // Will be called at regular interval to update the weather data (alarm)
31caedf
 
31caedf
 void UpdateData() {
31caedf
-    char command[1024], Line[512], FileName[128];
31caedf
+    char *command, Line[512], *FileName;
31caedf
+    const char weatherPlScript[] = "/usr/lib/wmfrog/weather.pl";
31caedf
     int ign;
31caedf
     char* igns;
31caedf
     igns = (char*) malloc(512);
31caedf
@@ -492,13 +508,29 @@ void UpdateData() {
31caedf
     /*
31caedf
      *  Execute Perl script to grab the Latest METAR Report
31caedf
      */
31caedf
-    snprintf(command, 1024, "/usr/lib/wmfrog/weather.pl %s %s", StationID, folder);
31caedf
-    //printf("Retrieveing data\n");
31caedf
-    ign = system(command);
31caedf
-    snprintf(FileName, 128, "%s/%s", folder, StationID);
31caedf
-    //fprintf(stderr,"%s\n\n",FileName);
31caedf
+    command = malloc(strlen(weatherPlScript) + 1 + strlen(StationID) + 1
31caedf
+            + strlen(folder) + 1);
31caedf
+    if (NULL == command) {
31caedf
+        fprintf(stderr, "Not enough memory to build wheater.pl command.\n");
31caedf
+    } else {
31caedf
+        sprintf(command, "%s %s %s", weatherPlScript, StationID, folder);
31caedf
+        //printf("Retrieveing data\n");
31caedf
+        ign = system(command);
31caedf
+        free(command);
31caedf
+    }
31caedf
+
31caedf
+    FileName = malloc(strlen(folder) + 1 + strlen(StationID) + 1);
31caedf
+    if (NULL == FileName) {
31caedf
+        fprintf(stderr, "Not enough memory to build staion ID file name.\n");
31caedf
+        fp = NULL;
31caedf
+    } else {
31caedf
+        sprintf(FileName, "%s/%s", folder, StationID);
31caedf
+        //fprintf(stderr,"%s\n\n",FileName);
31caedf
+        fp = fopen(FileName, "r");
31caedf
+        free(FileName);
31caedf
+    }
31caedf
 
31caedf
-    if ((fp = fopen(FileName, "r")) != NULL) {
31caedf
+    if (fp != NULL) {
31caedf
         ign = fscanf(fp, "Hour:%d", &weather.hour);
31caedf
         igns = fgets(Line, 512, fp); //h
31caedf
         ign = fscanf(fp, "Minute:%d", &weather.min);
31caedf
@@ -620,11 +652,21 @@ void UpdateData() {
31caedf
 char *GetTempDir(char *suffix) {
31caedf
     uid_t id;
31caedf
     struct passwd *userEntry;
31caedf
-    static char userHome[128];
31caedf
+    char *userHome;
31caedf
 
31caedf
     id = getuid();
31caedf
     userEntry = getpwuid(id);
31caedf
-    snprintf(userHome, 128, "%s/%s", userEntry->pw_dir, suffix);
31caedf
+    if (NULL == userEntry) {
31caedf
+        perror("Could not retrieve user's passwd entry");
31caedf
+        exit(-1);
31caedf
+    }
31caedf
+
31caedf
+    userHome = malloc(strlen(userEntry->pw_dir) + 1 + strlen(suffix) + 1);
31caedf
+    if (NULL == userHome) {
31caedf
+        fprintf(stderr, "Not enough memory for building temporary path.\n");
31caedf
+        exit(-1);
31caedf
+    }
31caedf
+    sprintf(userHome, "%s/%s", userEntry->pw_dir, suffix);
31caedf
     return userHome;
31caedf
 }
31caedf
 
31caedf
-- 
31caedf
2.7.4
31caedf