1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

Another big batch of memory leak fixes, again mostly on error paths.

The most interesting one is printer_add_enum, which I've modified to
take a char ** rather than a char * so that it can both realloc its
input buffer _and_ return NULL to indicate error.

[originally from svn r9959]
This commit is contained in:
Simon Tatham 2013-07-22 07:11:54 +00:00
parent 4c61cb20a1
commit b99bec3b02
9 changed files with 107 additions and 42 deletions

View File

@ -448,6 +448,8 @@ char *staticwrap(struct ctlpos *cp, HWND hwnd, char *text, int *lines)
if (lines) *lines = nlines;
sfree(pwidths);
return ret;
}
@ -1665,7 +1667,9 @@ void winctrl_layout(struct dlgparam *dp, struct winctrls *wc,
winctrl_add_shortcuts(dp, c);
if (actual_base_id == base_id)
base_id += num_ids;
}
} else {
sfree(data);
}
if (colstart >= 0) {
/*

View File

@ -2197,8 +2197,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
reconfig_result =
do_reconfig(hwnd, back ? back->cfg_info(backhandle) : 0);
reconfiguring = FALSE;
if (!reconfig_result)
if (!reconfig_result) {
conf_free(prev_conf);
break;
}
conf_cache_data();
@ -4903,10 +4905,17 @@ void write_clip(void *frontend, wchar_t * data, int *attr, int len, int must_des
GlobalFree(clipdata2);
return;
}
if (!(lock = GlobalLock(clipdata)))
if (!(lock = GlobalLock(clipdata))) {
GlobalFree(clipdata);
GlobalFree(clipdata2);
return;
if (!(lock2 = GlobalLock(clipdata2)))
}
if (!(lock2 = GlobalLock(clipdata2))) {
GlobalUnlock(clipdata);
GlobalFree(clipdata);
GlobalFree(clipdata2);
return;
}
memcpy(lock, data, len * sizeof(wchar_t));
WideCharToMultiByte(CP_ACP, 0, data, len, lock2, len2, NULL, NULL);

View File

@ -410,16 +410,20 @@ static IShellLink *make_shell_link(const char *appname,
/* Check if this is a valid session, otherwise don't add. */
if (sessionname) {
psettings_tmp = open_settings_r(sessionname);
if (!psettings_tmp)
if (!psettings_tmp) {
sfree(app_path);
return NULL;
}
close_settings_r(psettings_tmp);
}
/* Create the new item. */
if (!SUCCEEDED(CoCreateInstance(&CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER,
COMPTR(IShellLink, &ret))))
COMPTR(IShellLink, &ret)))) {
sfree(app_path);
return NULL;
}
/* Set path, parameters, icon and description. */
ret->lpVtbl->SetPath(ret, app_path);

View File

@ -420,11 +420,11 @@ static int save_ssh1_pubkey(char *filename, struct RSAKey *key)
char *dec1, *dec2;
FILE *fp;
dec1 = bignum_decimal(key->exponent);
dec2 = bignum_decimal(key->modulus);
fp = fopen(filename, "wb");
if (!fp)
return 0;
dec1 = bignum_decimal(key->exponent);
dec2 = bignum_decimal(key->modulus);
fprintf(fp, "%d %s %s %s\n",
bignum_bitcount(key->modulus), dec1, dec2, key->comment);
fclose(fp);
@ -1256,9 +1256,11 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
if (!state->generation_thread_exists) {
char filename[FILENAME_MAX];
if (prompt_keyfile(hwnd, "Load private key:",
filename, 0, LOWORD(wParam)==IDC_LOAD))
load_key_file(hwnd, state, filename_from_str(filename),
LOWORD(wParam) != IDC_LOAD);
filename, 0, LOWORD(wParam)==IDC_LOAD)) {
Filename *fn = filename_from_str(filename);
load_key_file(hwnd, state, fn, LOWORD(wParam) != IDC_LOAD);
filename_free(fn);
}
}
break;
}

View File

@ -811,8 +811,10 @@ static void *get_keylist1(int *length)
retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL);
assert(retval == 1);
response = vresponse;
if (resplen < 5 || response[4] != SSH1_AGENT_RSA_IDENTITIES_ANSWER)
if (resplen < 5 || response[4] != SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
sfree(response);
return NULL;
}
ret = snewn(resplen-5, unsigned char);
memcpy(ret, response+5, resplen-5);
@ -846,8 +848,10 @@ static void *get_keylist2(int *length)
retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL);
assert(retval == 1);
response = vresponse;
if (resplen < 5 || response[4] != SSH2_AGENT_IDENTITIES_ANSWER)
if (resplen < 5 || response[4] != SSH2_AGENT_IDENTITIES_ANSWER) {
sfree(response);
return NULL;
}
ret = snewn(resplen-5, unsigned char);
memcpy(ret, response+5, resplen-5);
@ -942,12 +946,17 @@ static void answer_msg(void *msg)
goto failure;
p += i;
i = ssh1_read_bignum(p, msgend - p, &reqkey.modulus);
if (i < 0)
if (i < 0) {
freebn(reqkey.exponent);
goto failure;
}
p += i;
i = ssh1_read_bignum(p, msgend - p, &challenge);
if (i < 0)
if (i < 0) {
freebn(reqkey.exponent);
freebn(reqkey.modulus);
goto failure;
}
p += i;
if (msgend < p+16) {
freebn(reqkey.exponent);
@ -1437,10 +1446,12 @@ static void prompt_add_keyfile(void)
of.lpstrTitle = "Select Private Key File";
of.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER;
if (request_file(keypath, &of, TRUE, FALSE)) {
if(strlen(filelist) > of.nFileOffset)
if(strlen(filelist) > of.nFileOffset) {
/* Only one filename returned? */
add_keyfile(filename_from_str(filelist));
else {
Filename *fn = filename_from_str(filelist);
add_keyfile(fn);
filename_free(fn);
} else {
/* we are returned a bunch of strings, end to
* end. first string is the directory, the
* rest the filenames. terminated with an
@ -1450,7 +1461,9 @@ static void prompt_add_keyfile(void)
char *filewalker = filelist + strlen(dir) + 1;
while (*filewalker != '\0') {
char *filename = dupcat(dir, "\\", filewalker, NULL);
add_keyfile(filename_from_str(filename));
Filename *fn = filename_from_str(filename);
add_keyfile(fn);
filename_free(fn);
sfree(filename);
filewalker += strlen(filewalker) + 1;
}
@ -1908,6 +1921,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
#ifdef DEBUG_IPC
debug(("couldn't get user SID\n"));
#endif
CloseHandle(filemap);
return 0;
}
@ -1915,6 +1929,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
#ifdef DEBUG_IPC
debug(("couldn't get default SID\n"));
#endif
CloseHandle(filemap);
sfree(ourself);
return 0;
}
@ -1926,6 +1942,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
debug(("couldn't get owner info for filemap: %d\n",
rc));
#endif
CloseHandle(filemap);
sfree(ourself);
sfree(ourself2);
return 0;
}
#ifdef DEBUG_IPC
@ -1944,6 +1963,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
if (!EqualSid(mapowner, ourself) &&
!EqualSid(mapowner, ourself2)) {
CloseHandle(filemap);
LocalFree(psd);
sfree(ourself);
sfree(ourself2);
return 0; /* security ID mismatch! */
}
#ifdef DEBUG_IPC
@ -2127,7 +2149,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
command = "";
break;
} else {
add_keyfile(filename_from_str(argv[i]));
Filename *fn = filename_from_str(argv[i]);
add_keyfile(fn);
filename_free(fn);
added_keys = TRUE;
}
}

View File

@ -209,8 +209,10 @@ int agent_query(void *in, int inlen, void **out, int *outlen,
filemap = CreateFileMapping(INVALID_HANDLE_VALUE, psa, PAGE_READWRITE,
0, AGENT_MAX_MSGLEN, mapname);
if (filemap == NULL || filemap == INVALID_HANDLE_VALUE)
if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) {
sfree(mapname);
return 1; /* *out == NULL, so failure */
}
p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
memcpy(p, in, inlen);
cds.dwData = AGENT_COPYDATA_ID;
@ -237,6 +239,7 @@ int agent_query(void *in, int inlen, void **out, int *outlen,
data->hwnd = hwnd;
if (CreateThread(NULL, 0, agent_query_thread, data, 0, &threadid))
return 0;
sfree(mapname);
sfree(data);
}
#endif
@ -258,6 +261,7 @@ int agent_query(void *in, int inlen, void **out, int *outlen,
}
UnmapViewOfFile(p);
CloseHandle(filemap);
sfree(mapname);
if (psd)
LocalFree(psd);
sfree(usersid);

View File

@ -18,39 +18,39 @@ struct printer_job_tag {
HANDLE hprinter;
};
static char *printer_add_enum(int param, DWORD level, char *buffer,
int offset, int *nprinters_ptr)
static int printer_add_enum(int param, DWORD level, char **buffer,
int offset, int *nprinters_ptr)
{
DWORD needed = 0, nprinters = 0;
buffer = sresize(buffer, offset+512, char);
*buffer = sresize(*buffer, offset+512, char);
/*
* Exploratory call to EnumPrinters to determine how much space
* we'll need for the output. Discard the return value since it
* will almost certainly be a failure due to lack of space.
*/
EnumPrinters(param, NULL, level, buffer+offset, 512,
EnumPrinters(param, NULL, level, (*buffer)+offset, 512,
&needed, &nprinters);
if (needed < 512)
needed = 512;
buffer = sresize(buffer, offset+needed, char);
*buffer = sresize(*buffer, offset+needed, char);
if (EnumPrinters(param, NULL, level, buffer+offset,
if (EnumPrinters(param, NULL, level, (*buffer)+offset,
needed, &needed, &nprinters) == 0)
return NULL;
return FALSE;
*nprinters_ptr += nprinters;
return buffer;
return TRUE;
}
printer_enum *printer_start_enum(int *nprinters_ptr)
{
printer_enum *ret = snew(printer_enum);
char *buffer = NULL, *retval;
char *buffer = NULL;
*nprinters_ptr = 0; /* default return value */
buffer = snewn(512, char);
@ -71,12 +71,9 @@ printer_enum *printer_start_enum(int *nprinters_ptr)
ret->enum_level = 4;
}
retval = printer_add_enum(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
ret->enum_level, buffer, 0, nprinters_ptr);
if (!retval)
if (!printer_add_enum(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
ret->enum_level, &buffer, 0, nprinters_ptr))
goto error;
else
buffer = retval;
switch (ret->enum_level) {
case 4:

View File

@ -180,6 +180,7 @@ Socket platform_new_connection(SockAddr addr, char *hostname,
sa.bInheritHandle = TRUE;
if (!CreatePipe(&us_from_cmd, &cmd_to_us, &sa, 0)) {
ret->error = dupprintf("Unable to create pipes for proxy command");
sfree(cmd);
return (Socket)ret;
}
@ -187,6 +188,7 @@ Socket platform_new_connection(SockAddr addr, char *hostname,
CloseHandle(us_from_cmd);
CloseHandle(cmd_to_us);
ret->error = dupprintf("Unable to create pipes for proxy command");
sfree(cmd);
return (Socket)ret;
}

View File

@ -167,7 +167,10 @@ char *read_setting_s(void *handle, const char *key)
ret = snewn(size+1, char);
if (RegQueryValueEx((HKEY) handle, key, 0,
&type, ret, &size) != ERROR_SUCCESS ||
type != REG_SZ) return NULL;
type != REG_SZ) {
sfree(ret);
return NULL;
}
return ret;
}
@ -190,6 +193,7 @@ FontSpec *read_setting_fontspec(void *handle, const char *name)
{
char *settingname;
char *fontname;
FontSpec *ret;
int isbold, height, charset;
fontname = read_setting_s(handle, name);
@ -199,19 +203,30 @@ FontSpec *read_setting_fontspec(void *handle, const char *name)
settingname = dupcat(name, "IsBold", NULL);
isbold = read_setting_i(handle, settingname, -1);
sfree(settingname);
if (isbold == -1) return NULL;
if (isbold == -1) {
sfree(fontname);
return NULL;
}
settingname = dupcat(name, "CharSet", NULL);
charset = read_setting_i(handle, settingname, -1);
sfree(settingname);
if (charset == -1) return NULL;
if (charset == -1) {
sfree(fontname);
return NULL;
}
settingname = dupcat(name, "Height", NULL);
height = read_setting_i(handle, settingname, INT_MIN);
sfree(settingname);
if (height == INT_MIN) return NULL;
if (height == INT_MIN) {
sfree(fontname);
return NULL;
}
return fontspec_new(fontname, isbold, height, charset);
ret = fontspec_new(fontname, isbold, height, charset);
sfree(fontname);
return ret;
}
void write_setting_fontspec(void *handle, const char *name, FontSpec *font)
@ -340,16 +355,18 @@ int verify_host_key(const char *hostname, int port,
* Now read a saved key in from the registry and see what it
* says.
*/
otherstr = snewn(len, char);
regname = snewn(3 * (strlen(hostname) + strlen(keytype)) + 15, char);
hostkey_regname(regname, hostname, port, keytype);
if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",
&rkey) != ERROR_SUCCESS)
&rkey) != ERROR_SUCCESS) {
sfree(regname);
return 1; /* key does not exist in registry */
}
readlen = len;
otherstr = snewn(len, char);
ret = RegQueryValueEx(rkey, regname, NULL, &type, otherstr, &readlen);
if (ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA &&
@ -412,6 +429,8 @@ int verify_host_key(const char *hostname, int port,
RegSetValueEx(rkey, regname, 0, REG_SZ, otherstr,
strlen(otherstr) + 1);
}
sfree(oldstyle);
}
RegCloseKey(rkey);