mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Avoid memcpy() with same source and destination during relmapper init.
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 also5b630501e,d3f4e8a8a,ad7b48ea0, 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
This commit is contained in:
		
							
								
								
									
										11
									
								
								src/backend/utils/cache/relmapper.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								src/backend/utils/cache/relmapper.c
									
									
									
									
										vendored
									
									
								
							@@ -846,8 +846,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 */
 | 
						/* Critical section done */
 | 
				
			||||||
	if (write_wal)
 | 
						if (write_wal)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user