public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed
@ 2023-10-10 14:13 sterpumihai at gmail dot com
  2023-10-10 19:05 ` [Bug libc/30958] " adhemerval.zanella at linaro dot org
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: sterpumihai at gmail dot com @ 2023-10-10 14:13 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

            Bug ID: 30958
           Summary: mkstemp always produces the same temp file if it's
                    removed
           Product: glibc
           Version: 2.40
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libc
          Assignee: unassigned at sourceware dot org
          Reporter: sterpumihai at gmail dot com
                CC: drepper.fsp at gmail dot com
  Target Milestone: ---

Hi,
I've actually dig this issue from binutils where the ar utility would
occasionally fail on my machine due to "ar.exe: could not create temporary file
whilst writing archive."
ar is basically using mkstemp to generate a temporary file.
When debugging I see that the same file name "stP1kAlM" is used for each ar
invocation. This was very strange to me so I wrote a small application using
mkstemp:


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char template[100];

int main()
{
  strncpy(template, "stXXXXXX", 11);
  mkstemp(template);
  printf("%s\n", template);
  return 0;
}

Each time I execute this I get a different file BUT if I remove the temporary
file at each step, exactly like ar does, I get the same temporary file all the
time. For instance, if the above code is in main.c

gcc main.c
a
del stP1kAlM && a
del stP1kAlM && a
del stP1kAlM && a
...

This makes the application generate the same "stP1kAlM" file.

I've tried looking into sysdeps/posix/tempname.c, I guess the function is
try_tempname_len. I understand that it wants to avoid producing the same random
file if it can be opened but what I don't understand is how the random seed is
always the same.
I mean, the seed seems to at least come from the virtual address of a local
variable ie.

random_value v = ((uintptr_t) &v) / alignof (max_align_t);

Additional information:
Using gcc from https://github.com/brechtsanders/winlibs_mingw
Reproducing with gcc 13.2 or 10.5 32 bit on Windows 10

I really wanted to get to the bottom of this myself but I'm fairly new to GNU.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
@ 2023-10-10 19:05 ` adhemerval.zanella at linaro dot org
  2023-10-11  4:09 ` sterpumihai at gmail dot com
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: adhemerval.zanella at linaro dot org @ 2023-10-10 19:05 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

Adhemerval Zanella <adhemerval.zanella at linaro dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |adhemerval.zanella at linaro dot o
                   |                            |rg

--- Comment #1 from Adhemerval Zanella <adhemerval.zanella at linaro dot org> ---
I think this can happen if ASLR is disabled, and if clock_gettime returns bogus
values (such as reported by gnulib commit on emacs
512e44adaebb3096ddd1bf564e679d06e0301616).  The getrandom usage by
use_getrandom is also wrong, it should be set to true if 'tryfunc !=
try_nocreate'.

At least on Linux, it should work most of time because ASLR will provide some
random bits (I am not sure about Windows).  In any case, although glibc
tempname.c is indeed wrong in some ways; if you are running MinGW you are most
likely using gnulib (which contains multiple fixes). I would suggest to update
the binutils gnulib version.

I will sync with gnulib and send a fix to glibc.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
  2023-10-10 19:05 ` [Bug libc/30958] " adhemerval.zanella at linaro dot org
@ 2023-10-11  4:09 ` sterpumihai at gmail dot com
  2023-10-11 10:23 ` fweimer at redhat dot com
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: sterpumihai at gmail dot com @ 2023-10-11  4:09 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

--- Comment #2 from Sterpu Mihai <sterpumihai at gmail dot com> ---
Hi and thank you for your quick response!

ASLR is certainly enabled on my machine. As proof, the following small
application:

```
#include <stdio.h>

int main()
{
  int x = &x;
  printf("%x\n",x);
  return 0;
}
```

will produce different outputs when being compiled with either gcc 10.5 or
13.5.

```
D:\temp\1010>a
927ffb6c

D:\temp\1010>a
19dffe4c

D:\temp\1010>a
39dffbbc

D:\temp\1010>a
1c1ff8ec

D:\temp\1010>a
603ff66c

D:\temp\1010>
```

From what I see, this is the first level of entropy that mkstemp makes use of -
regardless if inside function random_bits the __getrandom or __clock_gettime64
are reached.
Therefore, I cannot possibly explain how the same temporary file name is
produced - IF this code would actually execute on Windows.

HOWEVER, I did check gnulib like you suggested ie.
git://git.sv.gnu.org/gnulib.git

and it seems the implementation of try_tempname_len is.. different!

```
  /* A random variable.  */
  random_value v = 0;
```
This is the master branch of gnulib.

Therefore, no initial entropy like on the latest version of libc.

Questions (as a newbie in this universe):
Are glibc and gnulib completely independent of each other?
If yes, then can I propose a patch so the implementation uses the ASLR also in
gnulib, like it does on glibc?
If no and they have some sort of sync, why isn't the code synced already?

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
  2023-10-10 19:05 ` [Bug libc/30958] " adhemerval.zanella at linaro dot org
  2023-10-11  4:09 ` sterpumihai at gmail dot com
@ 2023-10-11 10:23 ` fweimer at redhat dot com
  2023-10-11 10:23 ` sam at gentoo dot org
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: fweimer at redhat dot com @ 2023-10-11 10:23 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

Florian Weimer <fweimer at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |MOVED
                 CC|                            |fweimer at redhat dot com

--- Comment #3 from Florian Weimer <fweimer at redhat dot com> ---
Please report this on the bug-gnulib list:
https://lists.gnu.org/mailman/listinfo/bug-gnulib

The GNU C Library does not support Windows.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
                   ` (2 preceding siblings ...)
  2023-10-11 10:23 ` fweimer at redhat dot com
@ 2023-10-11 10:23 ` sam at gentoo dot org
  2023-10-11 12:45 ` adhemerval.zanella at linaro dot org
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: sam at gentoo dot org @ 2023-10-11 10:23 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

Sam James <sam at gentoo dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |sam at gentoo dot org

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
                   ` (3 preceding siblings ...)
  2023-10-11 10:23 ` sam at gentoo dot org
@ 2023-10-11 12:45 ` adhemerval.zanella at linaro dot org
  2023-10-11 14:57 ` sterpumihai at gmail dot com
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: adhemerval.zanella at linaro dot org @ 2023-10-11 12:45 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

--- Comment #4 from Adhemerval Zanella <adhemerval.zanella at linaro dot org> ---
(In reply to Sterpu Mihai from comment #2)
> Questions (as a newbie in this universe):
> Are glibc and gnulib completely independent of each other?
> If yes, then can I propose a patch so the implementation uses the ASLR also
> in gnulib, like it does on glibc?
> If no and they have some sort of sync, why isn't the code synced already?

The glibc is not used in the MinGW environment, it supports only Linux and GNU
Hurd.  The tempname.c is *shared* between gnulib and glibc; but occasionally
they are kept out of sync.  The gnulib is also used on multiple projects to
provide a layer that fixes broken POSIX interfaces and adds GNU extensions.

The latest gnulib changed the way to get the initial entropy to avoid bleeding
ASLR information.  It now always issues getrandom and iff it fails for some
reason it will use the clock and a simple polynomial to get some entropy.

Also, getentropy is implemented differently depending on the system (gnulib
lib/getrandom.c).  On glibc is just a wrapper over Linux getrandom syscall,
while on Linux it tries to use either BCryptGenRandom/CryptGenRandom.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
                   ` (4 preceding siblings ...)
  2023-10-11 12:45 ` adhemerval.zanella at linaro dot org
@ 2023-10-11 14:57 ` sterpumihai at gmail dot com
  2023-10-11 15:09 ` schwab@linux-m68k.org
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: sterpumihai at gmail dot com @ 2023-10-11 14:57 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

--- Comment #5 from Sterpu Mihai <sterpumihai at gmail dot com> ---
Hi all,

@Florian yes, I already sent an e-mail to the bug mailing list of gnulib. Maybe
I should also get in touch with the comitter, Peter.

@Adhemerval I understand that ASLR info might be leaked if the address of a
local variable is used. But we now have to deal with the issue of parallel
execution of the same tool like ar ie. parallel compilation which is used a lot
(nobody compiles on a single thread, right?)

A seed value of 0 doesn't provide any randomness so that's why I think it was
coupled with clock() in gnulib. HOWEVER, keep in mind that clock() returns the
number of "ticks" which passed since the program started.
In case of parallel execution of programs, the value of clock() might even be
the same if the resolution is not high enough.
I wrote a small application that uses clock.

```
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main()
{
  {
    long long i,y=0;
    for(i = 0; i < 2000000000ll; i++)
    {
      y+= i%3;
    }
  }
  clock_t x = clock();
  printf("%d\n",x);
}
```

Compiled with mingw gcc 13.2 on Windows 10 this prints something in the range
of 6000. Given the fact it takes 6 seconds to execute on my machine I assume
the resolution of a tick is actually millsecond in this case.

Therefore, if a program like ar always calls mkstemp at start (when not even a
millisecond has passed) then the underlying random infrastructure used by
mkstemp will yield the same "random" string.

Parallel execution is solvable by adding something related to each process like
the pid. getpid seems portable and could be added in the implementation of
mkstemp in order to allow for parallel execution without leasking ASLR info.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
                   ` (5 preceding siblings ...)
  2023-10-11 14:57 ` sterpumihai at gmail dot com
@ 2023-10-11 15:09 ` schwab@linux-m68k.org
  2023-10-11 15:36 ` sterpumihai at gmail dot com
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: schwab@linux-m68k.org @ 2023-10-11 15:09 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

--- Comment #6 from Andreas Schwab <schwab@linux-m68k.org> ---
mkstemp still works correctly even if it always tries the same (unique) file
name first.  There is no race because when the function returns the file will
be created and opened exclusively.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
                   ` (6 preceding siblings ...)
  2023-10-11 15:09 ` schwab@linux-m68k.org
@ 2023-10-11 15:36 ` sterpumihai at gmail dot com
  2023-10-11 15:40 ` sterpumihai at gmail dot com
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: sterpumihai at gmail dot com @ 2023-10-11 15:36 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

--- Comment #7 from Sterpu Mihai <sterpumihai at gmail dot com> ---
@Andreas and yet we sporadically get the following error when compiling with
gcc:

ar.exe: could not create temporary file whilst writing archive: Permission
denied

When using procmon I can see the same temporary filename is used by each ar
process.

The error message above is from binutils when write_archive calls
make_tempname:

https://github.com/bminor/binutils-gdb/blob/master/binutils/ar.c

make_tempname (bucomm.c) returns NULL when open(mkstemp(...)) yields an invalid
file descriptor.
I also see that make_tempname closes the tempfile before returning. The race
condition might be here! One make_tempname invocation might close the file
descriptor returned by mkstemp while another one wants to open it.
So even if mkstemp itself was fine, the handling done by binutils'
make_tempname might not be.
Again, this is just a supposition, I don't have the required tools to see
exactly what's going on otherwise I would've debugged this already.

This is actually one of my first ideas regarding this whole situation: if
mkstemp doesn't guarantee a new random at each invocation then it creates the
premises for race conditions in code that uses it.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
                   ` (7 preceding siblings ...)
  2023-10-11 15:36 ` sterpumihai at gmail dot com
@ 2023-10-11 15:40 ` sterpumihai at gmail dot com
  2023-10-11 15:47 ` sterpumihai at gmail dot com
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: sterpumihai at gmail dot com @ 2023-10-11 15:40 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

--- Comment #8 from Sterpu Mihai <sterpumihai at gmail dot com> ---
For clarity, this is the implementation of make_tempname:

https://imgur.com/a/xx1YkNF

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
                   ` (8 preceding siblings ...)
  2023-10-11 15:40 ` sterpumihai at gmail dot com
@ 2023-10-11 15:47 ` sterpumihai at gmail dot com
  2023-10-11 16:09 ` adhemerval.zanella at linaro dot org
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: sterpumihai at gmail dot com @ 2023-10-11 15:47 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

--- Comment #9 from Sterpu Mihai <sterpumihai at gmail dot com> ---
Hmm, now I see that the open is on the #else preprocessor branch so only close
is called.
Not sure anymore how the race condition occurs..
The good thing is that it reproduces more frequently on a particular test
system we have around here so I can try out any potential fix quickly.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
                   ` (9 preceding siblings ...)
  2023-10-11 15:47 ` sterpumihai at gmail dot com
@ 2023-10-11 16:09 ` adhemerval.zanella at linaro dot org
  2023-10-13 12:01 ` sam at gentoo dot org
  2023-10-13 13:49 ` bruno at clisp dot org
  12 siblings, 0 replies; 14+ messages in thread
From: adhemerval.zanella at linaro dot org @ 2023-10-11 16:09 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

--- Comment #10 from Adhemerval Zanella <adhemerval.zanella at linaro dot org> ---
> Therefore, if a program like ar always calls mkstemp at start (when not even
> a millisecond has passed) then the underlying random infrastructure used by
> mkstemp will yield the same "random" string.
> 
> Parallel execution is solvable by adding something related to each process
> like the pid. getpid seems portable and could be added in the implementation
> of mkstemp in order to allow for parallel execution without leasking ASLR
> info.

As I said, a recent gnulib fixed this, now try_tempname_len will always use
getrandom (which in turn uses Windows crypt library), which should provide the
required entropy.

I am not sure which libc implementation mingw uses, afaik it uses the Windows
libmsvcrtXX.a one.  So I am not sure whether binutils will use the system one
or if they use the gnulib copy from the gnulib/import (which is also outdated,
similar to the one from glibc).

In fact, this issue seems similar to this one
https://bugs.launchpad.net/gcc-arm-embedded/+bug/1848002

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
                   ` (10 preceding siblings ...)
  2023-10-11 16:09 ` adhemerval.zanella at linaro dot org
@ 2023-10-13 12:01 ` sam at gentoo dot org
  2023-10-13 13:49 ` bruno at clisp dot org
  12 siblings, 0 replies; 14+ messages in thread
From: sam at gentoo dot org @ 2023-10-13 12:01 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

Sam James <sam at gentoo dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://sourceware.org/bugz
                   |                            |illa/show_bug.cgi?id=30969

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libc/30958] mkstemp always produces the same temp file if it's removed
  2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
                   ` (11 preceding siblings ...)
  2023-10-13 12:01 ` sam at gentoo dot org
@ 2023-10-13 13:49 ` bruno at clisp dot org
  12 siblings, 0 replies; 14+ messages in thread
From: bruno at clisp dot org @ 2023-10-13 13:49 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=30958

Bruno Haible <bruno at clisp dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bruno at clisp dot org

--- Comment #11 from Bruno Haible <bruno at clisp dot org> ---
I replied on bug-gnulib:
https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00058.html

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-10-13 13:49 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-10 14:13 [Bug libc/30958] New: mkstemp always produces the same temp file if it's removed sterpumihai at gmail dot com
2023-10-10 19:05 ` [Bug libc/30958] " adhemerval.zanella at linaro dot org
2023-10-11  4:09 ` sterpumihai at gmail dot com
2023-10-11 10:23 ` fweimer at redhat dot com
2023-10-11 10:23 ` sam at gentoo dot org
2023-10-11 12:45 ` adhemerval.zanella at linaro dot org
2023-10-11 14:57 ` sterpumihai at gmail dot com
2023-10-11 15:09 ` schwab@linux-m68k.org
2023-10-11 15:36 ` sterpumihai at gmail dot com
2023-10-11 15:40 ` sterpumihai at gmail dot com
2023-10-11 15:47 ` sterpumihai at gmail dot com
2023-10-11 16:09 ` adhemerval.zanella at linaro dot org
2023-10-13 12:01 ` sam at gentoo dot org
2023-10-13 13:49 ` bruno at clisp dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).