From 8ee7fae5f65a2bcce5a4201ddab63d32d9b59a16 Mon Sep 17 00:00:00 2001 From: Guido Vranken Date: Thu, 8 Jun 2017 01:02:38 +0200 Subject: [PATCH] Ensure option array p[] is always NULL-terminated 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 Acked-by: Gert Doering Message-Id: URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14757.html Signed-off-by: Gert Doering (cherry picked from commit 8b03d3d9307b407b0da98ebefb052b1fa87aefe7) --- src/openvpn/options.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 32b4961ba..aff77c496 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -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); } -- 2.47.2