fix memory overflow in ecpg preproc module

From: "Liu, Huailing" <liuhuailing(at)cn(dot)fujitsu(dot)com>
To: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: fix memory overflow in ecpg preproc module
Date: 2019-04-03 09:55:47
Message-ID: 1ED61871BE2DAD4CAC7B48AE8D08956101BF3B0D35@G08CNEXMBPEKD01.g08.fujitsu.local
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi, everyone

I have found a potential memory overflow in ecpg preproc module.

Here is:

https://github.com/postgres/postgres/blob/REL9_5_16/src/interfaces/ecpg/preproc/pgc.l

In parse_include() function
-------------------------------------------------------------------
for (ip = include_paths; yyin == NULL && ip != NULL; ip = ip->next)
{
if (strlen(ip->path) + strlen(yytext) + 3 > MAXPGPATH) ★1 forget to count the length of char '\0'.
{
fprintf(stderr, _("Error: include path \"%s/%s\" is too long on line %d, skipping\n"), ip->path, yytext, yylineno);
continue;
}
snprintf (inc_file, sizeof(inc_file), "%s/%s", ip->path, yytext);
yyin = fopen(inc_file, "r");
if (!yyin)
{
if (strcmp(inc_file + strlen(inc_file) - 2, ".h") != 0)
{
strcat(inc_file, ".h"); ★2
yyin = fopen( inc_file, "r" );
}
}
-----------------------------------------------------------------------
For example
(1)ecpg program has below statement
EXEC SQL INCLUDE “abbbbbbbbcd”
filename's length is 11.
(2)using ecpg -I command to Specify an additional include path
an additional include path's length is 1010
ex:/file1/ssssssss/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a
/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a
/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a
/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a
/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a
/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a
/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a
/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a
/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a
/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a

After entering the parse_include(), the roadmap of excuting is as follows.
1. When excuting the marked★1 code, strlen(ip->path) is 1010, and strlen(yytext) is 11.
So the total length (strlen(ip->path) + strlen(yytext) + 3 ) is 1024.
As MAXPGPATH is 1024, the error is not be throwed.
2. When excuting the marked★2 code, the string stored in the variable inc_file is as follows.

inc_file[0]:'f'
inc_file[1]:'i'
....
inc_file[1022]:'.'
inc_file[1023]:'h' ====>there is no space for the char '\0'.

Last, it is easy to fix, here is a solution patch.

--
以上
Liu Huailing
--------------------------------------------------
Liu Huailing
Development Department III
Software Division II
Nanjing Fujitsu Nanda Software Tech. Co., Ltd.(FNST)
ADDR.: No.6 Wenzhu Road, Software Avenue,
Nanjing, 210012, China
TEL : +86+25-86630566-8439
COINS: 7998-8439
FAX : +86+25-83317685
MAIL : liuhuailing(at)cn(dot)fujitsu(dot)com
--------------------------------------------------

Attachment Content-Type Size
pgl.pl.patch application/octet-stream 573 bytes

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Julien Rouhaud 2019-04-03 09:56:14 Re: Checksum errors in pg_stat_database
Previous Message Daniel Gustafsson 2019-04-03 09:38:57 Re: Simplify redability of some tests for toast_tuple_target in strings.sql