Bug#50498: 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: