aboutsummaryrefslogblamecommitdiffstats
path: root/main/dropbear/after-free-fix.patch
blob: 2f239637dfd7d03524402968f0bfe529da4f3be1 (plain) (tree)































































































                                                                                                                 

# HG changeset patch
# User Matt Johnston <matt@ucc.asn.au>
# 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