Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Aug 2001 01:03:58 -0400
From:      Mike Barcroft <mike@FreeBSD.org>
To:        audit@FreeBSD.org
Subject:   login(1) changes
Message-ID:  <20010809010358.A18538@coffee.q9media.com>

next in thread | raw e-mail | index | archive | help
I've appreciate reviews of the following change to login(1).

Best regards,
Mike Barcroft
 
----------------------------------------------------------------------

login.20010808-rev2.patch

o Replace occurrences of strncpy(3) with strlcpy(3); most of
  the uses of it were wrong anyway.
o Always check for NULL returns on strdup(3).
o Fix a possible buffer overflow in strcpy(3).
o Fix a format string vulnerability.
o t->ty_type in stypeof() could be NULL and eventually cause
  a segmentation fault in setenv(3), so check for that.

Index: login/login.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/login/login.c,v
retrieving revision 1.65
diff -u -r1.65 login.c
--- login/login.c	2001/07/28 19:53:10	1.65
+++ login/login.c	2001/08/09 04:34:49
@@ -210,7 +210,10 @@
 			if (uid)
 				errx(1, "-h option: %s", strerror(EPERM));
 			hflag = 1;
-			strncpy(full_hostname, optarg, sizeof(full_hostname)-1);
+			if (strlcpy(full_hostname, optarg,
+			    sizeof(full_hostname)) >= sizeof(full_hostname))
+				errx(1, "-h option: %s: exceeds maximum "
+				    "hostname size", optarg);
 
 			trimdomain(optarg, UT_HOSTSIZE);
 
@@ -232,6 +235,11 @@
 					    NI_NUMERICHOST|
 					    NI_WITHSCOPEID);
 					optarg = strdup(hostbuf);
+					if (optarg == NULL) {
+						syslog(LOG_NOTICE,
+						    "strdup(): %m");
+						sleepexit(1);
+					}
 				} else
 					optarg = "invalid hostname";
 				if (res != NULL)
@@ -304,8 +312,7 @@
 			if (failures > (pwd ? 0 : 1))
 				badlogin(tbuf);
 		}
-		(void)strncpy(tbuf, username, sizeof tbuf-1);
-		tbuf[sizeof tbuf-1] = '\0';
+		(void)strlcpy(tbuf, username, sizeof(tbuf));
 
 		pwd = getpwnam(username);
 
@@ -466,7 +473,10 @@
 				getnameinfo(res->ai_addr, res->ai_addrlen,
 				    hostbuf, sizeof(hostbuf), NULL, 0,
 				    NI_NUMERICHOST|NI_WITHSCOPEID);
-				optarg = strdup(hostbuf);
+				if ((optarg = strdup(hostbuf)) == NULL) {
+					syslog(LOG_NOTICE, "strdup(): %m");
+					sleepexit(1);
+				}
 			} else
 				optarg = NULL;
 			if (res != NULL)
@@ -487,7 +497,7 @@
 	if (*shell == '\0')   /* Not overridden */
 		shell = pwd->pw_shell;
 	if ((shell = strdup(shell)) == NULL) {
-		syslog(LOG_NOTICE, "memory allocation error");
+		syslog(LOG_NOTICE, "strdup(): %m");
 		sleepexit(1);
 	}
 
@@ -499,10 +509,10 @@
 	/* Nothing else left to fail -- really log in. */
 	memset((void *)&utmp, 0, sizeof(utmp));
 	(void)time(&utmp.ut_time);
-	(void)strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
+	(void)strlcpy(utmp.ut_name, username, sizeof(utmp.ut_name));
 	if (hostname)
-		(void)strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host));
-	(void)strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
+		(void)strlcpy(utmp.ut_host, hostname, sizeof(utmp.ut_host));
+	(void)strlcpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
 	login(&utmp);
 
 	dolastlog(quietlog);
@@ -530,8 +540,13 @@
 	/*
 	 * Preserve TERM if it happens to be already set.
 	 */
-	if ((term = getenv("TERM")) != NULL)
-		term = strdup(term);
+	if ((term = getenv("TERM")) != NULL) {
+		if ((term = strdup(term)) == NULL) {
+			syslog(LOG_NOTICE,
+			    "strdup(): %m");
+			sleepexit(1);
+		}
+	}
 
 	/*
 	 * Exclude cons/vt/ptys only, assume dialup otherwise
@@ -673,10 +688,9 @@
 		motd(cw);
 
 		cw = getenv("MAIL");	/* $MAIL may have been set by class */
-		if (cw != NULL) {
-			strncpy(tbuf, cw, sizeof(tbuf));
-			tbuf[sizeof(tbuf)-1] = '\0';
-		} else
+		if (cw != NULL)
+			strlcpy(tbuf, cw, sizeof(tbuf));
+		else
 			snprintf(tbuf, sizeof(tbuf), "%s/%s", _PATH_MAILDIR,
 			    pwd->pw_name);
 		if (stat(tbuf, &st) == 0 && st.st_size != 0)
@@ -699,9 +713,13 @@
 	/*
 	 * Login shells have a leading '-' in front of argv[0]
 	 */
-	tbuf[0] = '-';
-	(void)strcpy(tbuf + 1,
-	    (p = strrchr(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell);
+	if (snprintf(tbuf, sizeof(tbuf), "-%s",
+	    (p = strrchr(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell) >=
+	    sizeof(tbuf)) {
+		syslog(LOG_ERR, "user: %s: shell exceeds maximum pathname size",
+		    username);
+		errx(1, "shell exceeds maximum pathname size");
+	}
 
 	execlp(shell, tbuf, (char *)0);
 	err(1, "%s", shell);
@@ -898,7 +916,7 @@
 	static char nbuf[NBUFSIZ];
 
 	for (;;) {
-		(void)printf(prompt);
+		(void)printf("%s", prompt);
 		for (p = nbuf; (ch = getchar()) != '\n'; ) {
 			if (ch == EOF) {
 				badlogin(username);
@@ -931,10 +949,9 @@
 
 volatile int motdinterrupt;
 
-/* ARGSUSED */
 void
 sigint(signo)
-	int signo;
+	int signo __unused;
 {
 	motdinterrupt = 1;
 }
@@ -994,11 +1011,13 @@
 		}
 		memset((void *)&ll, 0, sizeof(ll));
 		(void)time(&ll.ll_time);
-		(void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
+		(void)strlcpy(ll.ll_line, tty, sizeof(ll.ll_line));
 		if (hostname)
-			(void)strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
+			(void)strlcpy(ll.ll_host, hostname, sizeof(ll.ll_host));
 		(void)write(fd, (char *)&ll, sizeof(ll));
 		(void)close(fd);
+	} else {
+		syslog(LOG_ERR, "cannot open %s: %m", _PATH_LASTLOG);
 	}
 }
 
@@ -1034,7 +1053,12 @@
 {
 	struct ttyent *t;
 
-	return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
+	if (ttyid != NULL && *ttyid != '\0') {
+		t = getttynam(ttyid);
+		if (t != NULL && t->ty_type != NULL)
+			return (t->ty_type);
+	}
+	return ("UNKNOWN");
 }
 
 void

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010809010358.A18538>