[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Secure Dereference of NULL-Pointer when using list.h



On 10/5/06, Ricard Wanderlof <ricard.wanderlof@xxxxxxxx> wrote:
You may be right. Reading standards is hairy and I would also consider the
interpretation "evaluate the expression and discard the value" valid.
Although I'm nitpicking here, say if foo were a hardware register which
had a side effect of some sorts when reading it, then the statement *foo;
would actually do something even though the value wouldn't be used (better
declare foo volatile too to make sure the compiler doesn't optimize it
away).
Yes, you are right! If you declare foo to be volatile, indeed its
value is must be read.


In any case, I wouldn't like to let a line like


*( (char *) 0);
In this case we only need to write this as:

*( (volatile char *) 0);

But unlike the value, the address is not volatile. It's not a variable. So,

&(*( (volatile char *) 0));

will still have no side effect. Only the char is volatile, not the
address, right? So,

s->foo; // fetches the value of foo(ideally)

&(s->foo); // will not fetch the value of foo - only compute its
address - since, computing the address of foo (here, by reading the
variable s) has no operation over the value of foo. So, this
expression must have side effect only upon 's', if there ever is any.


pass by the compiler, whether or not the actual compiler conforms to the standard, whichever the interpretation of the standard may be. It's one of the situations that I would imagine a compiler designer could get wrong, regardless what the standard says...

In support of your point,


======Page 108========

An object that has volatile-qualiïed type may be modiïed in ways
unknown to the implementation or have other unknown side effects.
Therefore any expression referring to such an object shall be
evaluated strictly according to the rules of the abstract machine, as
described in 5.1.2.3.
...
What constitutes an access to an object that has volatile-qualiïed
type is implementation-deïned.

======end=========

According to section 5.1.2.3

========Page 13============

Accessing a volatile object, modifying an object, modifying a ïle, or
calling a function that does any of those operations are all side
effects, which are changes in the state of the execution environment.
Evaluation of an expression may produce side effects. At certain
speciïed points in the execution sequence called sequence points, all
side effects of previous evaluations shall be complete and no side
effects of subsequent evaluations shall have taken place.
...

In the abstract machine, all expressions are evaluated as speciïed by
the semantics. An actual implementation need not evaluate part of an
expression if it can deduce that its value is not used and that no
needed side effects are produced (including any caused by calling a
function or accessing a volatile object).

========end==========

So I believe that in a recommended implementation,

a;

must fetch the value of 'a', though it should be discarded. But then
the compiler in our case optimises it (by not reading 'a'), unless 'a'
is declared as 'volatile'.

Thank you for pointing out this really nice one.

Regards,
Jinesh.

z¹Þw°n'¬éiy§!¢Ø^®Wš®v›¢ëm…ââžìdz¹Þ
Ü+ÞÛiÿùšŠYå–)îÆàþG«ég{âzÏÅm¶Ÿÿ‘êçzYÞÁž²Šàýöª