400-CVE-2012-0920.patch 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. # HG changeset patch
  2. # User Matt Johnston <[email protected]>
  3. # Date 1322947885 -28800
  4. # Node ID 818108bf7749bfecd4715a30e2583aac9dbe25e8
  5. # Parent 5e8d84f3ee7256d054ecf7e9f248765ccaa7f24f
  6. - Fix use-after-free if multiple command requests were sent. Move
  7. the original_command into chansess struct since that makes more sense
  8. --- a/auth.h
  9. +++ b/auth.h
  10. @@ -133,7 +133,6 @@ struct PubKeyOptions {
  11. int no_pty_flag;
  12. /* "command=" option. */
  13. unsigned char * forced_command;
  14. - unsigned char * original_command;
  15. };
  16. #endif
  17. --- a/chansession.h
  18. +++ b/chansession.h
  19. @@ -69,6 +69,10 @@ struct ChanSess {
  20. char * agentfile;
  21. char * agentdir;
  22. #endif
  23. +
  24. +#ifdef ENABLE_SVR_PUBKEY_OPTIONS
  25. + char *original_command;
  26. +#endif
  27. };
  28. struct ChildPid {
  29. --- a/svr-authpubkeyoptions.c
  30. +++ b/svr-authpubkeyoptions.c
  31. @@ -92,14 +92,15 @@ int svr_pubkey_allows_pty() {
  32. * by any 'command' public key option. */
  33. void svr_pubkey_set_forced_command(struct ChanSess *chansess) {
  34. if (ses.authstate.pubkey_options) {
  35. - ses.authstate.pubkey_options->original_command = chansess->cmd;
  36. - if (!chansess->cmd)
  37. - {
  38. - ses.authstate.pubkey_options->original_command = m_strdup("");
  39. + if (chansess->cmd) {
  40. + /* original_command takes ownership */
  41. + chansess->original_command = chansess->cmd;
  42. + } else {
  43. + chansess->original_command = m_strdup("");
  44. }
  45. - chansess->cmd = ses.authstate.pubkey_options->forced_command;
  46. + chansess->cmd = m_strdup(ses.authstate.pubkey_options->forced_command);
  47. #ifdef LOG_COMMANDS
  48. - dropbear_log(LOG_INFO, "Command forced to '%s'", ses.authstate.pubkey_options->original_command);
  49. + dropbear_log(LOG_INFO, "Command forced to '%s'", chansess->original_command);
  50. #endif
  51. }
  52. }
  53. --- a/svr-chansession.c
  54. +++ b/svr-chansession.c
  55. @@ -217,6 +217,8 @@ static int newchansess(struct Channel *c
  56. struct ChanSess *chansess;
  57. + TRACE(("new chansess %p", channel))
  58. +
  59. dropbear_assert(channel->typedata == NULL);
  60. chansess = (struct ChanSess*)m_malloc(sizeof(struct ChanSess));
  61. @@ -279,6 +281,10 @@ static void closechansess(struct Channel
  62. m_free(chansess->cmd);
  63. m_free(chansess->term);
  64. +#ifdef ENABLE_SVR_PUBKEY_OPTIONS
  65. + m_free(chansess->original_command);
  66. +#endif
  67. +
  68. if (chansess->tty) {
  69. /* write the utmp/wtmp login record */
  70. li = chansess_login_alloc(chansess);
  71. @@ -924,10 +930,8 @@ static void execchild(void *user_data) {
  72. }
  73. #ifdef ENABLE_SVR_PUBKEY_OPTIONS
  74. - if (ses.authstate.pubkey_options &&
  75. - ses.authstate.pubkey_options->original_command) {
  76. - addnewvar("SSH_ORIGINAL_COMMAND",
  77. - ses.authstate.pubkey_options->original_command);
  78. + if (chansess->original_command) {
  79. + addnewvar("SSH_ORIGINAL_COMMAND", chansess->original_command);
  80. }
  81. #endif