Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit202dbdb

Browse files
committed
Make pgwin32_putenv() follow DLL loading and unloading.
Until now, the first putenv() call of a given postgres.exe process wouldcache the set of loaded CRTs. If a CRT unloaded after that call, thenext putenv() would crash. That risk was largely theoretical, becausethe first putenv() precedes all PostgreSQL-initiated module loading.However, this might explain bad interactions with antivirus and othersoftware that injects threads asynchronously. If an additional CRTloaded after the first putenv(), pgwin32_putenv() would not discover it.That CRT would have all environment changes predating its load, but itwould not receive later PostgreSQL-initiated changes. An additional CRTloading concurrently with the first putenv() might miss that change inaddition to missing later changes. Fix all those problems. Thisremoves the cache mechanism from pgwin32_putenv(); the cost, less than100 μs per backend startup, is negligible.No resulting misbehavior was known to be user-visible given the coredistribution alone, but one can readily construct an affected extensionmodule. No back-patch given the lack of complaints and the potentialfor behavior changes in non-PostgreSQL code running in the backend.Christian Ullrich, reviewed by Michael Paquier.
1 parent95b9b8a commit202dbdb

File tree

1 file changed

+48
-112
lines changed

1 file changed

+48
-112
lines changed

‎src/port/win32env.c

Lines changed: 48 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -21,126 +21,37 @@ pgwin32_putenv(const char *envval)
2121
{
2222
char*envcpy;
2323
char*cp;
24-
25-
/*
26-
* Each CRT has its own _putenv() symbol and copy of the environment.
27-
* Update the environment in each CRT module currently loaded, so every
28-
* third-party library sees this change regardless of the CRT it links
29-
* against.
30-
*/
3124
#ifdef_MSC_VER
3225
typedefint (_cdecl*PUTENVPROC) (constchar*);
33-
staticstruct
34-
{
35-
char*modulename;
36-
HMODULEhmodule;
37-
PUTENVPROCputenvFunc;
38-
}rtmodules[]=
39-
{
40-
{
41-
"msvcrt",NULL,NULL
42-
},/* Visual Studio 6.0 / MinGW */
43-
{
44-
"msvcrtd",NULL,NULL
45-
},
46-
{
47-
"msvcr70",NULL,NULL
48-
},/* Visual Studio 2002 */
49-
{
50-
"msvcr70d",NULL,NULL
51-
},
52-
{
53-
"msvcr71",NULL,NULL
54-
},/* Visual Studio 2003 */
55-
{
56-
"msvcr71d",NULL,NULL
57-
},
58-
{
59-
"msvcr80",NULL,NULL
60-
},/* Visual Studio 2005 */
61-
{
62-
"msvcr80d",NULL,NULL
63-
},
64-
{
65-
"msvcr90",NULL,NULL
66-
},/* Visual Studio 2008 */
67-
{
68-
"msvcr90d",NULL,NULL
69-
},
70-
{
71-
"msvcr100",NULL,NULL
72-
},/* Visual Studio 2010 */
73-
{
74-
"msvcr100d",NULL,NULL
75-
},
76-
{
77-
"msvcr110",NULL,NULL
78-
},/* Visual Studio 2012 */
79-
{
80-
"msvcr110d",NULL,NULL
81-
},
82-
{
83-
"msvcr120",NULL,NULL
84-
},/* Visual Studio 2013 */
85-
{
86-
"msvcr120d",NULL,NULL
87-
},
88-
{
89-
"ucrtbase",NULL,NULL
90-
},/* Visual Studio 2015 and later */
91-
{
92-
"ucrtbased",NULL,NULL
93-
},
94-
{
95-
NULL,NULL,NULL
96-
}
26+
staticconstchar*constmodulenames[]= {
27+
"msvcrt",/* Visual Studio 6.0 / MinGW */
28+
"msvcrtd",
29+
"msvcr70",/* Visual Studio 2002 */
30+
"msvcr70d",
31+
"msvcr71",/* Visual Studio 2003 */
32+
"msvcr71d",
33+
"msvcr80",/* Visual Studio 2005 */
34+
"msvcr80d",
35+
"msvcr90",/* Visual Studio 2008 */
36+
"msvcr90d",
37+
"msvcr100",/* Visual Studio 2010 */
38+
"msvcr100d",
39+
"msvcr110",/* Visual Studio 2012 */
40+
"msvcr110d",
41+
"msvcr120",/* Visual Studio 2013 */
42+
"msvcr120d",
43+
"ucrtbase",/* Visual Studio 2015 and later */
44+
"ucrtbased",
45+
NULL
9746
};
9847
inti;
99-
100-
for (i=0;rtmodules[i].modulename;i++)
101-
{
102-
if (rtmodules[i].putenvFunc==NULL)
103-
{
104-
if (rtmodules[i].hmodule==NULL)
105-
{
106-
/* Not attempted before, so try to find this DLL */
107-
rtmodules[i].hmodule=GetModuleHandle(rtmodules[i].modulename);
108-
if (rtmodules[i].hmodule==NULL)
109-
{
110-
/*
111-
* Set to INVALID_HANDLE_VALUE so we know we have tried
112-
* this one before, and won't try again.
113-
*/
114-
rtmodules[i].hmodule=INVALID_HANDLE_VALUE;
115-
continue;
116-
}
117-
else
118-
{
119-
rtmodules[i].putenvFunc= (PUTENVPROC)GetProcAddress(rtmodules[i].hmodule,"_putenv");
120-
if (rtmodules[i].putenvFunc==NULL)
121-
{
122-
rtmodules[i].hmodule=INVALID_HANDLE_VALUE;
123-
continue;
124-
}
125-
}
126-
}
127-
else
128-
{
129-
/*
130-
* Module loaded, but we did not find the function last time.
131-
* We're not going to find it this time either...
132-
*/
133-
continue;
134-
}
135-
}
136-
/* At this point, putenvFunc is set or we have exited the loop */
137-
rtmodules[i].putenvFunc(envval);
138-
}
13948
#endif/* _MSC_VER */
14049

14150
/*
14251
* Update process environment, making this change visible to child
143-
* processes and to CRTs initializing in the future.
52+
* processes and to CRTs initializing in the future. Do this before the
53+
* _putenv() loop, for the benefit of any CRT that initializes during this
54+
* pgwin32_putenv() execution, after the loop checks that CRT.
14455
*
14556
* Need a copy of the string so we can modify it.
14657
*/
@@ -170,6 +81,31 @@ pgwin32_putenv(const char *envval)
17081
}
17182
free(envcpy);
17283

84+
/*
85+
* Each CRT has its own _putenv() symbol and copy of the environment.
86+
* Update the environment in each CRT module currently loaded, so every
87+
* third-party library sees this change regardless of the CRT it links
88+
* against. Addresses within these modules may become invalid the moment
89+
* we call FreeLibrary(), so don't cache them.
90+
*/
91+
#ifdef_MSC_VER
92+
for (i=0;modulenames[i];i++)
93+
{
94+
HMODULEhmodule=NULL;
95+
BOOLres=GetModuleHandleEx(0,modulenames[i],&hmodule);
96+
97+
if (res!=0&&hmodule!=NULL)
98+
{
99+
PUTENVPROCputenvFunc;
100+
101+
putenvFunc= (PUTENVPROC)GetProcAddress(hmodule,"_putenv");
102+
if (putenvFunc)
103+
putenvFunc(envval);
104+
FreeLibrary(hmodule);
105+
}
106+
}
107+
#endif/* _MSC_VER */
108+
173109
/* Finally, update our "own" cache */
174110
return_putenv(envval);
175111
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp