[git commit] ftpd: make DIR parameter work for non-root too: chdir to it instead of chroot

Denys Vlasenko vda.linux at googlemail.com
Tue Oct 13 11:49:53 UTC 2015


commit: http://git.busybox.net/busybox/commit/?id=f7ad927c2059ef9cd1cd6befeb43f26b92f6369f
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

Unfortunately, chroot() works only for root user, because of attacks
on setuid binaries (make DIR/lib/ld-linux.so a shell, hardlink to
a setuid binary, chroot to DIR, execute it and get root shell).

function                                             old     new   delta
ftpd_main                                           2160    2180     +20

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 networking/ftpd.c |   17 ++++++++++++++++-
 1 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/networking/ftpd.c b/networking/ftpd.c
index 7735b72..8345ae6 100644
--- a/networking/ftpd.c
+++ b/networking/ftpd.c
@@ -1223,11 +1223,26 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
 #endif
 	argv += optind;
 	if (argv[0]) {
+		const char *basedir = argv[0];
 #if !BB_MMU
 		G.root_fd = xopen("/", O_RDONLY | O_DIRECTORY);
 		close_on_exec_on(G.root_fd);
 #endif
-		xchroot(argv[0]);
+		if (chroot(basedir) == 0)
+			basedir = "/";
+#if !BB_MMU
+		else {
+			close(G.root_fd);
+			G.root_fd = -1;
+		}
+#endif
+		/*
+		 * If chroot failed, assume that we aren't root,
+		 * and at least chdir to the specified DIR
+		 * (older versions were dying with error message).
+		 * If chroot worked, move current dir to new "/":
+		 */
+		xchdir(basedir);
 	}
 
 #if ENABLE_FEATURE_FTP_AUTHENTICATION


More information about the busybox-cvs mailing list