ftpd: make DIR parameter work for non-root too: chdir to it instead of chroot
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@googlemail.com>
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 @@
#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