]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Ensure option array p[] is always NULL-terminated
authorGuido Vranken <guidovranken@gmail.com>
Wed, 7 Jun 2017 23:02:38 +0000 (01:02 +0200)
committerGert Doering <gert@greenie.muc.de>
Mon, 12 Jun 2017 13:28:47 +0000 (15:28 +0200)
Add one element (a terminating NULL pointer) to the array into
which parse_line() stores the arguments. This prevents that options
that traverse this array until a terminator is seen (for instance
options that call no_more_than_n_args) will peek beyond buffer bounds.
In the worst case this might lead to a crash (stack overflow, not
likely in practice).

Signed-off-by: Guido Vranken <guidovranken@gmail.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <CAO5O-EKCLjPpdKUH6cCoqoZDAfekSafpc7Ga55H2_5Hs4rBopg@mail.gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14757.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit 8b03d3d9307b407b0da98ebefb052b1fa87aefe7)

src/openvpn/options.c

index 32b4961ba690a969ed831fe56d02236ec0747ad0..aff77c496a695439a6a15346a79c20ec4ef3cafd 100644 (file)
@@ -3891,7 +3891,7 @@ read_config_file (struct options *options,
   FILE *fp;
   int line_num;
   char line[OPTION_LINE_SIZE+1];
-  char *p[MAX_PARMS];
+  char *p[MAX_PARMS+1];
 
   ++level;
   if (level <= max_recursive_levels)
@@ -3915,7 +3915,7 @@ read_config_file (struct options *options,
               /* Ignore UTF-8 BOM at start of stream */
               if (line_num == 1 && strncmp (line, "\xEF\xBB\xBF", 3) == 0)
                 offset = 3;
-              if (parse_line (line + offset, p, SIZE (p), file, line_num, msglevel, &options->gc))
+              if (parse_line (line + offset, p, SIZE (p)-1, file, line_num, msglevel, &options->gc))
                {
                  bypass_doubledash (&p[0]);
                  check_inline_file_via_fp (fp, p, &options->gc);
@@ -3955,10 +3955,10 @@ read_config_string (const char *prefix,
 
   while (buf_parse (&multiline, '\n', line, sizeof (line)))
     {
-      char *p[MAX_PARMS];
+      char *p[MAX_PARMS+1];
       CLEAR (p);
       ++line_num;
-      if (parse_line (line, p, SIZE (p), prefix, line_num, msglevel, &options->gc))
+      if (parse_line (line, p, SIZE (p)-1, prefix, line_num, msglevel, &options->gc))
        {
          bypass_doubledash (&p[0]);
          check_inline_file_via_buf (&multiline, p, &options->gc);
@@ -4039,10 +4039,10 @@ apply_push_options (struct options *options,
 
   while (buf_parse (buf, ',', line, sizeof (line)))
     {
-      char *p[MAX_PARMS];
+      char *p[MAX_PARMS+1];
       CLEAR (p);
       ++line_num;
-      if (parse_line (line, p, SIZE (p), file, line_num, msglevel, &options->gc))
+      if (parse_line (line, p, SIZE (p)-1, file, line_num, msglevel, &options->gc))
        {
          add_option (options, p, file, line_num, 0, msglevel, permission_mask, option_types_found, es);
        }