TrouSerS is an open-source TCG Software Stack by IBM.  It uses OpenSSL
to read passwords.  The code in ssl_ui.c of the trousers library has a
buffer overflow.  I suspect many other applications may have the same
problem because the documentation is not clear about how
UI_add_input_string handles terminating null bytes.  Here is the nub
of the issue.

People declare the buffer used by UI_add_input_string as:

  char pin_buf[UI_MAX_SECRET_STRING_LENGTH];

and then call UI_add_input_string as:

  if (!UI_add_input_string(ui, "Enter PIN:", 0, pin_buf,
                           1, UI_MAX_SECRET_STRING_LENGTH)) 

The documentation should tell them to use 

  char pin_buf[UI_MAX_SECRET_STRING_LENGTH + 1];

because there is a buffer overflow as demonstrated by the enclosed C
program. 

$ make LDLIBS=-lcrypto ui
cc     ui.c  -lcrypto -o ui
$ ./ui
pin_buf[UI_MAX_SECRET_STRING_LENGTH] = 1
Enter PIN:ab

strlen(pin_buf) = 2
pin_buf = ab
pin_buf[UI_MAX_SECRET_STRING_LENGTH] = 0
$ 

John


/*
 * This program shows the code in ssl_ui.c of the trousers library has
 * a buffer overflow.  I suspect many other applications may have the
 * same problem because the documentation is not clear about how
 * UI_add_input_string handles terminating null bytes.
 *
 * Typing in a password of length 2 sets 3 bytes in pin_buf.  The code
 * in ssl_ui.c has the same problem.  To be safe, you must declare
 * pin_buf as follows:
 * 
 * char pin_buf[UI_MAX_SECRET_STRING_LENGTH + 1];
 *
 * Compile with "make LDLIBS=-lcrypto ui"
 * See what happens when you type in a password of length two and three.
 *
 * John D. Ramsdell -- The MITRE Corporation -- October 2011
 */

#include <stdio.h>
#include <string.h>
#include <openssl/ui.h>

#define UI_MAX_SECRET_STRING_LENGTH 2

static int err(const char *msg)
{
  printf("%s\n", msg);
  return 1;
}

int main(void)
{
  char pin_buf[UI_MAX_SECRET_STRING_LENGTH];
  pin_buf[UI_MAX_SECRET_STRING_LENGTH] = 1; /* Out of buffer write */
  printf("pin_buf[UI_MAX_SECRET_STRING_LENGTH] = %d\n", 
         pin_buf[UI_MAX_SECRET_STRING_LENGTH]);
  UI *ui = UI_new();
  if (!ui)
    return err("no UI");

  if (!UI_add_input_string(ui, "Enter PIN:", 0, pin_buf,
                           1, UI_MAX_SECRET_STRING_LENGTH)) 
    return err("add input failed");

  if (UI_process(ui))
    return err("process failed");

  printf("strlen(pin_buf) = %zd\n", strlen(pin_buf));
  printf("pin_buf = %s\n", pin_buf);
  printf("pin_buf[UI_MAX_SECRET_STRING_LENGTH] = %d\n", 
         pin_buf[UI_MAX_SECRET_STRING_LENGTH]);

  return 0;
}

Reply via email to