Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Avoid memcpy() with same source and destination during relmapper init.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 18 Dec 2020 20:46:44 +0000 (15:46 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 18 Dec 2020 20:46:44 +0000 (15:46 -0500)
A narrow reading of the C standard says that memcpy(x,x,n) is undefined,
although it's hard to envision an implementation that would really
misbehave.  However, analysis tools such as valgrind might whine about
this; accordingly, let's band-aid relmapper.c to not do it.

See also 5b630501ed3f4e8a8aad7b48ea0, and other similar fixes.
Apparently, none of those folk tried valgrinding initdb?  This has been
like this for long enough that I'm surprised it hasn't been reported
before.

Back-patch, just in case anybody wants to use a back branch on a platform
that complains about this; we back-patched those earlier fixes too.

Discussion: https://postgr.es/m/161790.1608310142@sss.pgh.pa.us

src/backend/utils/cache/relmapper.c

index 3b4f21bc54828c7f56f8022f60bf0ff9aeedda0a..897a4deb14499090b1f24ca64d86f1d8b9970c3b 100644 (file)
@@ -928,8 +928,15 @@ write_relmap_file(bool shared, RelMapFile *newmap,
        }
    }
 
-   /* Success, update permanent copy */
-   memcpy(realmap, newmap, sizeof(RelMapFile));
+   /*
+    * Success, update permanent copy.  During bootstrap, we might be working
+    * on the permanent copy itself, in which case skip the memcpy() to avoid
+    * invoking nominally-undefined behavior.
+    */
+   if (realmap != newmap)
+       memcpy(realmap, newmap, sizeof(RelMapFile));
+   else
+       Assert(!send_sinval);   /* must be bootstrapping */
 
    /* Critical section done */
    if (write_wal)