Per commit 929b1c42f3d23dcffacdedb005ab83d3607b47ce
"libgomp: Robustify omp_get_device_distances [PR125877]", we've got:

    [...]
      FILE *f = fopen ("/sys/devices/system/node/online", "r");
      if (f == NULL)
        goto fail;
      char *lineptr = NULL;
    [...]
    fail:
      free (lineptr);
    [...]

In C (per my understanding), this is "valid" (syntax): 'lineptr' appears as
part of the block it's declared in.  However, it only gets initialized (to
'NULL') only *after* the first 'goto fail;', therefore that 'goto fail;',
'free (lineptr);' code path invokes undefined behavior, crashes for random junk
in 'lineptr'.

We've got:

    [...]
      char *lineptr = NULL;
      size_t nline;
      if (getline (&lineptr, &nline, f) <= 0)
    [...]

The 'getline' API states:

|  -- Function: ssize_t getline (char **LINEPTR, size_t *N, FILE *STREAM)
| [...]
|      If you set ‘*LINEPTR’ to a null pointer, and ‘*N’ to zero, before
|      the call, then ‘getline’ allocates the initial buffer [...]

..., so we should initialize 'nline' to zero.

We've got:

    [...]
      if (getline (&lineptr, &nline, f) <= 0)
        {
          free (lineptr);
          fclose (f);
          goto fail;
        }
    [...]
    fail:
      free (lineptr);
    [...]

..., that is, a double 'free' in the error case.

        PR libgomp/125877
        libgomp/
        * config/linux/numa.c (gomp_get_numa_distance): Move 'lineptr'
        initialization earlier, fix 'getline' call, avoid double 'free'.
---
 libgomp/config/linux/numa.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/libgomp/config/linux/numa.c b/libgomp/config/linux/numa.c
index 85214e56dc41..e092f398540f 100644
--- a/libgomp/config/linux/numa.c
+++ b/libgomp/config/linux/numa.c
@@ -87,14 +87,13 @@ retry:
   /* Obtain numa nodes.  */
 
   num = 0;
+  char *lineptr = NULL;
   FILE *f = fopen ("/sys/devices/system/node/online", "r");
   if (f == NULL)
     goto fail;
-  char *lineptr = NULL;
-  size_t nline;
+  size_t nline = 0;
   if (getline (&lineptr, &nline, f) <= 0)
     {
-      free (lineptr);
       fclose (f);
       goto fail;
     }
-- 
2.34.1

Reply via email to