Browse Source

* win/sysutils.pp: fix/clean up loading dll for SHGetFolderPath.
* Don't attempt to load shell32.dll, since every system with shell32.dll that exports SHGetFolderPath also has shfolder.dll present.
* Load shfolder.dll using a full path in order to prevent loading of malicious code by placing a same-named dll into program directory (Mantis #18185).

git-svn-id: trunk@16549 -

sergei 14 years ago
parent
commit
179229007e
1 changed files with 15 additions and 23 deletions
  1. 15 23
      rtl/win/sysutils.pp

+ 15 - 23
rtl/win/sysutils.pp

@@ -1130,36 +1130,28 @@ var
 Procedure InitDLL;
 
 Var
-  P : Pointer;
-
+  pathBuf: array[0..MAX_PATH-1] of char;
+  pathLength: Integer;
 begin
-  CFGDLLHandle:=LoadLibrary('shell32.dll');
-  if (CFGDLLHandle<>0) then
-    begin
-    P:=GetProcAddress(CFGDLLHandle,'SHGetFolderPathA');
-    If (P=Nil) then
-      begin
-      FreeLibrary(CFGDLLHandle);
-      CFGDllHandle:=0;
-      end
-    else
-      SHGetFolderPath:=PFNSHGetFolderPath(P);
-    end;
-  If (P=Nil) then
-    begin
-    CFGDLLHandle:=LoadLibrary('shfolder.dll');
+  { Load shfolder.dll using a full path, in order to prevent spoofing (Mantis #18185)
+    Don't bother loading shell32.dll because shfolder.dll itself redirects SHGetFolderPath
+    to shell32.dll whenever possible. }
+  pathLength:=GetSystemDirectory(pathBuf, MAX_PATH);
+  if (pathLength>0) and (pathLength<MAX_PATH-14) then { 14=length('\shfolder.dll'#0) }
+  begin
+    StrLCopy(@pathBuf[pathLength],'\shfolder.dll',MAX_PATH-pathLength-1);
+    CFGDLLHandle:=LoadLibrary(pathBuf);
+
     if (CFGDLLHandle<>0) then
+    begin
+      Pointer(ShGetFolderPath):=GetProcAddress(CFGDLLHandle,'SHGetFolderPathA');
+      If @ShGetFolderPath=nil then
       begin
-      P:=GetProcAddress(CFGDLLHandle,'SHGetFolderPathA');
-      If (P=Nil) then
-        begin
         FreeLibrary(CFGDLLHandle);
         CFGDllHandle:=0;
-        end
-      else
-        ShGetFolderPath:=PFNSHGetFolderPath(P);
       end;
     end;
+  end;
   If (@ShGetFolderPath=Nil) then
     Raise Exception.Create('Could not determine SHGetFolderPath Function');
 end;