File sysvinit-2.88+dsf-blowfish.dif of Package sysvinit

--- src/consoles.h
+++ src/consoles.h	2011-07-27 11:10:26.620613503 +0000
@@ -39,6 +39,7 @@ struct console {
 	int fd, id;
 #define	CON_SERIAL	0x0001
 #define	CON_NOTTY	0x0002
+#define	CON_EIGHTBIT	0x1000
 	pid_t pid;
 	struct chardata cp;
 	struct termios tio;
--- src/sulogin.c
+++ src/sulogin.c	2011-07-27 13:10:16.791925602 +0000
@@ -635,6 +635,7 @@ char *getpasswd(struct console *con)
 	ptr = &pass[0];
 	cp->eol = *ptr = '\0';
 
+	con->flags &= ~CON_EIGHTBIT;
 	eightbit = ((con->flags & CON_SERIAL) == 0 || (tty.c_cflag & (PARODD|PARENB)) == 0);
 	while (cp->eol == '\0') {
 		if (read(fd, &c, 1) < 1) {
@@ -697,6 +698,8 @@ char *getpasswd(struct console *con)
 				 goto quit;
 			}
 			*ptr++ = ascval;
+			if (((unsigned char)ascval) & 0x80)
+				con->flags |= CON_EIGHTBIT;
 			break;
 		}
 	}
@@ -839,6 +842,30 @@ void usage(void)
 	fprintf(stderr, "Usage: sulogin [-e] [-p] [-t timeout] [tty device]\n\r");
 }
 
+/*
+ * Wrapper for blowfish signedness bug (CVE-2011-2483)
+ */
+
+static
+int checkpw(const char *answer, const char *passwd, const struct console *con)
+{
+	char buf[64];
+
+	if (strcmp(crypt(answer, passwd), passwd) == 0)
+		return 1;
+	if (strncmp(passwd, "$2a$", 4) != 0)
+		return 0;
+	if ((con->flags & CON_EIGHTBIT) == 0)
+		return 0;
+	if (strlen(passwd) >= 64)
+		return 0;
+
+	strncpy(buf, passwd, 64);
+	buf[2] = 'x';
+
+	return (strcmp(crypt(answer, buf), buf) == 0);
+}
+
 int main(int argc, char **argv)
 {
 	char *tty = NULL;
@@ -967,8 +994,7 @@ int main(int argc, char **argv)
 				if ((answer = getpasswd(con)) == NULL)
 					break;
 
-				if (passwd[0] == '\0' ||
-				    strcmp(crypt(answer, passwd), passwd) == 0) {
+				if (passwd[0] == '\0' || checkpw(answer, passwd, con)) {
 					*usemask |= (1<<con->id);
 					sushell(pwd);
 					*usemask &= ~(1<<con->id);