pastebin - collaborative debugging tool
rovema.kpaste.net RSS


msnfs41client: AppVerifier/libtirpc/DLL, RunAsUserSYSTEM+misc patches, 2024-04-17 ...
Posted by Anonymous on Wed 17th Apr 2024 15:45
raw | new post

  1. From f6d1e0bad63000b7527b70a7438fe845e40aae5b Mon Sep 17 00:00:00 2001
  2. From: Roland Mainz <roland.mainz@nrubsig.org>
  3. Date: Tue, 16 Apr 2024 14:49:10 +0200
  4. Subject: [PATCH 1/4] libtirpc,daemon: Do not call WinSock API from |DllMain()|
  5.  
  6. It is not legal to call the WinSock API, including |WSAStartup()|,
  7. from (libtirpc's) |DllMain()|.
  8. See https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsastartup
  9.  
  10. AppVerifier+cdb generated this stack trace:
  11. ---- snip ----
  12. vrfcore!VerifierStopMessageEx+0x7f7
  13. vfnet!StopIfCalledWithinDllMain+0xfa
  14. vfnet!VfHookWSAStartup+0x2d
  15. libtirpc!winsock_init(void)+0x28 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\libtirpc\src\wintirpc.c @ 75]
  16. libtirpc!DllMain(struct HINSTANCE__ * hinstDLL = 0x00007ffc`75c80000, unsigned long fdwReason = 1, void * lpvReserved = 0x000000ad`2239f640)+0x50 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\libtirpc\src\wintirpc.c @ 109]
  17. libtirpc!dllmain_dispatch(struct HINSTANCE__ * instance = 0x00007ffc`75c80000, unsigned long reason = 1, void * reserved = 0x000000ad`2239f640)+0x98 [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp @ 281]
  18. libtirpc!_DllMainCRTStartup(struct HINSTANCE__ * instance = 0x00007ffc`75c80000, unsigned long reason = 1, void * reserved = 0x000000ad`2239f640)+0x31 [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp @ 335]
  19. verifier!AVrfpStandardDllEntryPointRoutine+0xe9
  20. vrfcore!VfCoreStandardDllEntryPointRoutine+0x18a
  21. vfbasics!AVrfpStandardDllEntryPointRoutine+0xf3
  22. ntdll!LdrpCallInitRoutine+0x61
  23. ntdll!LdrpInitializeNode+0x1d3
  24. ntdll!LdrpInitializeGraphRecurse+0x42
  25. ntdll!LdrpInitializeGraphRecurse+0xc8
  26. ntdll!LdrpInitializeProcess+0x1f62
  27. ntdll!LdrpInitialize+0x15f
  28. ntdll!LdrpInitialize+0x3b
  29. ntdll!LdrInitializeThunk+0xe
  30. ---- snip ----
  31.  
  32. We now do the |WSAStartup()| via |__rpc_nconf2fd()|, but without
  33. support for cleanup. In the future we should do refcounting, and
  34. do a cleanup if the refcount reaches 0.
  35.  
  36. Reported-by: Dan Shelton <dan.f.shelton@gmail.com>
  37. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  38. ---
  39.  daemon/nfs41_daemon.c      | 18 +++++++++++-
  40.  libtirpc/src/rpc_generic.c |  4 +++
  41.  libtirpc/src/wintirpc.c    | 57 ++++++++------------------------------
  42.  libtirpc/tirpc/wintirpc.h  |  3 ++
  43.  4 files changed, 36 insertions(+), 46 deletions(-)
  44.  
  45. diff --git a/daemon/nfs41_daemon.c b/daemon/nfs41_daemon.c
  46. index 5b9c48d..5a6bbc2 100644
  47. --- a/daemon/nfs41_daemon.c
  48. +++ b/daemon/nfs41_daemon.c
  49. @@ -520,6 +520,21 @@ void nfsd_crt_debug_init(void)
  50.  #endif /* _DEBUG */
  51.  }
  52.  
  53. +static
  54. +bool winsock_init(void)
  55. +{
  56. +       int err;
  57. +        WSADATA WSAData;
  58. +
  59. +       err = WSAStartup(MAKEWORD(2, 2), &WSAData);
  60. +       if (err != 0) {
  61. +               eprintf("winsock_init: WSAStartup() failed!\n");
  62. +               WSACleanup();
  63. +               return false;
  64. +       }
  65. +       return true;
  66. +}
  67. +
  68.  static
  69.  void init_version_string(void)
  70.  {
  71. @@ -625,8 +640,9 @@ VOID ServiceStart(DWORD argc, LPTSTR *argv)
  72.          exit(1);
  73.      set_debug_level(cmd_args.debug_level);
  74.      open_log_files();
  75. -    init_version_string();
  76.      nfsd_crt_debug_init();
  77. +    (void)winsock_init();
  78. +    init_version_string();
  79.  #ifdef NFS41_DRIVER_SID_CACHE
  80.      sidcache_init();
  81.  #else
  82. diff --git a/libtirpc/src/rpc_generic.c b/libtirpc/src/rpc_generic.c
  83. index e5c8274..345c4ba 100644
  84. --- a/libtirpc/src/rpc_generic.c
  85. +++ b/libtirpc/src/rpc_generic.c
  86. @@ -563,6 +563,10 @@ __rpc_nconf2fd(const struct netconfig *nconf)
  87.         struct __rpc_sockinfo si;
  88.         int fd;
  89.  
  90. +#ifdef _WIN32
  91. +       if (!wintirpc_winsock_init())
  92. +               return 0;
  93. +#endif
  94.         if (!__rpc_nconf2sockinfo(nconf, &si))
  95.                 return 0;
  96.  
  97. diff --git a/libtirpc/src/wintirpc.c b/libtirpc/src/wintirpc.c
  98. index 152caf4..1eba532 100644
  99. --- a/libtirpc/src/wintirpc.c
  100. +++ b/libtirpc/src/wintirpc.c
  101. @@ -34,52 +34,21 @@ static DWORD dwTlsIndex;
  102.  
  103.  extern void multithread_init(void);
  104.  
  105. -VOID
  106. -tirpc_report(LPTSTR lpszMsg)
  107. -{
  108. -       WCHAR    chMsg[256];
  109. -       HANDLE   hEventSource;
  110. -       LPCWSTR  lpszStrings[2];
  111. -
  112. -       // Use event logging to log the error.
  113. -       //
  114. -       hEventSource = RegisterEventSource(NULL,
  115. -                                                                          TEXT("tirpc.dll"));
  116. -
  117. -       swprintf_s(chMsg, sizeof(chMsg), L"tirpc report: %d", GetLastError());
  118. -       lpszStrings[0] = (LPCWSTR)chMsg;
  119. -       lpszStrings[1] = lpszMsg;
  120. -
  121. -       if (hEventSource != NULL) {
  122. -               ReportEvent(hEventSource, // handle of event source
  123. -                       EVENTLOG_WARNING_TYPE, // event type
  124. -                       0,                    // event category
  125. -                       0,                    // event ID
  126. -                       NULL,                 // current user's SID
  127. -                       2,                    // strings in lpszStrings
  128. -                       0,                    // no bytes of raw data
  129. -                       lpszStrings,          // array of error strings
  130. -                       NULL);                // no raw data
  131. -
  132. -               (VOID) DeregisterEventSource(hEventSource);
  133. -       }
  134. -}
  135. -
  136.  void tirpc_criticalsection_init(void) {
  137.         multithread_init();
  138.  }
  139.  
  140. -BOOL winsock_init(void)
  141. +bool wintirpc_winsock_init(void)
  142.  {
  143.         int err;
  144. -       err = WSAStartup(MAKEWORD( 3, 3 ), &WSAData);   // XXX THIS SHOULD BE FAILING!!!!!!!!!!!!!!!!!
  145. +       err = WSAStartup(MAKEWORD(2, 2), &WSAData);
  146.         if (err != 0) {
  147.                 init = 0;
  148. -               tirpc_report(L"WSAStartup failed!\n");
  149. +               (void)fprintf(stderr, "winsock_init: WSAStartup failed!\n");
  150.                 WSACleanup();
  151. -               return FALSE;
  152. +               return false;
  153.         }
  154. -       return TRUE;
  155. +       return true;
  156.  }
  157.  
  158.  BOOL winsock_fini(void)
  159. @@ -104,13 +73,9 @@ BOOL WINAPI DllMain/*tirpc_main*/(HINSTANCE hinstDLL,       // DLL module handle
  160.                 // The DLL is loading due to process
  161.                 // initialization or a call to LoadLibrary.
  162.          case DLL_PROCESS_ATTACH:
  163. -                      
  164. -                       // Initialize socket library
  165. -                       if (winsock_init() == FALSE)
  166. -                               return FALSE;
  167. -
  168. -                       // Initialize CriticalSections
  169. -                       tirpc_criticalsection_init();
  170. +            // Do NOT init WinSock here, it is not legal and AppVerifer will complain
  171. +            // Initialize CriticalSections
  172. +            tirpc_criticalsection_init();
  173.  
  174.              // Allocate a TLS index.
  175.              if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
  176. @@ -149,8 +114,10 @@ BOOL WINAPI DllMain/*tirpc_main*/(HINSTANCE hinstDLL,      // DLL module handle
  177.              // Release the TLS index.
  178.              TlsFree(dwTlsIndex);
  179.  
  180. -                       // Clean up winsock stuff
  181. -                       winsock_fini();
  182. +            // Clean up winsock stuff
  183. +           // FIXME: This is not legal in DllMain, we should use
  184. +           // recounting instead
  185. +            winsock_fini();
  186.  
  187.              break;
  188.  
  189. diff --git a/libtirpc/tirpc/wintirpc.h b/libtirpc/tirpc/wintirpc.h
  190. index 4d70be4..94ecf18 100644
  191. --- a/libtirpc/tirpc/wintirpc.h
  192. +++ b/libtirpc/tirpc/wintirpc.h
  193. @@ -39,9 +39,11 @@
  194.  /* use visual studio's debug heap */
  195.  # define _CRTDBG_MAP_ALLOC
  196.  # include <stdlib.h>
  197. +# include <stdbool.h>
  198.  # include <crtdbg.h>
  199.  #else
  200.  # include <stdlib.h>
  201. +# include <stdbool.h>
  202.  #endif
  203.  
  204.  /* Common Windows includes */
  205. @@ -136,6 +138,7 @@ struct sockaddr_un {
  206.  typedef SSIZE_T wintirpc_ssize_t;
  207.  
  208.  /* Prototypes */
  209. +bool wintirpc_winsock_init(void);
  210.  int wintirpc_socket(int af,int type, int protocol);
  211.  int wintirpc_closesocket(int in_fd);
  212.  int wintirpc_close(int in_fd);
  213. --
  214. 2.43.0
  215.  
  216. From 1f7d9946d49a3aaffab024e965d4ed54ce6a9ff7 Mon Sep 17 00:00:00 2001
  217. From: Roland Mainz <roland.mainz@nrubsig.org>
  218. Date: Wed, 17 Apr 2024 13:44:45 +0200
  219. Subject: [PATCH 2/4] nfs41_np: Network provider should use |towupper()|, not
  220.  |toupper()|
  221.  
  222. Network provider should use |towupper()|, not |toupper()|
  223.  
  224. Reported-by: Martin Wege <martin.l.wege@gmail.com>
  225. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  226. ---
  227.  dll/nfs41_np.c | 2 +-
  228.  1 file changed, 1 insertion(+), 1 deletion(-)
  229.  
  230. diff --git a/dll/nfs41_np.c b/dll/nfs41_np.c
  231. index 350cb73..db57e4f 100644
  232. --- a/dll/nfs41_np.c
  233. +++ b/dll/nfs41_np.c
  234. @@ -469,7 +469,7 @@ NPAddConnection3(
  235.          goto out;
  236.      }
  237.  
  238. -    LocalName[0] = (WCHAR) toupper(lpNetResource->lpLocalName[0]);
  239. +    LocalName[0] = towupper(lpNetResource->lpLocalName[0]);
  240.      LocalName[1] = L':';
  241.      LocalName[2] = L'\0';
  242.      StringCchCopyW( ConnectionName, NFS41_SYS_MAX_PATH_LEN, NFS41_DEVICE_NAME );
  243. --
  244. 2.43.0
  245.  
  246. From 90cdb3adcd1aa323d3489b55a0817eb17af522a8 Mon Sep 17 00:00:00 2001
  247. From: Roland Mainz <roland.mainz@nrubsig.org>
  248. Date: Wed, 17 Apr 2024 14:38:46 +0200
  249. Subject: [PATCH 3/4] cygwin: nfsd_debug cannot run as user "SYSTEM", fails
  250.  with exit code 0xC0000022
  251.  
  252. nfsd_debug.exe cannot run as user "SYSTEM", fails with exit code
  253. 0xC0000022 due to file permission errors.
  254.  
  255. It turns out this is a DLL load error - if a DLL cannot be *read* the
  256. system triggers an exit code of 0xC0000022.
  257.  
  258. DLLs can only be used if they are readable (chmod a+r), the execute
  259. flag (chmod a+x) only matters for Cygwin, so the bintarball Makefile
  260. target must do a chmod a+rx instead of chmod a+x, as we install the
  261. files usually as a non-SYSTEM plain user.
  262.  
  263. Reported-by: Martin Wege <martin.l.wege@gmail.com>
  264. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  265. ---
  266.  cygwin/Makefile | 4 ++--
  267.  1 file changed, 2 insertions(+), 2 deletions(-)
  268.  
  269. diff --git a/cygwin/Makefile b/cygwin/Makefile
  270. index a2fcd24..ea16bfa 100644
  271. --- a/cygwin/Makefile
  272. +++ b/cygwin/Makefile
  273. @@ -111,8 +111,8 @@ installdest: $(VS_BUILD_DIR)/nfsd.exe \
  274.                         cp "$$i" $(DESTDIR)/cygdrive/c/cygwin64/sbin/. ; \
  275.                 done
  276.         @ printf "# Set file flags\n"
  277. -       (cd $(DESTDIR)/cygdrive/c/cygwin64/sbin/ && chmod a+x *.exe *.dll)
  278. -       (cd $(DESTDIR)/cygdrive/c/cygwin64/lib/msnfs41client/ && chmod a+x *.dll)
  279. +       (cd $(DESTDIR)/cygdrive/c/cygwin64/sbin/ && chmod a+rx *.exe *.dll)
  280. +       (cd $(DESTDIR)/cygdrive/c/cygwin64/lib/msnfs41client/ && chmod a+rx *.dll)
  281.         @printf "\n#\n# TEST sbin dir is %s\n#\n" "$(DESTDIR)/cygdrive/c/cygwin64/sbin/"
  282.         @printf '\n'
  283.         @printf "\n#\n# Now use\n# $$ cd '%s' && ./msnfs41client install #\n# to install the kernel driver as Admin\n#\n" \
  284. --
  285. 2.43.0
  286.  
  287. From 0955e463cbadad8c456c49d3a3c4b27e993be79c Mon Sep 17 00:00:00 2001
  288. From: Roland Mainz <roland.mainz@nrubsig.org>
  289. Date: Wed, 17 Apr 2024 15:21:18 +0200
  290. Subject: [PATCH 4/4] daemon: "cygwin_idmapper.ksh: line 141: getent: not
  291.  found" if nfsd runs as "SYSTEM"
  292.  
  293. idmapping can fail with a "cygwin_idmapper.ksh: line 141: getent: not found"
  294. error message if nfsd/nfsd_debug runs as user "SYSTEM".
  295. This happens because Cygwin does not include "/bin:/sbin" in the PATH
  296. variable for user "SYSTEM".
  297.  
  298. We fix this by explicitly setting PATH='/bin:/usr/bin' (default
  299. from $ getconf PATH #) in cygwin_idmapper.ksh.
  300.  
  301. Reported-by: Martin Wege <martin.l.wege@gmail.com>
  302. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  303. ---
  304.  cygwin_idmapper.ksh | 2 ++
  305.  1 file changed, 2 insertions(+)
  306.  
  307. diff --git a/cygwin_idmapper.ksh b/cygwin_idmapper.ksh
  308. index 55251b9..588e40b 100644
  309. --- a/cygwin_idmapper.ksh
  310. +++ b/cygwin_idmapper.ksh
  311. @@ -3,6 +3,8 @@
  312.  set -o nounset
  313.  typeset IFS=''
  314.  
  315. +export PATH='/bin:/usr/bin'
  316. +
  317.  #
  318.  # global variables for this script
  319.  # (stored in compound variable so we
  320. --
  321. 2.43.0

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at