aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-08-26 14:46:36 -0700
committerH. Peter Anvin <hpa@zytor.com>2008-08-26 14:46:36 -0700
commit2a6fef03f88e7aa56009f608dccd17e6f24dde97 (patch)
tree7ad00e1cd13b7a0c8eb54a3f6f039ad0413d90a3
parent2a6e8707d8da5e39ea3472c6d820099331fc5585 (diff)
downloadsyslinux-elf-2a6fef03f88e7aa56009f608dccd17e6f24dde97.tar.gz
syslinux-elf-2a6fef03f88e7aa56009f608dccd17e6f24dde97.tar.xz
syslinux-elf-2a6fef03f88e7aa56009f608dccd17e6f24dde97.zip
menu: avoid leaving obvious password turds in memory
Avoid leaving obvious password turds in memory. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--com32/menu/Makefile2
-rw-r--r--com32/menu/drain.c27
-rw-r--r--com32/menu/menu.h3
-rw-r--r--com32/menu/menumain.c13
-rw-r--r--com32/menu/passwd.c24
5 files changed, 57 insertions, 12 deletions
diff --git a/com32/menu/Makefile b/com32/menu/Makefile
index cfdea06a..9b856c2e 100644
--- a/com32/menu/Makefile
+++ b/com32/menu/Makefile
@@ -23,7 +23,7 @@ LNXLIBS = ../libutil/libutil_lnx.a
MODULES = menu.c32 vesamenu.c32
TESTFILES =
-COMMONOBJS = menumain.o readconfig.o passwd.o printmsg.o colors.o \
+COMMONOBJS = menumain.o readconfig.o passwd.o drain.o printmsg.o colors.o \
background.o refstr.o execute.o
all: $(MODULES) $(TESTFILES)
diff --git a/com32/menu/drain.c b/com32/menu/drain.c
new file mode 100644
index 00000000..83ebbdc3
--- /dev/null
+++ b/com32/menu/drain.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/cpu.h>
+
+void drain_keyboard(void)
+{
+ /* Prevent "ghost typing" and keyboard buffer snooping */
+ volatile char junk;
+ int rv;
+
+ do {
+ rv = read(0, &junk, 1);
+ } while (rv > 0);
+
+ junk = 0;
+
+ cli();
+ *(volatile uint8_t *)0x419 = 0; /* Alt-XXX keyboard area */
+ *(volatile uint16_t *)0x41a = 0x1e; /* Keyboard buffer empty */
+ *(volatile uint16_t *)0x41c = 0x1e;
+ memset((volatile void *)0x41e, 0, 32); /* Clear the actual keyboard buffer */
+ sti();
+}
+
+
diff --git a/com32/menu/menu.h b/com32/menu/menu.h
index 3cb127e2..1fa1a24b 100644
--- a/com32/menu/menu.h
+++ b/com32/menu/menu.h
@@ -217,4 +217,7 @@ void set_background(const char *new_background);
/* execute.c */
void execute(const char *cmdline, enum kernel_type type);
+/* drain.c */
+void drain_keyboard(void);
+
#endif /* MENU_H */
diff --git a/com32/menu/menumain.c b/com32/menu/menumain.c
index 01b4fb4b..f7af90aa 100644
--- a/com32/menu/menumain.c
+++ b/com32/menu/menumain.c
@@ -215,6 +215,7 @@ ask_passwd(const char *menu_entry)
int done;
int key;
int x;
+ int rv;
printf("\033[%d;%dH\2#11\016l", PASSWD_ROW, PASSWD_MARGIN+1);
for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ )
@@ -232,6 +233,8 @@ ask_passwd(const char *menu_entry)
PASSWD_ROW, (WIDTH-(strlen(cm->messages[MSG_PASSPROMPT])+2))/2,
cm->messages[MSG_PASSPROMPT], PASSWD_ROW+1, PASSWD_MARGIN+3);
+ drain_keyboard();
+
/* Actually allow user to type a password, then compare to the SHA1 */
done = 0;
p = user_passwd;
@@ -282,9 +285,15 @@ ask_passwd(const char *menu_entry)
*p = '\0';
- return (cm->menu_master_passwd &&
- passwd_compare(cm->menu_master_passwd, user_passwd))
+ rv = (cm->menu_master_passwd &&
+ passwd_compare(cm->menu_master_passwd, user_passwd))
|| (menu_entry && passwd_compare(menu_entry, user_passwd));
+
+ /* Clean up */
+ memset(user_passwd, 0, WIDTH);
+ drain_keyboard();
+
+ return rv;
}
diff --git a/com32/menu/passwd.c b/com32/menu/passwd.c
index b3bb70a5..534fe8bd 100644
--- a/com32/menu/passwd.c
+++ b/com32/menu/passwd.c
@@ -19,26 +19,32 @@
static int passwd_compare_sha1(const char *passwd, const char *entry)
{
+ struct {
+ SHA1_CTX ctx;
+ unsigned char sha1[20], pwdsha1[20];
+ } d;
const char *p;
- SHA1_CTX ctx;
- unsigned char sha1[20], pwdsha1[20];
+ int rv;
- SHA1Init(&ctx);
+ SHA1Init(&d.ctx);
if ( (p = strchr(passwd+3, '$')) ) {
- SHA1Update(&ctx, (void *)passwd+3, p-(passwd+3));
+ SHA1Update(&d.ctx, (void *)passwd+3, p-(passwd+3));
p++;
} else {
p = passwd+3; /* Assume no salt */
}
- SHA1Update(&ctx, (void *)entry, strlen(entry));
- SHA1Final(sha1, &ctx);
+ SHA1Update(&d.ctx, (void *)entry, strlen(entry));
+ SHA1Final(d.sha1, &d.ctx);
- memset(pwdsha1, 0, 20);
- unbase64(pwdsha1, 20, p);
+ memset(d.pwdsha1, 0, 20);
+ unbase64(d.pwdsha1, 20, p);
- return !memcmp(sha1, pwdsha1, 20);
+ rv = !memcmp(d.sha1, d.pwdsha1, 20);
+
+ memset(&d, 0, sizeof d);
+ return rv;
}
static int passwd_compare_md5(const char *passwd, const char *entry)