1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-03-23 15:09:24 -05:00

pscp: replace crash with diagnostic on opendir failure.

A user points out that the call to close_directory() in pscp.c's
rsource() function should have been inside rather than outside the if
statement that checks whether the directory handle is NULL. As a
result, any failed attempt to open a directory during a 'pscp -r'
recursive upload leads to a null-pointer dereference.

Moved the close_directory call to where it should be, and also
arranged to print the OS error code if the directory-open fails, by
also changing the API of open_directory to return an error string on
failure.
This commit is contained in:
Simon Tatham 2018-12-27 16:52:23 +00:00
parent 3322d4c082
commit 85fbb4216e
5 changed files with 17 additions and 9 deletions

7
pscp.c
View File

@ -1696,7 +1696,8 @@ static void rsource(const char *src)
if (scp_send_dirname(last, 0755)) if (scp_send_dirname(last, 0755))
return; return;
dir = open_directory(src); const char *opendir_err;
dir = open_directory(src, &opendir_err);
if (dir != NULL) { if (dir != NULL) {
char *filename; char *filename;
while ((filename = read_filename(dir)) != NULL) { while ((filename = read_filename(dir)) != NULL) {
@ -1705,8 +1706,10 @@ static void rsource(const char *src)
sfree(foundfile); sfree(foundfile);
sfree(filename); sfree(filename);
} }
}
close_directory(dir); close_directory(dir);
} else {
tell_user(stderr, "Error opening directory %s: %s", src, opendir_err);
}
(void) scp_send_enddir(); (void) scp_send_enddir();

View File

@ -533,6 +533,7 @@ bool sftp_put_file(char *fname, char *outfname, bool recurse, bool restart)
bool result; bool result;
int nnames, namesize; int nnames, namesize;
char *name, **ournames; char *name, **ournames;
const char *opendir_err;
DirHandle *dh; DirHandle *dh;
int i; int i;
@ -563,9 +564,9 @@ bool sftp_put_file(char *fname, char *outfname, bool recurse, bool restart)
nnames = namesize = 0; nnames = namesize = 0;
ournames = NULL; ournames = NULL;
dh = open_directory(fname); dh = open_directory(fname, &opendir_err);
if (!dh) { if (!dh) {
printf("%s: unable to open directory\n", fname); printf("%s: unable to open directory: %s\n", fname, opendir_err);
return false; return false;
} }
while ((name = read_filename(dh)) != NULL) { while ((name = read_filename(dh)) != NULL) {

View File

@ -127,7 +127,7 @@ int file_type(const char *name);
* Read all the file names out of a directory. * Read all the file names out of a directory.
*/ */
typedef struct DirHandle DirHandle; typedef struct DirHandle DirHandle;
DirHandle *open_directory(const char *name); DirHandle *open_directory(const char *name, const char **errmsg);
/* The string returned from this will need freeing if not NULL */ /* The string returned from this will need freeing if not NULL */
char *read_filename(DirHandle *dir); char *read_filename(DirHandle *dir);
void close_directory(DirHandle *dir); void close_directory(DirHandle *dir);

View File

@ -311,14 +311,16 @@ struct DirHandle {
DIR *dir; DIR *dir;
}; };
DirHandle *open_directory(const char *name) DirHandle *open_directory(const char *name, const char **errmsg)
{ {
DIR *dir; DIR *dir;
DirHandle *ret; DirHandle *ret;
dir = opendir(name); dir = opendir(name);
if (!dir) if (!dir) {
*errmsg = strerror(errno);
return NULL; return NULL;
}
ret = snew(DirHandle); ret = snew(DirHandle);
ret->dir = dir; ret->dir = dir;

View File

@ -266,7 +266,7 @@ struct DirHandle {
char *name; char *name;
}; };
DirHandle *open_directory(const char *name) DirHandle *open_directory(const char *name, const char **errmsg)
{ {
HANDLE h; HANDLE h;
WIN32_FIND_DATA fdat; WIN32_FIND_DATA fdat;
@ -276,8 +276,10 @@ DirHandle *open_directory(const char *name)
/* Enumerate files in dir `foo'. */ /* Enumerate files in dir `foo'. */
findfile = dupcat(name, "/*", NULL); findfile = dupcat(name, "/*", NULL);
h = FindFirstFile(findfile, &fdat); h = FindFirstFile(findfile, &fdat);
if (h == INVALID_HANDLE_VALUE) if (h == INVALID_HANDLE_VALUE) {
*errmsg = win_strerror(GetLastError());
return NULL; return NULL;
}
sfree(findfile); sfree(findfile);
ret = snew(DirHandle); ret = snew(DirHandle);