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;
}