[m-rev.] diff: Fix problems parsing environment options.

Peter Wang novalazy at gmail.com
Mon Jul 23 11:04:21 AEST 2018


runtime/mercury_wrapper.c:
    Fix wrong size argument in calls to snprintf.

    Fix use-after-free if there is an error while parsing environment
    options.
---
 runtime/mercury_wrapper.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/runtime/mercury_wrapper.c b/runtime/mercury_wrapper.c
index 7d88229e7..cac03f1e9 100644
--- a/runtime/mercury_wrapper.c
+++ b/runtime/mercury_wrapper.c
@@ -1076,22 +1076,20 @@ MR_process_environment_options(void)
     prog_env_option_name = MR_GC_NEW_ARRAY(char, prog_env_option_name_len);
     strcpy(prog_env_option_name, MERCURY_OPTIONS);
     prog_env_option_name[mercury_options_len] = '_';
     strcpy(prog_env_option_name + mercury_options_len + 1, progname);
 
     prog_env_options = getenv(prog_env_option_name);
     if (prog_env_options == NULL) {
         prog_env_options = (char *) "";
     }
 
-    MR_GC_free(prog_env_option_name);
-
     if (gen_env_options[0] != '\0' || prog_env_options[0] != '\0'
         || MR_runtime_flags[0] != '\0')
     {
         const char  *dummy_cmd;
         int         dummy_cmd_len;
         char        *dummy_command_line;
         int         dummy_command_line_len;
         char        *option_arg_str;
         char        **option_argv;
         int         option_argc;
@@ -1148,57 +1146,58 @@ MR_process_environment_options(void)
         printf("MR_runtime_flags = <%s>\n", MR_runtime_flags);
         printf("gen_env_options = <%s>\n", gen_env_options);
         printf("prog_env_options = <%s>\n", prog_env_options);
         printf("dummy_command_line = <%s>\n", dummy_command_line);
 #endif
 
         error_msg = MR_make_argv(dummy_command_line, &option_arg_str,
             &option_argv, &option_argc);
         if (error_msg != NULL) {
             char    *where_buf;
-            int     where_buf_next;
+            int     where_buf_cur;
 
             where_buf = MR_GC_NEW_ARRAY(char, WHERE_BUF_SIZE);
             where_buf[0] = '\0';
-            where_buf_next = strlen(where_buf);
+            where_buf_cur = 0;
 
             if (gen_env_options[0] != '\0') {
-                snprintf(where_buf + where_buf_next, WHERE_BUF_SIZE,
-                    "%sthe %s environment variable",
-                    where_buf_next == 0 ? "" : " and/or ",
-                    MERCURY_OPTIONS);
-                where_buf_next = strlen(where_buf);
+                snprintf(where_buf, WHERE_BUF_SIZE,
+                    "the %s environment variable", MERCURY_OPTIONS);
             }
 
             if (prog_env_options[0] != '\0') {
-                snprintf(where_buf + where_buf_next, WHERE_BUF_SIZE,
+                where_buf_cur = strlen(where_buf);
+                snprintf(where_buf + where_buf_cur,
+                    WHERE_BUF_SIZE - where_buf_cur,
                     "%sthe %s environment variable",
-                    where_buf_next == 0 ? "" : " and/or ",
+                    where_buf_cur == 0 ? "" : " and/or ",
                     prog_env_option_name);
-                where_buf_next = strlen(where_buf);
             }
 
             if (MR_runtime_flags[0] != '\0') {
-                snprintf(where_buf + where_buf_next, WHERE_BUF_SIZE,
+                where_buf_cur = strlen(where_buf);
+                snprintf(where_buf + where_buf_cur,
+                    WHERE_BUF_SIZE - where_buf_cur,
                     "%sthe runtime options built into the executable",
-                    where_buf_next == 0 ? "" : " and/or ");
-                where_buf_next = strlen(where_buf);
+                    where_buf_cur == 0 ? "" : " and/or ");
             }
 
             MR_fatal_error("error parsing %s:\n%s\n", where_buf, error_msg);
         }
 
         MR_GC_free(dummy_command_line);
         MR_process_options(option_argc, option_argv);
         MR_GC_free(option_arg_str);
         MR_GC_free(option_argv);
     }
+
+    MR_GC_free(prog_env_option_name);
 }
 
 enum MR_long_option {
     MR_HEAP_SIZE = 256,
     MR_HEAP_SIZE_KWORDS,
     MR_DETSTACK_SIZE,
     MR_DETSTACK_SIZE_KWORDS,
     MR_NONDETSTACK_SIZE,
     MR_NONDETSTACK_SIZE_KWORDS,
     MR_SMALL_DETSTACK_SIZE,
-- 
2.18.0



More information about the reviews mailing list