Bug 2089247

Summary: glibc: tempnam() regression in glibc [rhel-8.7.0]
Product: Red Hat Enterprise Linux 8 Reporter: pbhosale
Component: glibcAssignee: Florian Weimer <fweimer>
Status: CLOSED ERRATA QA Contact: Martin Coufal <mcoufal>
Severity: medium Docs Contact: Dominik <dklon>
Priority: urgent    
Version: 8.4CC: ashankar, codonell, dj, dklon, fweimer, kwalker, mcoufal, mnewsome, mpoole, pfrankli, sipoyare, skolosov, vpakolu
Target Milestone: rcKeywords: Bugfix, Patch, Regression, Triaged, ZStream
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: glibc-2.28-204.el8 Doc Type: Bug Fix
Doc Text:
.The `tempnam` function now uses `getrandom` to increase the randomness of generated file names Previously, the `tempnam` function in Red Hat Enterprise Linux 8.4 and later used time-derived randomness for choosing paths. As a result, the `tempnam` function was not producing the full set of possible file names when invoked repeatedly in quick succession. This bug has been fixed by a new implementation that uses the `getrandom` function to increase the randomness of the generated file names. As a result, the `tempnam` function now generates more distinct file names.
Story Points: ---
Clone Of:
: 2093457 (view as bug list) Environment:
Last Closed: 2022-11-08 10:43:12 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 2093457    

Description pbhosale 2022-05-23 09:45:14 UTC
Description of problem:

tempnam() regregresion in glibc affecting RedHat 8.4+.

The C function tempnam() can generate a very small number of unique temporary filenames on RedHat 8.5. As a result an application which is using tempnam() may not function properly under heavy load.  

Based on customers investigations it appears to be a regression in glibc starting with RedHat 8.4. Also RedHat 7.9 is not affected.  We think that latest glibc was already fixed but the fixes were not backported in RedHat 8.5

See below a demo program which outputs the number of unique temporary file names that can be generated on RedHat 8.5 vs RedHat 7.9.

---
#include <map>
#include <iostream>
int main(int argc, char **argv)
{
  std::map<std::string, int> m;
  int i;
  for (i=0; i<1000000; i++) {
    auto ret = m.insert(std::pair<std::string,int>(tempnam(NULL, "a"),1));
    if (ret.second == false) {
      break;
    }
  }
  std::cout << "Generated " << i << " tempnam() distinct entries\n";
  return 0;
}
---
Compile like: 
g++ -o tempnam_demo tempnam_demo.c
---


If the above program is run more times on RedHat 8.5 it outputs results like:
~~~
Generated 4362 tempnam() distinct entries
Generated 3867 tempnam() distinct entries
Generated 4384 tempnam() distinct entries
Generated 5811 tempnam() distinct entries
Generated 13786 tempnam() distinct entries
Generated 10687 tempnam() distinct entries
Generated 13476 tempnam() distinct entries
Generated 5854 tempnam() distinct entries
Generated 7741 tempnam() distinct entries
~~~
If the above program is run more times on RedHat 7.9 it outputs results like:

~~~
Generated 208381 tempnam() distinct entries
Generated 182184 tempnam() distinct entries
Generated 145776 tempnam() distinct entries
Generated 679048 tempnam() distinct entries
Generated 578402 tempnam() distinct entries
Generated 95064 tempnam() distinct entries
Generated 420830 tempnam() distinct entries
Generated 430587 tempnam() distinct entries
Generated 112908 tempnam() distinct entries
~~~


Version-Release number of selected component (if applicable):


How reproducible:


Steps to Reproduce:
1.
2.
3.

Actual results:


Expected results:


Additional info:

Also customer has  provided detail one scenario(pseudocode) that is affected:
---
process_1
   # init zone
   filename = tempnam();
    ...
   # processing zone
  ...
  createAndFillFile(filename); // file is actually created and filled with information
  ...

process_2
   # init zone
   filename = tempnam();
    ...
   # processing zone
  ...
  createAndFillFile(filename); // file is actually created and filled with information
 ...

process_n
   # init zone
   filename = tempnam();
    ...
   # processing zone
  ...
  createAndFillFile(filename); // file is actually created and filled with information
 ...

---

In the above scenario each process is using tempnam() but is not creating the file(based in filename) immediately. When there are many processes and the load on machine is very high, the time interval between the filename is generated and the file is actually created is increasing for each process(there may be few seconds between). So, there are lot of tempnam() calls in parallel without files from previous calls to be actually created.

This is a scenario which is affected by current reported bug, scenario that works very well on RedHat 7.9, but sometimes is not working properly on RedHat 8.4+.

Comment 1 Florian Weimer 2022-05-23 10:04:24 UTC
We are likely missing this upstream fix:

commit e1df30fbc2e2167a982c0e77a7ebee28f4dd0800
Author: Adhemerval Zanella <adhemerval.zanella>
Date:   Thu Jul 25 11:22:17 2019 -0300

    Get new entropy on each attempt __gen_tempname (BZ #15813)
    
    This is missing bit for fully fix BZ#15813 (the other two were fixed
    by 359653aaacad463).
    
    Checked on x86_64-linux-gnu.
    
            [BZ #15813]
            sysdeps/posix/tempname.c (__gen_tempname): get entrypy on each
            attempt.

I will produce a test build.

Comment 2 Florian Weimer 2022-05-23 11:03:37 UTC
The commit is insufficient. I still see very few different values.

Comment 3 Florian Weimer 2022-05-23 17:21:41 UTC
We need these patches in addition:

commit 8eaf34eda256ba3647ed6e7ed5c7c9aa19955d17
Author: Samuel Thibault <samuel.thibault>
Date:   Fri Dec 13 10:10:59 2019 +0100

    hurd: Fix local PLT

commit 4dddd7e9cbecad4aa03ee5a9b9edb596e3d4e909
Author: Adhemerval Zanella <adhemerval.zanella>
Date:   Tue Sep 29 08:56:07 2020 -0300

    posix: Sync tempname with gnulib [BZ #26648]

commit f430293d842031f2afc3013f156e1018065e480e
Author: Adhemerval Zanella <adhemerval.zanella>
Date:   Tue Jan 12 09:17:09 2021 -0300

    posix: consume less entropy on tempname

Plus this commit to avoid patching the gnulib version further:

commit 04986243d1af37ac0177ed2f9db0a066ebd2b212
Author: Adhemerval Zanella <adhemerval.zanella>
Date:   Wed Jul 15 19:35:58 2020 +0000

    Remove internal usage of extensible stat functions

I don't see a way to safely add time64 support to our downstream glibc, so we also need a patch to use the time32 functions on i686.

Comment 20 errata-xmlrpc 2022-11-08 10:43:12 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (glibc bug fix and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2022:7684