Bug 111413 - libgomp >= 13 segfault on loading if environ is NULL
Summary: libgomp >= 13 segfault on loading if environ is NULL
Status: ASSIGNED
Alias: None
Product: gcc
Classification: Unclassified
Component: libgomp (show other bugs)
Version: 13.2.1
: P3 normal
Target Milestone: ---
Assignee: Jakub Jelinek
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-09-14 10:09 UTC by Silvio Traversaro
Modified: 2023-12-05 16:32 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-09-18 00:00:00


Attachments
Example to reproduce the issue, compile with gcc -ldl test_gomp_segfault.c -o test_gomp_segfault (232 bytes, text/plain)
2023-09-14 10:09 UTC, Silvio Traversaro
Details
gcc14-pr111413.patch (1.61 KB, patch)
2023-09-18 09:03 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Silvio Traversaro 2023-09-14 10:09:37 UTC
Created attachment 55900 [details]
Example to reproduce the issue, compile with gcc -ldl test_gomp_segfault.c -o test_gomp_segfault

Since release 13, it seems that libgomp fails on loading in the environ global variable is NULL, for example if clearenv (https://man7.org/linux/man-pages/man3/clearenv.3.html) was called before a dlopen.

The problem seems in https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libgomp/env.c;hb=73a0d3bf895b5c322676178a51ac0d68cf603953#l2227, where `environ` is dereferenced without first checking if it is NULL.

A minimal reproducer is attached to the issue, that can be compiled and run as:

gcc -ldl test_gomp_segfault.c -o test_gomp_segfault
./test_gomp_segfault
Comment 1 Jakub Jelinek 2023-09-18 09:03:01 UTC
Created attachment 55920 [details]
gcc14-pr111413.patch

Untested fix.  Large patch but in the end it is just
--- libgomp/env.c
+++ libgomp/env.c
@@ -2224,6 +2224,7 @@ initialize_env (void)
   none = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_NO_SUFFIX);
   initialize_icvs (&none->icvs);
 
+  if (environ)
     for (env = environ; *env != 0; env++)
       {
        if (!startswith (*env, "OMP_"))
plus reindentation.
Comment 2 GCC Commits 2023-09-19 07:31:06 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:15345980633c502f0486a2e40e96224f49134130

commit r14-4122-g15345980633c502f0486a2e40e96224f49134130
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Sep 19 09:26:35 2023 +0200

    libgomp: Handle NULL environ like pointer to NULL pointer [PR111413]
    
    clearenv function just sets environ to NULL (after sometimes freeing it),
    rather than setting it to a pointer to NULL, and our code was assuming
    it is always non-NULL.
    
    Fixed thusly, the change seems to be large but actually is just
    +  if (environ)
         for (env = environ; *env != 0; env++)
    plus reindentation.  I've also noticed the block after this for loop
    was badly indented (too much) and fixed that too.
    
    No testcase added, as it needs clearenv + dlopen.
    
    2023-09-19  Jakub Jelinek  <jakub@redhat.com>
    
            PR libgomp/111413
            * env.c (initialize_env): Don't dereference environ if it is NULL.
            Reindent.
Comment 3 Silvio Traversaro 2023-09-19 08:31:32 UTC
Thanks a lot for fixing this!
Comment 4 GCC Commits 2023-12-05 16:32:20 UTC
The releases/gcc-13 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:c128ad8e830e90a429eaeccc3fb000a73fd6779c

commit r13-8118-gc128ad8e830e90a429eaeccc3fb000a73fd6779c
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Sep 19 09:26:35 2023 +0200

    libgomp: Handle NULL environ like pointer to NULL pointer [PR111413]
    
    clearenv function just sets environ to NULL (after sometimes freeing it),
    rather than setting it to a pointer to NULL, and our code was assuming
    it is always non-NULL.
    
    Fixed thusly, the change seems to be large but actually is just
    +  if (environ)
         for (env = environ; *env != 0; env++)
    plus reindentation.  I've also noticed the block after this for loop
    was badly indented (too much) and fixed that too.
    
    No testcase added, as it needs clearenv + dlopen.
    
    2023-09-19  Jakub Jelinek  <jakub@redhat.com>
    
            PR libgomp/111413
            * env.c (initialize_env): Don't dereference environ if it is NULL.
            Reindent.
    
    (cherry picked from commit 15345980633c502f0486a2e40e96224f49134130)