Re: BUG #16186: The usage of undefined value in pgbench.c - Mailing list pgsql-bugs

From Fabien COELHO
Subject Re: BUG #16186: The usage of undefined value in pgbench.c
Date
Msg-id alpine.DEB.2.21.2001060824350.24609@pseudo
Whole thread Raw
In response to BUG #16186: The usage of undefined value in pgbench.c  (PG Bug reporting form <noreply@postgresql.org>)
List pgsql-bugs
你好 Jian,

> Bug reference:      16186
> Logged by:          Jian Zhang
> Email address:      starbugs@qq.com
> PostgreSQL version: 12.1
> Operating system:   Linux
> Description:
>
> We checked the code in file “pgbench.c” and there are three errors occurring
> in lines 1900, 2100 and 2357 in function evalStandardFunc.

> All the three errors are caused by the usage of variables with undefined 
> values.

The word "usage" suggest that they are actually used, but I do not think 
that it is the case.

> Firstly, in line 1900, the code is “if ((lval->type == PGBT_DOUBLE || 
> rval->type == PGBT_DOUBLE) && func != PGBENCH_MOD)”. The pointer “lval” 
> mentioned in this line is defined by the code in line 1894 as 
> “PgBenchValue *lval = &vargs[0], *rval = &vargs[1];”, so it is assigned 
> as the address of “vargs[0]”.

Yes. So?

The vargs array is initialized at the beginning of the function in a for 
loop, as you noted below.

The expression parser checks that the number of arguments is okay for each 
function/operator (the arity is stored PGBENCH_FUNCTIONS array in 
"exprparse.y" and checked in "make_func" default case in switch), so that 
for all the functions of the case at hand we know that there have two 
arguments, so vargs[0] and vargs[1] contents will be defined.

There is also an assert on nargs to cover that, just in case.

If there NULL they are dealt with at the beginning of the function 
(has_null), and NO_VALUE is never used, so the type must be defined to 
something.

Maybe some assert could be moved before the declarations for the 
principle, but when the code was written pg was not C99 yet.

> Secondly, in line 2100, the code is “if (varg->type == PGBT_INT)”.    The
> pointer “varg” mentioned in this line is defined by the code in line 2096:
> “PgBenchValue *varg = &vargs[0];”, so it is also assigned as the address of
> “vargs[0]”.

Same analysis: exprparse checked that abs has one arg, and moreover 
there is an assert to cover it again.

> Lastly, in line 2357, the code is “vargs[0].type == vargs[1].type 
> &&vargs[0].u.bval == vargs[1].u.bval);”. The 1st and 2nd elements of 
> array “vargs” is directly used without confirming weather the array is 
> correctly defined or not.

Same analysis.

Ok, the "bval" access is doubtful because we do not know whether it is 
actually a boolean. I'll think about it.

> The array “vargs” is defined by the code “PgBenchValue 
> vargs[MAX_FARGS];” in line 1855 and is initialized in the function of 
> “evaluateExpr” in line 1861, the code is “if (!evaluateExpr(st, l->expr, 
> &vargs[nargs]))”. So the assignment of array “vargs” depends on both the 
> input pointer “st” and the pointer “I” defined by the input parameter 
> “args”. All the input parameters of function “evalStandardFunc” are 
> listed in line 1849. The code is “evalStandardFunc(CState *st, 
> PgBenchFunction func, PgBenchExprLink *args, PgBenchValue *retval)”. The 
> program should check the effectiveness of input parameters “st” and 
> “args” to avoid these three errors.

AFAICS, this is done by the parser, and again with asserts on nargs.

So I do not think that there is an actual bug, although the why requires 
advanced interprocedural analyses.

Maybe the bval access could be rethought, though.

-- 
Fabien.

pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: [bug report] A sql statements make query hang
Next
From: PG Bug reporting form
Date:
Subject: BUG #16192: Function to_char(date,'IW') return incorrect value for last days of a year