Skip to content

Commit

Permalink
Free memory before exiting. Based on patch from Thorsten Horstmann.
Browse files Browse the repository at this point in the history
Client side is not complete.
  • Loading branch information
mkj committed Feb 24, 2015
1 parent 4b1f5ec commit 21bed0d
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 14 deletions.
45 changes: 33 additions & 12 deletions common-session.c
Expand Up @@ -240,6 +240,15 @@ void session_loop(void(*loophandler)()) {
/* Not reached */
}

static void cleanup_buf(buffer **buf) {
if (!*buf) {
return;
}
buf_burn(*buf);
buf_free(*buf);
*buf = NULL;
}

/* clean up a session on exit */
void session_cleanup() {

Expand All @@ -256,19 +265,31 @@ void session_cleanup() {
}

chancleanup();

/* Cleaning up keys must happen after other cleanup
functions which might queue packets */
if (ses.session_id) {
buf_burn(ses.session_id);
buf_free(ses.session_id);
ses.session_id = NULL;
}
if (ses.hash) {
buf_burn(ses.hash);
buf_free(ses.hash);
ses.hash = NULL;

/* Most dropbear functions are unsafe to run after this point */
#ifdef DROPBEAR_CLEANUP
/* listeners call cleanup functions, this should occur before
other session state is freed. */
remove_all_listeners();

while (!isempty(&ses.writequeue)) {
buf_free(dequeue(&ses.writequeue));
}

m_free(ses.remoteident);
m_free(ses.authstate.pw_dir);
m_free(ses.authstate.pw_name);
m_free(ses.authstate.pw_shell);
m_free(ses.authstate.pw_passwd);
m_free(ses.authstate.username);
#endif

cleanup_buf(&ses.session_id);
cleanup_buf(&ses.hash);
cleanup_buf(&ses.payload);
cleanup_buf(&ses.readbuf);
cleanup_buf(&ses.writepayload);

m_burn(ses.keys, sizeof(struct key_context));
m_free(ses.keys);

Expand Down
9 changes: 9 additions & 0 deletions listener.c
Expand Up @@ -161,5 +161,14 @@ void remove_listener(struct Listener* listener) {
}
ses.listeners[listener->index] = NULL;
m_free(listener);
}

void remove_all_listeners(void) {
unsigned int i;
for (i = 0; i < ses.listensize; i++) {
if (ses.listeners[i]) {
remove_listener(ses.listeners[i]);
}
}
m_free(ses.listeners);
}
2 changes: 2 additions & 0 deletions listener.h
Expand Up @@ -60,4 +60,6 @@ struct Listener * get_listener(int type, void* typedata,

void remove_listener(struct Listener* listener);

void remove_all_listeners(void);

#endif /* DROPBEAR_LISTENER_H */
4 changes: 4 additions & 0 deletions svr-chansession.c
Expand Up @@ -787,9 +787,11 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) {

TRACE(("back to normal sigchld"))
/* Revert to normal sigchld handling */
/*
if (signal(SIGCHLD, SIG_DFL) == SIG_ERR) {
dropbear_exit("signal() error");
}
*/

/* redirect stdin/stdout/stderr */
close(chansess->master);
Expand Down Expand Up @@ -1005,9 +1007,11 @@ void svr_chansessinitialise() {
sa_chld.sa_handler = sesssigchild_handler;
sa_chld.sa_flags = SA_NOCLDSTOP;
sigemptyset(&sa_chld.sa_mask);
/*
if (sigaction(SIGCHLD, &sa_chld, NULL) < 0) {
dropbear_exit("signal() error");
}
*/

}

Expand Down
17 changes: 15 additions & 2 deletions svr-session.c
Expand Up @@ -78,10 +78,13 @@ static const struct ChanType *svr_chantypes[] = {
};

static void
svr_session_cleanup(void)
{
svr_session_cleanup(void) {
/* free potential public key options */
svr_pubkey_options_cleanup();

m_free(svr_ses.addrstring);
m_free(svr_ses.childpids);
m_free(svr_ses.remotehost);
}

static void
Expand Down Expand Up @@ -150,6 +153,7 @@ void svr_session(int sock, int childpipe) {
void svr_dropbear_exit(int exitcode, const char* format, va_list param) {

char fmtbuf[300];
int i;

if (!sessinitdone) {
/* before session init */
Expand Down Expand Up @@ -183,6 +187,15 @@ void svr_dropbear_exit(int exitcode, const char* format, va_list param) {
session_cleanup();
}

if (svr_opts.hostkey) {
sign_key_free(svr_opts.hostkey);
svr_opts.hostkey = NULL;
}
for (i = 0; i < DROPBEAR_MAX_PORTS; i++) {
m_free(svr_opts.addresses[i]);
m_free(svr_opts.ports[i]);
}

exit(exitcode);

}
Expand Down
3 changes: 3 additions & 0 deletions sysoptions.h
Expand Up @@ -256,6 +256,9 @@
#define DROPBEAR_LISTEN_BACKLOG MAX_CHANNELS
#endif

/* free memory before exiting */
#define DROPBEAR_CLEANUP

/* Use this string since some implementations might special-case it */
#define DROPBEAR_KEEPALIVE_STRING "keepalive@openssh.com"

Expand Down

0 comments on commit 21bed0d

Please sign in to comment.