SOLVED Re: Memory leak in hush with NOMMU busybox-1.37.0

Henrique de Moraes Holschuh henrique at nic.br
Mon Aug 4 12:20:43 UTC 2025


Em 04/08/2025 08:15, Roberto A. Foglietta escreveu:
> On Mon, 4 Aug 2025 at 13:11, Denys Vlasenko <vda.linux at googlemail.com> wrote:
>> The correct fix is to specify the pointer in question as "volatile"
>> variable, so that gcc stops making assumptions about its liveness.
> 
> You are right as a manual, Denis.
> 
> ...but god knows what gcc does with a volatile which is not associated
> with a hardware I/O line. (LOL)

Compilers never cared about this.  "volatile" in C is very well defined: 
it simply means every time the memory location is accessed, the compiler 
must issue a fresh read.

And that's *all* it does, which is quite often "not enough".  It is 
indeed a real pitfall that has claimed a lot of victims over the years.

volatile isn't "read once" or "write once": the compiler can output code 
that will read a volatile variable many times even if the load shows up 
only once in the source code.  In fact, declaring something volatile 
INCREASES the chances the compiler will load it more than once.

volatile isn't a compile barrier: the compiler can still move the 
loads/stores to volatile variables around, unless something else in the 
code forbids it to.  It must not reorder loads and stores to the same 
volatile variable, and it must not elide loads because it just stored 
something and that data is still in a register, but that's it.

volatile loads and stores are not atomic, and they are not synchronizing 
(memory barriers) either.  A store to a volatile variable can result 
into the compiler generating read-modify-write code for some types, for 
example.  There is *nothing* in volatile that ensures no mixing of 
concurrent writes won't be observed by a concurrent reader.  Evidently, 
there is also no implied ordering between reads or writes from separate 
hardware threads.

Granted, some CPU architectures might give you atomic behavior on 
load/store of for some types "for free", and paper over *some* such bugs 
on code that misused volatile.  E.g. x86 and x86-64 are not going to 
allow a concurrent load to observe a mixed concurrent writes for aligned 
int32_t (among many other types).  This still gives you no 
synchronization, and a stored value by one hardware thread might take 
its sweet time to become visible to other hardware threads.

Now, when doing memory-mapped I/O, *SOME* architectures will have 
specific hardware access modes (e.g. uncached) for that address space 
region, which may paper over some of the above issues.  Some would call 
C code that depends on such behavior buggy.


So, when two threads of execution could access the same memory location 
(and that certainly includes parent and child from fork() and friends), 
if any of these accesses could be a store or you need ordering of any 
sort, you will most likely need more than just "volatile" to ensure it 
will always behave as intended.

-- 
Henrique de Moraes Holschuh
Analista de Projetos
Centro de Estudos e Pesquisas em Tecnologias de Redes e Operações 
(Ceptro.br)
+55 11 5509-3537 R.:4023
INOC 22548*625
www.nic.br


More information about the busybox mailing list