# HG changeset patch # User Matt Johnston # Date 1322947885 -28800 # Node ID 818108bf7749bfecd4715a30e2583aac9dbe25e8 # Parent 5e8d84f3ee7256d054ecf7e9f248765ccaa7f24f - Fix use-after-free if multiple command requests were sent. Move the original_command into chansess struct since that makes more sense diff -r 5e8d84f3ee72 -r 818108bf7749 auth.h --- a/auth.h Sun Dec 04 05:27:57 2011 +0800 +++ b/auth.h Sun Dec 04 05:31:25 2011 +0800 @@ -133,7 +133,6 @@ int no_pty_flag; /* "command=" option. */ unsigned char * forced_command; - unsigned char * original_command; }; #endif diff -r 5e8d84f3ee72 -r 818108bf7749 chansession.h --- a/chansession.h Sun Dec 04 05:27:57 2011 +0800 +++ b/chansession.h Sun Dec 04 05:31:25 2011 +0800 @@ -69,6 +69,10 @@ char * agentfile; char * agentdir; #endif + +#ifdef ENABLE_SVR_PUBKEY_OPTIONS + char *original_command; +#endif }; struct ChildPid { diff -r 5e8d84f3ee72 -r 818108bf7749 svr-authpubkeyoptions.c --- a/svr-authpubkeyoptions.c Sun Dec 04 05:27:57 2011 +0800 +++ b/svr-authpubkeyoptions.c Sun Dec 04 05:31:25 2011 +0800 @@ -92,14 +92,15 @@ * by any 'command' public key option. */ void svr_pubkey_set_forced_command(struct ChanSess *chansess) { if (ses.authstate.pubkey_options) { - ses.authstate.pubkey_options->original_command = chansess->cmd; - if (!chansess->cmd) - { - ses.authstate.pubkey_options->original_command = m_strdup(""); + if (chansess->cmd) { + /* original_command takes ownership */ + chansess->original_command = chansess->cmd; + } else { + chansess->original_command = m_strdup(""); } - chansess->cmd = ses.authstate.pubkey_options->forced_command; + chansess->cmd = m_strdup(ses.authstate.pubkey_options->forced_command); #ifdef LOG_COMMANDS - dropbear_log(LOG_INFO, "Command forced to '%s'", ses.authstate.pubkey_options->original_command); + dropbear_log(LOG_INFO, "Command forced to '%s'", chansess->original_command); #endif } } diff -r 5e8d84f3ee72 -r 818108bf7749 svr-chansession.c --- a/svr-chansession.c Sun Dec 04 05:27:57 2011 +0800 +++ b/svr-chansession.c Sun Dec 04 05:31:25 2011 +0800 @@ -217,6 +217,8 @@ struct ChanSess *chansess; + TRACE(("new chansess %p", channel)) + dropbear_assert(channel->typedata == NULL); chansess = (struct ChanSess*)m_malloc(sizeof(struct ChanSess)); @@ -279,6 +281,10 @@ m_free(chansess->cmd); m_free(chansess->term); +#ifdef ENABLE_SVR_PUBKEY_OPTIONS + m_free(chansess->original_command); +#endif + if (chansess->tty) { /* write the utmp/wtmp login record */ li = chansess_login_alloc(chansess); @@ -924,10 +930,8 @@ } #ifdef ENABLE_SVR_PUBKEY_OPTIONS - if (ses.authstate.pubkey_options && - ses.authstate.pubkey_options->original_command) { - addnewvar("SSH_ORIGINAL_COMMAND", - ses.authstate.pubkey_options->original_command); + if (chansess->original_command) { + addnewvar("SSH_ORIGINAL_COMMAND", chansess->original_command); } #endif