[newlib-cygwin] Cygwin: user profile: Make an effort to unload unused user profiles

Corinna Vinschen corinna@sourceware.org
Sat Feb 23 17:00:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=71b8777a7140b79942d6e5079818cad2c3f5f07f

commit 71b8777a7140b79942d6e5079818cad2c3f5f07f
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Sat Feb 23 17:30:44 2019 +0100

    Cygwin: user profile: Make an effort to unload unused user profiles
    
    Does this work?  There's not much feedback given.
    
    TODO: We might want to try unloading the user profile at process
    exit as well, FWIW.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/autoload.cc |  1 +
 winsup/cygwin/cygheap.h   |  3 +++
 winsup/cygwin/sec_auth.cc |  6 ++++++
 winsup/cygwin/security.h  |  1 +
 winsup/cygwin/syscalls.cc | 15 ++++++++++++---
 winsup/cygwin/uinfo.cc    |  2 ++
 6 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 056fac7..c04e25c 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -699,6 +699,7 @@ LoadDLLfuncEx (CreateEnvironmentBlock, 12, userenv, 1)
 LoadDLLfuncEx2 (CreateProfile, 16, userenv, 1, 1)
 LoadDLLfunc (DestroyEnvironmentBlock, 4, userenv)
 LoadDLLfunc (LoadUserProfileW, 8, userenv)
+LoadDLLfunc (UnloadUserProfile, 8, userenv)
 
 LoadDLLfuncEx3 (waveInAddBuffer, 12, winmm, 1, 0, 1)
 LoadDLLfuncEx3 (waveInClose, 4, winmm, 1, 0, 1)
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index 8877cc3..5c5e3cd 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -106,6 +106,9 @@ public:
   HANDLE curr_primary_token;	 /* Just a copy of external or internal token */
   HANDLE curr_imp_token;	 /* impersonation token derived from primary
 				    token */
+  HANDLE imp_profile_token;	 /* Handle to the token used to load the
+				    user profile in "imp_profile" */
+  HANDLE imp_profile;		 /* Handle to the user profile */
   bool ext_token_is_restricted;  /* external_token is restricted token */
   bool curr_token_is_restricted; /* curr_primary_token is restricted token */
   bool setuid_to_restricted;     /* switch to restricted token by setuid () */
diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc
index c96011d..59ee553 100644
--- a/winsup/cygwin/sec_auth.cc
+++ b/winsup/cygwin/sec_auth.cc
@@ -306,6 +306,12 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid)
   return pi.hProfile;
 }
 
+bool
+unload_user_profile (HANDLE token, HANDLE profile)
+{
+  return UnloadUserProfile (token, profile);
+}
+
 HANDLE
 lsa_open_policy (PWCHAR server, ACCESS_MASK access)
 {
diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h
index 483a527..0ce7e8d 100644
--- a/winsup/cygwin/security.h
+++ b/winsup/cygwin/security.h
@@ -502,6 +502,7 @@ PWCHAR get_user_profile_directory (PCWSTR sidstr, PWCHAR path, SIZE_T path_len);
 
 /* Load user profile if it's not already loaded. */
 HANDLE load_user_profile (HANDLE token, struct passwd *pw, cygpsid &sid);
+bool unload_user_profile (HANDLE token, HANDLE profile);
 
 HANDLE lsa_open_policy (PWCHAR server, ACCESS_MASK access);
 void lsa_close_policy (HANDLE lsa);
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 172b7c4..b103976 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -3603,8 +3603,17 @@ seteuid32 (uid_t uid)
     {
       NTSTATUS status;
 
-      if (!request_restricted_uid_switch)
-	load_user_profile (new_token, pw_new, usersid);
+      if (!request_restricted_uid_switch
+	  && new_token != cygheap->user.imp_profile_token)
+	{
+	  if (cygheap->user.imp_profile_token && cygheap->user.imp_profile)
+	    unload_user_profile (cygheap->user.imp_profile_token,
+				 cygheap->user.imp_profile);
+	  cygheap->user.imp_profile = load_user_profile (new_token, pw_new,
+							 usersid);
+	  if (cygheap->user.imp_profile)
+	    cygheap->user.imp_profile_token = new_token;
+	}
 
       /* Try setting owner to same value as user. */
       status = NtSetInformationToken (new_token, TokenOwner,
@@ -3634,7 +3643,7 @@ seteuid32 (uid_t uid)
   issamesid = (usersid == cygheap->user.sid ());
   cygheap->user.set_sid (usersid);
   cygheap->user.curr_primary_token = new_token == hProcToken ? NO_IMPERSONATION
-							: new_token;
+							     : new_token;
   cygheap->user.curr_token_is_restricted = false;
   cygheap->user.setuid_to_restricted = false;
   if (cygheap->user.curr_imp_token != NO_IMPERSONATION)
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index bfcce00..49614cb 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -239,6 +239,8 @@ uinfo_init ()
   cygheap->user.internal_token = NO_IMPERSONATION;
   cygheap->user.curr_primary_token = NO_IMPERSONATION;
   cygheap->user.curr_imp_token = NO_IMPERSONATION;
+  cygheap->user.imp_profile_token = NO_IMPERSONATION;
+  cygheap->user.imp_profile = NULL;
   cygheap->user.ext_token_is_restricted = false;
   cygheap->user.curr_token_is_restricted = false;
   cygheap->user.setuid_to_restricted = false;



More information about the Cygwin-cvs mailing list