[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#50512: Buffer overflow in openssh pam adapter



Package: ssh
Version: 1:1.2pre11-2
Severity: critical

The PAM adapter in sshd takes random memory as part of a message to be
sent, and writes a NUL into random byte after that memory:

      pamconv_msg[strlen(pamconv_msg)] = '\n';
      pamconv_msg[strlen(pamconv_msg) + 1] = '\0';

This is a Bad Thing.

The below patch seems to eliminate this bug.  However, the the entire
PAM adapter needs a careful memory-usage audit to make sure there are
no more such bugs.  For that matter, libpam needs an audit, too; I
found a memory leak in the motd module without even trying.


Index: sshd.c
*************** static int pamconv(int num_msg, const st
*** 151,156 ****
                     struct pam_response **resp, void *appdata_ptr)
  {
!   int count = 0;
!   struct pam_response *reply = NULL;
  
    /* PAM will free this later */
--- 151,158 ----
                     struct pam_response **resp, void *appdata_ptr)
  {
!   struct pam_response *reply;
!   int count;
!   size_t msg_len;
!   char *p;
  
    /* PAM will free this later */
*************** static int pamconv(int num_msg, const st
*** 177,199 ****
          reply[count].resp = xstrdup("");
  	
! 	if (msg[count]->msg == NULL) break;
  	debug("Adding PAM message: %s", msg[count]->msg);
! 	if (pamconv_msg == NULL)
! 	{
! 	  pamconv_msg = malloc(strlen(msg[count]->msg) + 2);
! 	  
! 	  if (pamconv_msg == NULL)
! 	    return PAM_CONV_ERR;
! 	    
! 	  strncpy(pamconv_msg, msg[count]->msg, strlen(msg[count]->msg));
! 	  pamconv_msg[strlen(msg[count]->msg)] = '\n';
! 	  pamconv_msg[strlen(msg[count]->msg) + 1] = '\0';
! 	} else
  	{
! 	  pamconv_msg = realloc(pamconv_msg, strlen(pamconv_msg) + strlen(msg[count]->msg) + 2);
! 	  strncat(pamconv_msg, msg[count]->msg, strlen(msg[count]->msg));
! 	  pamconv_msg[strlen(pamconv_msg)] = '\n';
! 	  pamconv_msg[strlen(pamconv_msg) + 1] = '\0';
  	}
          break;
  
--- 179,198 ----
          reply[count].resp = xstrdup("");
  	
! 	if (msg[count]->msg == NULL)
! 	    break;
  	debug("Adding PAM message: %s", msg[count]->msg);
! 
! 	msg_len = strlen(msg[count]->msg);
! 	if (pamconv_msg)
  	{
! 	  size_t n = strlen(pamconv_msg);
! 	  pamconv_msg = xrealloc(pamconv_msg, n + msg_len + 2);
! 	  p = pamconv_msg + n;
  	}
+ 	else
+ 	  pamconv_msg = p = xmalloc(msg_len + 2);
+ 	memcpy(p, msg[count]->msg, msg_len);
+ 	p[msg_len] = '\n';
+ 	p[msg_len + 1] = '\0';
          break;
  

-- 
Chip Salzenberg             - a.k.a. -              <chip@valinux.com>
     "Fleagal.  Bingo.  Drooper.  Snork.  They're cops."   //MST3K


Reply to: