@@ -2919,9 +2919,12 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
29192919 word32 idx = 0 ;
29202920 int ret = WS_SUCCESS ;
29212921 int rc ;
2922+ WS_DIR_LIST * cur ;
2923+ char * dirName ;
2924+ word32 dirNameSz ;
29222925
29232926 word32 outSz = WOLFSSH_HANDLE_ID_SZ + WOLFSSH_SFTP_HEADER + UINT32_SZ ;
2924- byte * out = NULL ;
2927+ byte * out ;
29252928 byte idFlat [WOLFSSH_HANDLE_ID_SZ ];
29262929 char per [] = "Permission denied" ;
29272930 char tooMany [] = "Too Many Open Directory Handles" ;
@@ -2960,71 +2963,46 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
29602963
29612964 if (WOPENDIR (ssh -> fs , ssh -> ctx -> heap , & ctx , dir ) != 0 ) {
29622965 WLOG (WS_LOG_SFTP , "Error with opening directory: %s" , dir );
2963- if (wolfSSH_SFTP_CreateStatus (ssh , WOLFSSH_FTP_NOFILE , reqId ,
2964- "Unable To Open Directory" , "English" , NULL , & outSz )
2965- != WS_SIZE_ONLY ) {
2966- return WS_FATAL_ERROR ;
2967- }
2968- ret = WS_BAD_FILE_E ;
2966+ rc = SFTP_SendStatus (ssh , WOLFSSH_FTP_NOFILE , reqId ,
2967+ "Unable To Open Directory" );
2968+ return (rc == WS_SUCCESS ) ? WS_BAD_FILE_E : rc ;
29692969 }
29702970
2971- WOLFSSH_UNUSED (reqId );
2972-
2973- if (ret == WS_SUCCESS ) {
2974- WS_DIR_LIST * cur = NULL ;
2975- char * dirName = NULL ;
2976- word32 dirNameSz ;
2971+ /* allocate everything, the reply included, before publishing the handle
2972+ * so a failure leaves no handle the peer was never told about */
2973+ dirNameSz = (word32 )WSTRLEN (dir ) + 1 ;
2974+ cur = (WS_DIR_LIST * )WMALLOC (sizeof (WS_DIR_LIST ),
2975+ ssh -> ctx -> heap , DYNTYPE_SFTP );
2976+ dirName = (char * )WMALLOC (dirNameSz , ssh -> ctx -> heap , DYNTYPE_PATH );
2977+ out = (byte * )WMALLOC (outSz , ssh -> ctx -> heap , DYNTYPE_BUFFER );
2978+ if (cur == NULL || dirName == NULL || out == NULL ) {
2979+ WCLOSEDIR (ssh -> fs , & ctx );
2980+ WFREE (cur , ssh -> ctx -> heap , DYNTYPE_SFTP );
2981+ WFREE (dirName , ssh -> ctx -> heap , DYNTYPE_PATH );
2982+ WFREE (out , ssh -> ctx -> heap , DYNTYPE_BUFFER );
2983+ return WS_MEMORY_E ;
2984+ }
29772985
2978- cur = (WS_DIR_LIST * )WMALLOC (sizeof (WS_DIR_LIST ),
2979- ssh -> ctx -> heap , DYNTYPE_SFTP );
2980- if (cur == NULL ) {
2981- WCLOSEDIR (ssh -> fs , & ctx );
2982- return WS_MEMORY_E ;
2983- }
2984- dirNameSz = (word32 )WSTRLEN (dir ) + 1 ;
2985- dirName = (char * )WMALLOC (dirNameSz ,
2986- ssh -> ctx -> heap , DYNTYPE_PATH );
2987- if (dirName == NULL ) {
2988- WCLOSEDIR (ssh -> fs , & ctx );
2989- WFREE (cur , ssh -> ctx -> heap , DYNTYPE_SFTP );
2990- return WS_MEMORY_E ;
2991- }
2992- WMEMCPY (dirName , dir , dirNameSz );
2986+ WMEMCPY (dirName , dir , dirNameSz );
29932987#ifdef WOLFSSL_NUCLEUS
2994- WMEMCPY (& cur -> dir , & ctx , sizeof (WDIR ));
2988+ WMEMCPY (& cur -> dir , & ctx , sizeof (WDIR ));
29952989#else
2996- cur -> dir = ctx ;
2990+ cur -> dir = ctx ;
29972991#endif
2998- SFTP_HandleIdNext (ssh , cur -> id );
2999- SFTP_HandleIdEncode (cur -> id , idFlat );
3000- cur -> isEof = 0 ;
3001- cur -> next = ssh -> dirList ;
3002- ssh -> dirList = cur ;
3003- ssh -> dirList -> dirName = dirName ; /* take over ownership of buffer */
3004- }
2992+ SFTP_HandleIdNext (ssh , cur -> id );
2993+ SFTP_HandleIdEncode (cur -> id , idFlat );
2994+ cur -> isEof = 0 ;
2995+ cur -> dirName = dirName ; /* take over ownership of buffer */
2996+ cur -> next = ssh -> dirList ;
2997+ ssh -> dirList = cur ;
30052998
3006- out = (byte * )WMALLOC (outSz , ssh -> ctx -> heap , DYNTYPE_BUFFER );
3007- if (out == NULL ) {
3008- return WS_MEMORY_E ;
3009- }
3010-
3011- if (ret == WS_SUCCESS ) {
3012- SFTP_CreatePacket (ssh , WOLFSSH_FTP_HANDLE , out , outSz ,
3013- idFlat , sizeof (idFlat ));
3014- }
3015- else {
3016- if (wolfSSH_SFTP_CreateStatus (ssh , WOLFSSH_FTP_NOFILE , reqId ,
3017- "Unable To Open Directory" , "English" , out , & outSz )
3018- != WS_SUCCESS ) {
3019- WFREE (out , ssh -> ctx -> heap , DYNTYPE_BUFFER );
3020- return WS_FATAL_ERROR ;
3021- }
3022- }
2999+ SFTP_CreatePacket (ssh , WOLFSSH_FTP_HANDLE , out , outSz ,
3000+ idFlat , sizeof (idFlat ));
30233001
30243002 /* set send out buffer, "out" is taken by ssh */
30253003 wolfSSH_SFTP_RecvSetSend (ssh , out , outSz );
30263004
3027- return ret ;
3005+ return WS_SUCCESS ;
30283006}
30293007#else /* USE_WINDOWS_API */
30303008{
@@ -3037,9 +3015,10 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
30373015 int isDir = 0 ;
30383016 int ret = WS_SUCCESS ;
30393017 int rc ;
3018+ WS_DIR_LIST * cur ;
30403019
30413020 word32 outSz = WOLFSSH_HANDLE_ID_SZ + WOLFSSH_SFTP_HEADER + UINT32_SZ ;
3042- byte * out = NULL ;
3021+ byte * out ;
30433022 byte idFlat [WOLFSSH_HANDLE_ID_SZ ];
30443023 char name [MAX_PATH ];
30453024 char clean [WOLFSSH_MAX_FILENAME ];
@@ -3133,62 +3112,45 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
31333112 findHandle = (HANDLE )WS_FindFirstFileA (name ,
31343113 realName , sizeof (realName ), & isDir , ssh -> ctx -> heap );
31353114 if (findHandle == INVALID_HANDLE_VALUE || !isDir ) {
3136-
31373115 WLOG (WS_LOG_SFTP , "Error with opening directory: %s" , name );
3138- WFREE (dirName , ssh -> ctx -> heap , DYNTYPE_BUFFER );
3139-
3140- if (wolfSSH_SFTP_CreateStatus (ssh , WOLFSSH_FTP_NOFILE , reqId ,
3141- "Unable To Open Directory" , "English" , NULL , & outSz )
3142- != WS_SIZE_ONLY ) {
3143- return WS_FATAL_ERROR ;
3144- }
31453116 ret = WS_BAD_FILE_E ;
31463117 }
31473118 if (findHandle != NULL && findHandle != INVALID_HANDLE_VALUE )
31483119 FindClose (findHandle );
3149- }
3150-
3151- WOLFSSH_UNUSED (reqId );
3152-
3153- if (ret == WS_SUCCESS ) {
3154- WS_DIR_LIST * cur = (WS_DIR_LIST * )WMALLOC (sizeof (WS_DIR_LIST ),
3155- ssh -> ctx -> heap , DYNTYPE_SFTP );
3156- if (cur == NULL ) {
3120+ if (ret != WS_SUCCESS ) {
31573121 WFREE (dirName , ssh -> ctx -> heap , DYNTYPE_BUFFER );
3158- return WS_MEMORY_E ;
3122+ rc = SFTP_SendStatus (ssh , WOLFSSH_FTP_NOFILE , reqId ,
3123+ "Unable To Open Directory" );
3124+ return (rc == WS_SUCCESS ) ? ret : rc ;
31593125 }
3160- cur -> dir = INVALID_HANDLE_VALUE ;
3161- SFTP_HandleIdNext (ssh , cur -> id );
3162- SFTP_HandleIdEncode (cur -> id , idFlat );
3163- cur -> isEof = 0 ;
3164- cur -> dirName = dirName ; /* take over ownership of buffer */
3165- cur -> next = ssh -> dirList ;
3166- ssh -> dirList = cur ;
3167-
31683126 }
31693127
3128+ /* allocate the reply before publishing the handle so a failure leaves
3129+ * no handle the peer was never told about */
3130+ cur = (WS_DIR_LIST * )WMALLOC (sizeof (WS_DIR_LIST ),
3131+ ssh -> ctx -> heap , DYNTYPE_SFTP );
31703132 out = (byte * )WMALLOC (outSz , ssh -> ctx -> heap , DYNTYPE_BUFFER );
3171- if (out == NULL ) {
3133+ if (cur == NULL || out == NULL ) {
3134+ WFREE (cur , ssh -> ctx -> heap , DYNTYPE_SFTP );
3135+ WFREE (out , ssh -> ctx -> heap , DYNTYPE_BUFFER );
3136+ WFREE (dirName , ssh -> ctx -> heap , DYNTYPE_BUFFER );
31723137 return WS_MEMORY_E ;
31733138 }
3139+ cur -> dir = INVALID_HANDLE_VALUE ;
3140+ SFTP_HandleIdNext (ssh , cur -> id );
3141+ SFTP_HandleIdEncode (cur -> id , idFlat );
3142+ cur -> isEof = 0 ;
3143+ cur -> dirName = dirName ; /* take over ownership of buffer */
3144+ cur -> next = ssh -> dirList ;
3145+ ssh -> dirList = cur ;
31743146
3175- if (ret == WS_SUCCESS ) {
3176- SFTP_CreatePacket (ssh , WOLFSSH_FTP_HANDLE , out , outSz ,
3177- idFlat , sizeof (idFlat ));
3178- }
3179- else {
3180- if (wolfSSH_SFTP_CreateStatus (ssh , WOLFSSH_FTP_NOFILE , reqId ,
3181- "Unable To Open Directory" , "English" , out , & outSz )
3182- != WS_SUCCESS ) {
3183- WFREE (out , ssh -> ctx -> heap , DYNTYPE_BUFFER );
3184- return WS_FATAL_ERROR ;
3185- }
3186- }
3147+ SFTP_CreatePacket (ssh , WOLFSSH_FTP_HANDLE , out , outSz ,
3148+ idFlat , sizeof (idFlat ));
31873149
31883150 /* set send out buffer, "out" is taken by ssh */
31893151 wolfSSH_SFTP_RecvSetSend (ssh , out , outSz );
31903152
3191- return ret ;
3153+ return WS_SUCCESS ;
31923154}
31933155#endif /* USE_WINDOWS_API */
31943156
0 commit comments