The patch that I sent before does not check if both passwords are of the
same length, which is bad.
>From a4001bf30fb44245fc7da12b61fcf7df5f762058 Mon Sep 17 00:00:00 2001
From: Jakob Kramer <[email protected]>
Date: Wed, 30 Apr 2014 00:20:31 +0200
Subject: [PATCH 2/2] su: use "constant time" memcmp to compare password
---
su.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/su.c b/su.c
index 16ce6c2..3149e5c 100644
--- a/su.c
+++ b/su.c
@@ -17,6 +17,7 @@ extern char **environ;
static const char *randreply(void);
static char *msetenv(const char *, const char *);
static void dologin(struct passwd *);
+static int passcmp(const char *, const char *);
static void
usage(void)
@@ -86,7 +87,7 @@ main(int argc, char *argv[])
if (!cryptpass)
eprintf("crypt:");
- if (strcmp(cryptpass, spw->sp_pwdp) != 0)
+ if (passcmp(cryptpass, spw->sp_pwdp) != 0)
eprintf(randreply());
for (i = 0; cryptpass[i]; i++)
@@ -187,3 +188,20 @@ dologin(struct passwd *pw)
eprintf("chdir %s:", pw->pw_dir);
execve(pw->pw_shell, newargv, newenv);
}
+
+static int
+passcmp(const char *s, const char *t)
+{
+ size_t ls = strlen(s);
+ size_t lt = strlen(t);
+ size_t i;
+ char d = 0;
+
+ if (ls != lt)
+ return 1;
+
+ for (i = 0; i < ls; i++)
+ d |= s[i] ^ t[i];
+
+ return d;
+}
--
1.8.5.1