NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: lib/58136 (Use after free in libintl pgettext)
> On Aug 19, 2024, at 7:50 AM, gnats-admin%netbsd.org@localhost wrote:
>
> The following reply was made to PR lib/58136; it has been noted by GNATS.
>
> From: Paul Ripke <stix%stix.id.au@localhost>
> To: gnats-bugs%netbsd.org@localhost
> Cc:
> Subject: Re: lib/58136 (Use after free in libintl pgettext)
> Date: Mon, 19 Aug 2024 21:45:04 +1000
>
> From my reading of C's behaviour, dereferencing a freed pointer is undefined
> behaviour, obviously. But using the pointer value should not be? Indeed, when
> compiled with clang/llvm, your code results in only one call to free.
In N1256 (a C99 draft) section 6.2.4p2, it says
The /lifetime/ of an object is the portion of program execution during which
storage is guaranteed to be reserved for it. An object exists, has a constant
address,^25) and retains its last-stored value throughout its lifetime.^26) If
an object is referred to outside of its lifetime, the behavior is undefined. The
value of a pointer becomes indeterminate when the object it points to
reaches the end of its lifetime.
Section 7.20.3 describes the malloc, calloc, realloc, and free functions. Section
7.20.3p1 contains the sentence
The lifetime of an allocated object extends from the allocation until the
deallocation.
Section 3.17.2 defines "indeterminate value" as
either an unspecified value or a trap representation
Section 3.17.3 defines "unspecified value" as
valid value of the relevant type where this International Standard imposes
no requirements on which value is chosen in any instance
NOTE An unspecified value cannot be a trap representation
Putting this together, we can see that accessing the value of a pointer after
it has been freed can result in a meaningless value or a trap.
ANSI C says something slightly different. Section 6.1.2.4 of ANSI C says
An object has a /storage duration/ that determines its lifetime. There are
two storage durations: static and automatic.
An object whose identifier is declared with external or internal linkage, or
with the storage-class specifier static has /static storage duration/. For such
an object, storage is reserved and its stored value is initialized only once,
prior to program startup. The object exists and retains its last-stored value
throughout the execution of the program.^15
An object whose identifier is declared with no linkage and without the
storage-class specifier static has /automatic storage duration/. Storage is
guaranteed to be reserved for a new instance of such an object on each
normal entry into the block with which it is associated, or on a jump from
outside the block to a labeled statement in the block or in an enclosed
block. In an initialization is specified for the value stored in the object, it is
performed on each normal entry, but not if the block is entered by a jump
to a labeled statement. Storage for the object is no longer guaranteed to
be reserved when execution of a block ends in any way. (Entering an
enclosed block suspends but does not end execution of the enclosing
block. Calling a function suspends but does not end execution of the
block containing the call.) The value of a pointer that referred to an object
with automatic storage duration that is no longer guaranteed to be
reserved is indeterminate.
Section 7.10.3 addresses malloc, calloc, realloc and free, and contains
the sentence
The value of a pointer that refers to freed space is indeterminate.
Section 3.16 defines "undefined behavior" as
Behavior, upon use of a nonportable or erroneous program construct,
of erroneous data, or of indeterminately valued objects, for which this
International Standard imposes no requirements. Permissible undefined
behavior ranges from ignoring the situation completely with unpredictable
results, to behaving during translation or program execution in a
documented manner characteristic of the environment (with or without
issuance of a diagnostic message), to terminating a translation or
execution (with the issuance of a diagnostic message).
If a "shall" or "shall not" requirement that appears outside of a constraint
is violated, the behavior is undefined. Undefined behavior is otherwise
indicated in this International Standard by the words "undefined behavior"
or by the omission of any explicit definition of behavior. There is no
difference in emphasis among these three; they all describe "behavior
that is undefined."
Putting these together, we see that accessing a pointer after is has been freed is undefined behavior in ANSI C.
> Agreed on the missing test, though. This code is old and crufty, does it have
> any coverage at all? I didn't see any after a brief look.
>
> --
> Paul Ripke
> "Great minds discuss ideas, average minds discuss events, small minds
> discuss people."
> -- Disputed: Often attributed to Eleanor Roosevelt. 1948.
>
Home |
Main Index |
Thread Index |
Old Index