svn commit: r365781 - in releng: 11.3/libexec/ftpd 11.4/libexec/ftpd 12.1/libexec/ftpd 12.2/libexec/ftpd

Gordon Tetlow gordon at FreeBSD.org
Tue Sep 15 21:47:45 UTC 2020


Author: gordon
Date: Tue Sep 15 21:47:44 2020
New Revision: 365781
URL: https://svnweb.freebsd.org/changeset/base/365781

Log:
  Fix ftpd privilege escalation via ftpchroot.
  
  Approved by:	so
  Approved by:	re (implicit for releng/12.2)
  Security:	FreeBSD-SA-20:30.ftpd
  Security:	CVE-2020-7468

Modified:
  releng/11.3/libexec/ftpd/ftpd.c
  releng/11.4/libexec/ftpd/ftpd.c
  releng/12.1/libexec/ftpd/ftpd.c
  releng/12.2/libexec/ftpd/ftpd.c

Modified: releng/11.3/libexec/ftpd/ftpd.c
==============================================================================
--- releng/11.3/libexec/ftpd/ftpd.c	Tue Sep 15 21:46:39 2020	(r365780)
+++ releng/11.3/libexec/ftpd/ftpd.c	Tue Sep 15 21:47:44 2020	(r365781)
@@ -1593,13 +1593,20 @@ skip:
 	 *    (uid 0 has no root power over NFS if not mapped explicitly.)
 	 */
 	if (seteuid(pw->pw_uid) < 0) {
-		reply(550, "Can't set uid.");
-		goto bad;
+		if (guest || dochroot) {
+			fatalerror("Can't set uid.");
+		} else {
+			reply(550, "Can't set uid.");
+			goto bad;
+		}
 	}
+	/*
+	 * Do not allow the session to live if we're chroot()'ed and chdir()
+	 * fails. Otherwise the chroot jail can be escaped.
+	 */
 	if (chdir(homedir) < 0) {
 		if (guest || dochroot) {
-			reply(550, "Can't change to base directory.");
-			goto bad;
+			fatalerror("Can't change to base directory.");
 		} else {
 			if (chdir("/") < 0) {
 				reply(550, "Root is inaccessible.");

Modified: releng/11.4/libexec/ftpd/ftpd.c
==============================================================================
--- releng/11.4/libexec/ftpd/ftpd.c	Tue Sep 15 21:46:39 2020	(r365780)
+++ releng/11.4/libexec/ftpd/ftpd.c	Tue Sep 15 21:47:44 2020	(r365781)
@@ -1593,13 +1593,20 @@ skip:
 	 *    (uid 0 has no root power over NFS if not mapped explicitly.)
 	 */
 	if (seteuid(pw->pw_uid) < 0) {
-		reply(550, "Can't set uid.");
-		goto bad;
+		if (guest || dochroot) {
+			fatalerror("Can't set uid.");
+		} else {
+			reply(550, "Can't set uid.");
+			goto bad;
+		}
 	}
+	/*
+	 * Do not allow the session to live if we're chroot()'ed and chdir()
+	 * fails. Otherwise the chroot jail can be escaped.
+	 */
 	if (chdir(homedir) < 0) {
 		if (guest || dochroot) {
-			reply(550, "Can't change to base directory.");
-			goto bad;
+			fatalerror("Can't change to base directory.");
 		} else {
 			if (chdir("/") < 0) {
 				reply(550, "Root is inaccessible.");

Modified: releng/12.1/libexec/ftpd/ftpd.c
==============================================================================
--- releng/12.1/libexec/ftpd/ftpd.c	Tue Sep 15 21:46:39 2020	(r365780)
+++ releng/12.1/libexec/ftpd/ftpd.c	Tue Sep 15 21:47:44 2020	(r365781)
@@ -1595,13 +1595,20 @@ skip:
 	 *    (uid 0 has no root power over NFS if not mapped explicitly.)
 	 */
 	if (seteuid(pw->pw_uid) < 0) {
-		reply(550, "Can't set uid.");
-		goto bad;
+		if (guest || dochroot) {
+			fatalerror("Can't set uid.");
+		} else {
+			reply(550, "Can't set uid.");
+			goto bad;
+		}
 	}
+	/*
+	 * Do not allow the session to live if we're chroot()'ed and chdir()
+	 * fails. Otherwise the chroot jail can be escaped.
+	 */
 	if (chdir(homedir) < 0) {
 		if (guest || dochroot) {
-			reply(550, "Can't change to base directory.");
-			goto bad;
+			fatalerror("Can't change to base directory.");
 		} else {
 			if (chdir("/") < 0) {
 				reply(550, "Root is inaccessible.");

Modified: releng/12.2/libexec/ftpd/ftpd.c
==============================================================================
--- releng/12.2/libexec/ftpd/ftpd.c	Tue Sep 15 21:46:39 2020	(r365780)
+++ releng/12.2/libexec/ftpd/ftpd.c	Tue Sep 15 21:47:44 2020	(r365781)
@@ -1595,13 +1595,20 @@ skip:
 	 *    (uid 0 has no root power over NFS if not mapped explicitly.)
 	 */
 	if (seteuid(pw->pw_uid) < 0) {
-		reply(550, "Can't set uid.");
-		goto bad;
+		if (guest || dochroot) {
+			fatalerror("Can't set uid.");
+		} else {
+			reply(550, "Can't set uid.");
+			goto bad;
+		}
 	}
+	/*
+	 * Do not allow the session to live if we're chroot()'ed and chdir()
+	 * fails. Otherwise the chroot jail can be escaped.
+	 */
 	if (chdir(homedir) < 0) {
 		if (guest || dochroot) {
-			reply(550, "Can't change to base directory.");
-			goto bad;
+			fatalerror("Can't change to base directory.");
 		} else {
 			if (chdir("/") < 0) {
 				reply(550, "Root is inaccessible.");


More information about the svn-src-all mailing list